全局变量的作用域是从全局变量定义的位置到本源文件结束都有效。
我们先看一下全局变量在反汇编中是怎么体现的,如示例示例代码CH07_3_4。
#include
#include
int i = 2;
int main(void)
{
int j = i;
return 0;
}
1: #include
2: #include
3: int i = 2;
4: int main(void)
5: {
00401010 push ebp
00401011 mov ebp,esp
00401013 sub esp,44h
00401016 push ebx
00401017 push esi
00401018 push edi
00401019 lea edi,[ebp-44h]
0040101C mov ecx,11h
00401021 mov eax,0CCCCCCCCh
00401026 rep stos dword ptr [edi]
上面的代码就不再分析了,下面是重点。
6: int j = i;
00401028 mov eax,[i (00421a30)]
这一行中(00421a30)正是全局变量i的存放地址。
全局变量编译的时候就已经确定了内存地址和宽度,变量名就是内存地址的别名。如果不重新编译(也就是不重新构建程序),全局变量的内存地址将不会改变。
0040102D mov dword ptr [ebp-4],eax
7: return 0;
00401030 xor eax,eax
8: }
图7-3-22
总结:全局变量保存在内存的全局区中,占用静态的存储单元。说到静态的存储单元,这里还要提一下全局变量分为:全局变量和静态全局变量。全局变量的定义请看示例代码CH07_3_4,而静态全局变量,只是在int i = 2;前加static关键字。
书写形式:static int i =2;
全局变量与静态全局变量有什么区别?
全局变量作用范围:从全局变量定义的位置到本源文件结束都有效,如果想在别的文件中访问可以加上extend声明,书写形式:extend int i = 2;详细介绍请看第十章文件。
静态全局变量作用范围:只在定义它的文件中可用,而文件之外是不可以被看见的。静态全局变量就是用来解决重名问题的,使用静态全局变量就是告诉编译器这个变量只在当前文件使用,在别的文件中就不可以使用。
对于一个完整的程序:内存分布有如下几个区、栈区、堆区、全局区、常量区、代码区。
图7-3-22
图7-3-22有几个没有介绍到,以后的章节中会补充,这里要有这么几个概念。我们看代码示例CH07_3_5,代码中又不理解的地方,不要着急,在后续的章节中会介绍到。
#include
#include
//全局区
int g_n1 = 1;//全局初始化区
char g_c2 ;//全局未初始化区
void funtion()
{
int a = 1;
}
int main(void)
{
int nNum = 1;//栈区
char cStr2[] = "123";//栈区
char *cStr1 = "hello";//cStr1在栈区,hello\0在常量区
static int nNum1 = 0;//全局初始化区
char *pCStr = (char *)malloc(10);//分配10字节区域在堆区
strcpy(pCStr, "666");//666放在常量区
printf("程序代码区的地址\n");
printf("funtion=%08X\n", funtion);
printf("文字常量区 常量的地址\n");
printf("&cStr1=%08X\n", &cStr1);
printf("&pCStr=%08X\n", &pCStr);
printf("全局区变量的地址\n");
printf("&g_n1=%08X\n", &g_n1);
printf("&g_c2=%08X\n", &g_c2);
printf("&nNum1=%08X\n", &nNum1);
printf("栈区 变量的地址\n");
printf("&nNum=%08X\n", &nNum);
printf("&cStr2=%08X\n", &cStr2);
printf("堆区 空间的地址\n");
printf("pCStr=%08X\n", pCStr);
free(pCStr);//释放
system("pause");
return 0;
}
运行结果:
图7-3-23
举报/反馈