变量的属性
- C语言的变量可以有自己的属性
- 在定义变量的时候可以加上 “属性” 关键字
- “属性”关键字指明变量的特有意义
语法:
property type var_name
auto 关键字
- auto c语言中局部变量的默认属性
- 表明被修饰的变量存储在栈上,
- 编译器默认所有的局部变量都是auto
void f()
{
int i; // 局部变量默认属性为 auto
auto int j; // 显示声明为auto属性
}
Register关键字
- register关键字指明将局部变量存储于寄存器中
- 只是请求寄存器变量,但不一定成功
- register变量必需是CPU寄存器可以接收的值
- 不能用&运算获取register变量地址(寄存器的数量是有限的,&运算是取内存中 的地址,寄存器不属于内存)
不能修饰全局变量,因为一旦声明为寄存器变量,就一直占用寄存器;访问寄存器的速度比内存快的多,是为了决绝效率的
register int g_v ; // error
int main()
{
register char c;
printf("&d\n", &c); // error
}
Static 关键字
- static关键字指明变量的“静态”属性
修饰的局部变量存储在程序静态区
- static关键字具有“作用域限定符”的意义
修饰的全局变量的作用域只有在声明的文件中
修饰的函数作用域只有在声明的文件中
它修饰函数的时候函数就成为静态函数,此时的含义不是指存储方式,而是指函数的作用域局限于本文件(内部函数)(好处不用担心自己定义的函数是否与其它文件中的函数同名)
int g_v;
static int g_c; // 静态局部变量,只有当前文件才能访问
int main()
{
int i; // 局部变量 ,在栈上分配空间
static int j; // 静态局部变量,在静态存储区分配空间
return 0;
}
关键字对比实验
int f1()
{
int r = 0;
r++;
return r;
}
int f2()
{
static int r = 0;
r++;
return r;
}
int main()
{
auto int i = 0; // 显示声明 auto 属性,i 为栈变量
static int k = 0; // 局部变量 k 的存储区位于静态区,作用域位于 main 中
register int j = 0; // 向编译器申请将 j 存储于寄存器中
printf("%p\n", &i);
printf("%p\n", &k);
// printf("%p\n", &j); // error
for(i=0; i<5; i++)
{
printf("%d\n", f1());
}
for(i=0; i<5; i++)
{
printf("%d\n", f2());
}
return 0;
}
输出:
0x7fff3ef1b774
0x601048
1
1
1
1
1
1
2
3
4
5
extern 关键字
- extern 用于声明外部定义的变量和函数
extern变量(函数)在文件其它地方分配空间(定义)
- extern 用于 "告诉"编译器用C方式编
extern "C"
{
int f(int a, int b)
{
return a+ b;
}
}
示例一:
// main.c
extern int g_v;
int main()
{
printf("%d\n", g_v);
return 0;
}
int g_v;
示例二
// main.c
extern int g_v;
extern void func1();
extern void func2(); // error
int main()
{
printf("%d\n", g_v);
func1();
func2();
return 0;
}
// test.c
int g_v;
void func1()
{
}
static void func2()
{
小结
- auto关键字存储在程序的栈中,默认属性
- static关键字存储在程序静态区中
- register变量请求存储于CPU寄存器中
- extern变量在文件的其他地方分配空间
- extern能够指示编译器按照标准C方式编译程序