声明与定义
- 声明或定义变量的一般形式为:[存储类型] [数据类型] [变量名表]
- 存储类型有:自动变量(auto)、静态变量(static)、外部变量(extern)、寄存器变量(register)
- 可以声明多次,但只能定义一次。
- 一般在头文件中,只进行声明,不进行定义。否则,头文件被多个源文件包含时,会出现重定义。这是因为include头文件时,编译器会在预处理阶段将头文件的内容复制到源文件中,这样包含该头文件的源文件就都会进行一次定义,出现重定义。
int a;
int a;
int b = 10;
int main()
{
extern int c;
int d;
}
int a;
int b = 10;
auto
- auto是所有局部变量默认的存储类型,因此局部变量也称为自动变量。
- auto不能用于修饰全局变量
- 局部变量在栈中分配内存,在生命周期结束后就会销毁。
register
- register指示编译器将变量存储在处理器的寄存器中,从而提高运行效率。
- 编译器可能会忽略register指示,将变量存储在内存中。
- 因为变量存储在寄存器中,所以不能对register变量取地址,也不能在声明时赋初值。
extern
- extern常用在变量名前,表示该变量是在别处定义的,要在此处引用,所以需要先声明一下。编译器不会为extern声明的变量分配内存,其内存是在真正定义处分配的。
- extern也可以用在函数名前,但是一般不这样使用。因为函数包含函数名和函数体,可以很好区分函数的声明和定义。
int fun1();
int fun1()
{
return 1;
}
static
- 全局静态变量:该全局变量只能在本文件使用,即使在别的文件中使用extern也不行。在别的文件可以定义同名变量,不会冲突。
- 局部静态变量:该局部变量在函数生命周期外依然存在,如下,每次调用输出的结果递增1。
static void output(void) {
static int temp = 10;
printf("%d\n",temp);
temp++;
}
- 静态函数:静态函数只能在本文件使用。在别的文件可以定义同名函数,不会冲突。
- 特殊用法:在头文件中使用。使用static可以在不同文件中使用 include 包含头文件时产生不同的实体,这样就不会出现重复定义的情况了。第一次看到 static 在头文件使用的时候是和 inline 一起使用的,本来一个内联函数放在头文件中声明为 inline 就可以了,为什么还要加上 static 呢?这是为了在不同文件中使用 include 包含头文件时能够产生不同的内联函数(同名),这样就不会出现重复定义的情况了。同理,如果你在头文件中用 static 申明一个变量,那么每次使用 include 包含这个头文件的时候都会产生一个变量,虽然它们的名字相同,但是它们内存位置却是不同的,比如张三这个名字,虽然都叫张三,但可能他们不是同一个人,所做的一些行为也就不一样了。