C语言的变量属性
C语言中的变量可以有自己的属性
在定义变量的时候可以加上"属性"关键字
"属性"关键字指明变量的特殊意义
语法:
`property type var_name;`
示例:
void code()
{
auto char i;
register int j;
static long k;
extern double m;
}
auto 关键字
auto 即C语言中局部变量的默认属性
auto 表明被修饰的变量存储于栈上
编译器默认所有的局部变量都是auto
示例:
void code()
{
int i; // 局部变量默认属性为 auto
auto int j; // 显示声明 auto 属性
}
register 关键字
register 关键字指明将局部变量存储于寄存器中(为了获得最高的访问速度)
register 只是请求寄存器变量,但不一定请求成功(寄存器的数量是有限的)
register 变量必须是CPU寄存器可以接收的值
不能用 & 运算符获取register变量的地址
示例:
register int g_v; // Error, 编译器报错
void code()
{
register char var;
printf("0x%p\n", &var); // Error, 编译器报错
}
static 关键字
static 关键字指明变量的 "静态" 属性
static 修饰的局部变量存储在程序静态区
static 关键字同时具有 "作用域限定符" 的意义
staitc 修饰的全局变量作用域只是声明的文件中
staitc 修饰的函数作用域只是声明的文件中
示例:
#include
int g_v; // 全局变量,程序的任意地方均能访问
static int g_vs // 静态全局变量,只有当前文件中可以访问
int main()
{
int var; // 局部变量,在栈上分配空间
static int svar; // 静态局部变量,在静态存储区分配空间
return 0;
}
示例分析:auto, register, static 对比分析
#include
int f1()
{
int r = 0;
r++;
return r;
}
int f2()
{
static int r = 0;
r++;
return r;
}
int main()
{
auto int i = 0;
auto int j = 0;
static int k = 0;
register int y = 0;
printf("%p\n", &i);
printf("%p\n", &j);
printf("%p\n", &k);
// printf("%p\n", &y); // Error, 编译器报错
printf("\n");
for(i=0; i<5; i++)
{
printf("%d\n", f1());
}
printf("\n");
for(i=0; i<5; i++)
{
printf("%d\n", f2());
}
return 0;
}
输出:
0xbfcdcbdc
0xbfcdcbd8
0x804a020
1
1
1
1
1
1
2
3
4
5
分析:
auto int i = 0; auto int j = 0; static int k = 0;
其中 i, j, k在定义时是连续的,打印输出 i, j 地址连续, k 地址不连续,表明 k 不是在栈中分配的空间。
extern 关键字
extern 用于声明 "外部" 定义的变量和函数
extern 变量在文件的其它地方分配空间
extern 函数在文件的其它地方定义
extern 用于 “告诉” 编译器用 C 方式编译
C++ 编译器和一些变种C编译器默认会按 "自己" 的方式编译函数和变量,通过 extern 关键字可以命令编译器"以标准C方式进行编译"。
示例:
extern "C"
{
int f(int a, int b)
{
return a + b;
}
}
编程实验:static 和 extern 的使用
Test_1.c
#include
extern int getI();
int main()
{
printf("%d\n", getI());
return 0;
}
Test_2.c
static int g_i;
int getI()
{
return g_i;
}
输出:
0
小结
auto 变量存储在程序的栈中,默认属性
static 变量存储在程序静态区中
register 变量请求存储于CPU寄存器中
extern 变量在文件的其它地方分配空间
extern 能够指示编译器按照标准 C 方式编译程序
以上内容参考狄泰软件学院系列课程,请大家保护原创!