目录
1.作用域的区别:
全局变量:可用范围是“整个工程”,只需在函数体前中定义,该变量后的所有函数都可以使用该变量。当遇到其他不包含全局变量定义的文件需要用到该变量时,使用extern关键字声明这个变量即可。
extern,英文单词,主要用作为动词、名词、形容词,作动词时译为“驱逐”,作名词时译为“非住院医生;不住院的医院员工;外勤修女;大学实习生”,作形容词时译为“外面的;外来的;对外的”。
//这里是A文件
int i=0;//定义一个全局变量,以下的函数都能调用
void SUM(void)//累加
{
for(i=0;i<=100;i++)
i+=i;
}
void RIDE(void)//累乘
{
for(i=1;i<=100;i++)
i*=i;
}
//这里是B文件
extern int i;//声明该变量已经在别处定义啦(别处指A文件),要在此处引用,此时作用域是以下全部函数
int A(void)
{
i=10;
retern 0;
}
int B(void)
{
i=11;
retern 0;
}
//这里是C文件
int C(void)
{
extern int i;//声明该变量已经在别处定义啦,要在此处引用,此时作用域是该函数(C)
i=10;
retern 0;
}
int D(void)
{
...
}
局部变量:可用范围是“在定义的那个函数或者循环体内”,当退出函数/循环体时该局部变量所占用的内存也被收回。
//这里是D文件
void SUM(void)//累加
{
int i=1;//该变量为SUM的专用变量,属于局部变量
i=i+1;
}
void RIDE(void)//累乘
{
int i=3;//该变量为RIDE的专用变量,属于另一个局部变量
i=i*2;
}
静态局部变量:可当使用static声明全局变量,此时该变量就升级成了静态全局变量,其使用范围是“声明此变量所在的文件内”。它和全局变量区别在于:其他的文件即便使用extern声明该变量也不能使用,仅在当前文件中使用。
静态局部变量:当使用static声明局部变量,此时该变量就升级成了静态局部变量,其使用范围是“声明此变量所在的函数/循环体内”。它不会随着函数/循环体的结束而消失,而是会继续存在,并且定义只用到一次。
static,英语单词,形容词、名词,作形容词的意思是“静态的;静电的;静力的”,作名词的意思是“静电;静电干扰”。
//这是E文件
int fun(int a)
{
static int i=0;
i=a+i
return i;
}
int main(void)
{
int b,c;
b=fun(2);
c=fun(3);
return 0;
}
//运行完以后b=0+2=2,c=2+3=5
2.生命周期的区别:
全局变量:随进程存在
局部变量:存在于“定义到函数/循环体结束”的时间段,然后其内存被释放
静态全局变量:随进程存在
静态局部变量:随进程存在
3.内存分配的区别:
全局变量:全局(静态)存储区
局部变量:存放在栈中,只有在所在函数被调用时才动态地为变量分配存储单元
静态全局变量:全局(静态)存储区
静态局部变量:全局(静态)存储区
3.1 全局(静态)存储区:分为DATA段和BSS段。程序运行结束时自动释放。
3.1.1 DATA段(全局初始化区):存放初始化的全局变量和静态变量。
3.1.2 BSS段(全局未初始化区):存放未初始化的全局变量和静态变量。在程序执行之前会被系统自动清0,所以未初始化的全局变量和静态变量在程序执行之前已经为0。
3.2 把局部变量改变为静态局部变量是改变了它的存储方式(即生命周期)。把全局变量改变为静态全局变量是改变了它的作用域,限制它的使用范围。因此static这个说明符在不同的地方所起的作用是不同的
4.使用方式的区别:
全局变量在声明后程序的各个部分都可以用到,但是局部变量只能在局部使用。
函数内部使用优先级:局部变量>全局变量。
5.总结:
1.若全局变量仅在单个C文件/单个函数中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度;
2.设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题,因为他们都放在静态数据存储区,全局可见;
3.当函数内使用由static声明的变量时,函数会带“内部记忆”的功能,即该变量每次进去都会直接读取内存中的值,不会像局部变量一样每次进入函数都定义一次。