3.1变量的基础
变量在程序中用变量名表示,变量名由用户根据其用途任意命名。
变量名由字母、数字、下划线组成,不能以数字开始,不能和c的关键字重名。
在程序运行时,变量占据存储空间的大小由其数据决定
变量在内存空间中的首地址,称为变量的地址。
3.2变量的说明
变量在程序中使用时,必须先说明他们的存储类型和数据类型。
说明的一般形式是:
<存储类型> <数据类型><变量名>;
<存储类型>是关键词auto、register、static和extern
<数据类型>可以是基本数据类型也可以是自定义的数值
3.3变量的存储类型
在 C 语言中,变量的 存储类型(Storage Class)决定了变量的作用域、生命周期和存储位置。C 语言定义了四种存储类型:auto、egister、static 和 extern。以下是它们的详细介绍和区别:
1.auto(自动变量)
·作用域:仅在声明它的代码块(如函数、循环、条件语句等)内有效。
·生命周期:从代码块开始执行时分配内存,代码块结束时自动释放内存。
·存储位置:栈内存。
·初始化:默认值是随机的(未显式初始化时)。
·特点:
默认的存储类型(即局部变量默认是 auto,通常省略不写)。
每次进入代码块时重新分配内存。
常用于临时变量。
示例:
void func() {
auto int x = 10; // 等价于 int x = 10;
// x 的作用域仅在 func 函数内
}
2. register(寄存器变量)
·作用域:与 auto相同,仅在声明它的代码块内有效。
·生命周期:与 auto相同,代码块结束时释放。
·存储位置:建议编译器将变量存储在 CPU 寄存器中(但实际是否存储由编译器决定)。
·初始化:默认值随机。
·特点:
旨在提高访问速度(寄存器比内存快)。
不能对 register 变量取地址(如 &x),因为寄存器没有内存地址。
现代编译器通常会自动优化寄存器的使用,因此 register关键字已较少显式使用。
示例:
void func() {
register int counter; // 建议编译器将 counter 存储在寄存器中
for (counter = 0; counter < 1000; counter++) {
// 高频使用的变量可能适合 register
}
}
3. static(静态变量)
·作用域:
局部静态变量:仅在声明它的代码块内有效。
全局静态变量:仅在当前源文件(.c文件)内有效(避免被其他文件访问)。
·生命周期:程序运行期间一直存在,内存不会释放。
·存储位置:静态存储区(全局数据区)。
·初始化:默认初始化为 0(数值类型)或空指针(指针类型)。
·特点:
局部静态变量的值在多次函数调用之间保持持久。
全局静态变量对其他文件不可见(通过 static 限制作用域)。
示例:
// 局部静态变量
void func() {
static int count = 0; // 只初始化一次
count++;
printf("Count: %d\n", count); // 输出会递增
}
// 全局静态变量(仅在当前文件可见)
static int file_private = 42; // 其他文件无法访问此变量
4. extern(外部变量)
·作用域:全局作用域(所有源文件可见)。
·生命周期:程序运行期间一直存在。
·存储位置:静态存储区(全局数据区)。
·初始化:默认初始化为 0,但通常在定义时显式初始化。
·特点:
用于声明一个在其他源文件中定义的全局变量或函数。
允许跨文件共享全局变量或函数。
extern 仅声明变量,不分配内存(内存分配在定义处)。
示例:
// file1.c
int global_var = 100; // 全局变量定义
// file2.c
extern int global_var; // 声明外部变量
void func() {
printf("%d\n", global_var); // 访问其他文件中的全局变量
}
四种存储类型的对比:
存储类型 | 作用域 | 生命周期 | 存储位置 | 初始化 | 典型用途 |
auto | 代码块内 | 代码块执行期间 | 栈内存 | 随机值 | 临时局部变量 |
register | 代码块内 | 代码块执行期间 | 寄存器(建议) | 随机值 | 高频访问的临时变量 |
static | 局部:代码块内 全部:当前文件 | 程序运行期间 | 静态存储区 | 默认0 | 持久化局部变量、文件私有变量 |
extern | 全局(跨文件) | 程序运行期间 | 静态存储区 | 默认0 | 跨文件共享全局变量或函数 |
关键区别:
1. auto和static:
auto变量每次进入代码块时重新初始化,static 变量只初始化一次,保留上次的值。
2. extern和 static:
static全局变量仅在当前文件可见,extern用于跨文件共享全局变量。
3. register的限制:
不能取地址,且是否存储在寄存器中由编译器决定。