关键词:C语言的变量属性、auto
关键字、 register
关键字、 static
关键字、extern
关键字
1. C语言的变量属性
- C语言中的变量可以有自己的属性,在定义变量的时候可以加上属性关键字,属性关键字指明变量的特有意义。
- 语法:
property type var_name;
- 示例:
int main()
{
auto char i;
register int j;
static long k;
extern double m;
return o;
}
2. auto
关键字
-
auto
即C语言中局部变量的默认属性 -
auto
表明将被修饰的变量存储于栈上 -
编译器默认所有的局部变量都是
auto
的
示例:
void f()
{
int i; // 局部变量默认属性为 auto
auto int j; // 显示声明 auto 属性
}
3. register
关键字
-
register
关键字指明将局部变量存储于寄存器中 -
register
只是请求寄存器变量,但不一定请求成功 -
register
变量的值必须是CPU寄存器可以接受的值 -
不能用
&
运算符获取register
变量的地址,因为&
是获取内存地址,而不能获取到寄存器变量的地址
示例:
#include <stdio.h>
register int g_v; // error: register name not specified for ‘g_v’
int main()
{
register char var;
printf("0x%08x\n", &var); // error: address of register variable ‘var’ requested
return 0;
}
4. static
关键字
-
static
关键字指明变量的静态属性
static
修饰的局部变量存储在程序静态区,即局部变量未被static
修饰时,变量位于栈空间,局部变量被static
修饰后,变量位于静态区,这个局部变量的生命周期和全局变量的生命周期相同,作用域只在局部区域 -
static
关键字同时具有作用域限定符的意义
static
修饰的全局变量作用域仅在声明的文件中
static
修饰的函数作用域仅在声明的文件中
#include <stdio.h>
int g_v; // 全局变量, 程序的任意地方均能访问
static int g_sv; // 静态全局变量, 只有当前文件中可访问
int main()
{
int var; // 局部变量,在栈上分配空间
static int svar; // 静态局部变量, 在静态数据区分配空间
return 0;
}
5. auto
,register
,static
对比分析
#include <stdio.h>
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: address of register variable ‘j’ requested
for(i=0; i<5; i++)
{
printf("%d\n", f1());
}
for(i=0; i<5; i++)
{
printf("%d\n", f2());
}
return 0;
}
输出结果:
0xbfdeb84c
0x804a01c
1
1
1
1
1
1
2
3
4
5
总结:
auto
修饰的变量i的地址值为:0xbfdeb84c,static
修饰的变量j的地址值为:0x804a01c。两地址值相差较大的原因是因为变量i位于栈空间,变量j位于常量区;
f1()中的变量r位于栈空间,每次调用时被初始化为0,f2()中的变量r位于静态区,只被初始化一次,r的生命周期为程序的运行周期,每次对它的改动都会被保留下来。
6. extern
关键字
作用一:extern
用于声明外部定义的变量和函数
extern
变量在文件的其它地方分配空间
extern
函数在文件的其它地方定义
作用二:extern
用于告诉编译器用C方式编译
C++编译器和一些变种C编译器默认会按“自己”的方式编译函数和变量,通过extern
关键字可以命令编译器以标准C方式进行编译。如:
extern "C"
{
int f(int a, int b)
{
return a + b;
}
}
7. static
和extern
的使用
test.c
#include <stdio.h>
extern int g_v; // 告诉编译器变量g_v在其他地方已经定义
int main()
{
printf("%d\n", g_v);
return 0;
}
g.c
int g_v = 10; // 定义全局变量 g_v
输出结果:
- 当
g.c
中用static
修饰后,源代码如下:
static int g_v = 10; // 定义全局变量 g_v
输出结果:
错误原因:static
修饰的全局变量作用域仅在声明的文件中,其它文件访问不到,因此在test.c
中编译器会提示g_v
没有定义。解决方法:
test.c
#include <stdio.h>
extern int getV(); // 告诉编译器函数getV()在其他地方已经定义
int main()
{
printf("%d\n", getV());
return 0;
}
g.c
static int g_v = 10; // 定义全局变量 g_v
int getV()
{
return g_v;
}
输出结果:
8. 小结
-
auto
变量存储在程序的栈中,为默认属性 -
static
变量存储在程序静态区中 -
register
变量请求存储于CPU寄存器中 -
extern
变量在文件的其它地方分配空间 -
extern
能够指示编译器按照C方式编译程序
声明:此文章为本人在学习狄泰软件学院《C语言深度解析》所做的笔记,文章中包含狄泰软件资料内容一切版权归狄泰软件所有!
网友评论