C语言中的变量可以有自己的属性,只需在定义变量的时候加上“属性”关键字即可。
“属性”关键字指明变量的特有属性。
1、auto关键字:
auto是C语言中局部变量的默认属性,表明被修饰的变量存储在栈上。
编译器默认所有的局部变量都是auto属性。
2、register关键字:
表明局部变量存储在寄存器中,要注意的是,这只是请求寄存器变量,但是不一定成功。register变量必须是CPU寄存器可以接受的值。
不能用“&”运算符获取register变量的地址。
观察下面代码
#include <stdio.h> register int g_v; //error int main() { register char var; printf("%ox08X", &var); //error return 0; }
linux下使用Gcc进行编译:
delphi@delphi-vm:~/will$ gcc test.c test.c: In function ‘main’: test.c:10: error: address of register variable ‘var’ requested
3、static关键字
static关键字表明变量的“静态”属性:
static修饰的局部变量存储在程序静态区;
static关键字具有“作用域限定符”的意义:
static修饰的全局变量作用域只是在声明的文件中;
static修饰函数作用域只在声明的文件中。
#include<stdio.h> int g_v; //全局变量 程序的任意地方都可以访问 static int g_vs; //静态全局变量,只有当前文件中可以访问 int main() { int var; //局部变量,在栈上分配空间 static int svar; //静态局部变量,在静态存储区分配空间 return 0; }
示例代码:观察下面代码,判断输出,并体会auto、register、static关键字的作用
#include <stdio.h> int f1() { int i=0; i++; return i; } int f2() { static i=0; i++; return i; } int main() { auto int i=0; //栈上 register int j=0; //向编译器申请将j存储在寄存器中 static int k=0; //静态数据区,作用域在mian中 printf("%p\n", &i); //printf("%p\n", &j); //error printf("%p\n", &k); for(i=0; i<5; i++) //C99不允许声明的时候定义在循环中 { printf("%d\n", f1()); } for(i=0; i<5; i++) { printf("%d\n", f2()); } return 0; }
在Linux下使用gcc进行编译并运行,结果如下:
delphi@delphi-vm:~/will$ gcc test.c delphi@delphi-vm:~/will$ ./a.out 0xbfc222ec 0x804a01c 1 1 1 1 1 1 2 3 4 5
4、extern关键字
extern用于声明“外部”定义的变量和函数
extern变量在文件的其他地方分配空间;
extern函数在文件的其他地方定义。
extern用于“告诉”编译器使用C的方式编译代码:
C++编译器和一些变种C编译器默认会按照“自己”的方式编译函数和变量。
示例:
extern "C" //C++和C的桥梁 { int f(int a, int b) { return a+b; } }
观察下面代码,体会extern的作用,注意static全局变量和extern的“互斥性”
#include<stdio.h> //test.c extern int g_i; int mian() { printf("%d\n", g_i); return 0; }
g.c: int g_i=10; //gcc test.c g.c static g_i=10; //编译错误,static作用域缩小 static和extern“互斥性”;
那么如何访问其他文件中的static全局变量呢?——定义函数
g.c: int getI() { return g_i; } 在main()中 extern int getI();
小结:
auto变量存储在程序的栈上,并且是默认属性;
static局部变量存储在程序的静态区,修饰的全局变量(函数)只能在声明的文件中访问(作用域限定)。
register变量请求存储于CPU寄存器中,访问速度快;
extern变量在文件的其他地方分配空间;
extern能够指示编译器按照标准C方式进行编译。