这期我们研究下static和extern关键字,这两个关键字会影响到变量的分配位置,从而影响代码的执行结果。
static关键字:
static修饰的变量不管是全局变量还是局部变量都会被分配到可执行程序的数据节中,相当于都是全局变量
void demo() {
static int b = 10;
printf("static b:%d\n", b++);
}
int main() {
printf("static a:%d\n", a);
demo();
demo();
return 0;
}
控制台输出如下:
static a:1234
static b:10
static b:11
从截图中我们看到a变量和上例中局部变量b同样被分配在了可以执行文件的数据节中,所以两次输出的b值不相同
使用dumpbin查看编译后的main.obj文件
04F 00000000 SECT10 notype Static | _a
050 00000004 SECT10 notype Static | ?b@?1??demo@@9@9 (`demo'::`2'::b)
extern关键字:
extern只是一个简单的声明,编译器只是分配一个指针大小的空间,用来存放链接器最后定位到的变量的内存地址
a.c文件中定义一个自定义结构体,并创建变量haha_c:
struct _c{
unsigned char a;
unsigned char a2;
unsigned char a3;
unsigned char a4;
unsigned char a5;
} haha_c = {
0x99,
0x98,
0x97,
0x96,
0x66,
};
b.c文件中
extern short haha_c;
int main() {
printf("%hx\n", haha_c);
}
控制台输出:9899

从汇编代码中可以看出haha_c变量被当成了指针使用
使用dumpbin查看编译后的b.obj文件
04A 00000000 UNDEF notype External | _haha_c
总结:
1. static关键字编译后符号类型是static的所以static关键字修饰的变量只在obj文件范围内可见,extern关键字编译后的符号类型是external的,连接器可以在其他obj文件中找到
2. static关键字修饰后的变量最终都会被分配到数据段所在内存空间,对整个进程可见,所以才会有static修饰的局部变量全局只会初始化一次的说法
3. extern关键字相当于是一个指针的声明,extern int相当于int* extern short相当于short*,至于他真正指向的地址真实情况是什么类型我们是无从知晓的(只有在对应的obj文件才能看到真实的数据结构)。我们可以使用该特点隐藏我们内部数据结构,只导出部分字段供他人使用

7749

被折叠的 条评论
为什么被折叠?



