第七章 函数
第五节 局部变量和全局变量
1. 局部变量
在一个函数内部定义的变量叫局部变量,只在本函数范围内有效,也就是说,只有在函数内才能使用它们,
在函数外部是不能使用这些变量的
-
不同的函数可以使用相同的变量名,互相并不干扰(看内存地址并不相同)
-
形式参数,也是个局部变量,只在对应函数中有效
#include <iostream>
void func1(int tmp) {
// 无法使用main函数中定义的m,n,k
// 这里能使用的变量是tmp,x,y
int x, y;//局部变量
int m, n;//和main函数中m,n不相同
return;
}
int main() {
// m.n,k这三个变量只在主函数中有效,虽然主函数调用了其他函数,但在其他函数中依旧无法使用主函数中的局部变量
int m, n;
int k = 4;
return 0;
}
- 一种特殊的写法
#include <iostream>
int main() {
int a = 2, b = 3;
{
// 用大括号写一段代码,大括号扩起来的叫复合语句,
// 在复合语句中定义的变量,这些变量只在本复合语句中有效
// 复合语句也叫程序块
int c;//有效范围只在符合语句内,一旦离开复合语句,变量c的内存就被系统释放了
c = a + b;
}
return 0;
}
2. 全局变量
-
定义:在函数外部定义的变量就叫做全局变量(外部变量)
-
全局变量可以为本文件中其他函数所共用,全局变量的有效范围,从定义变量的位置开始到本源程序文件结束,
-
在一个函数中,既可以使用本函数中的局部变量,又可以使用有效的全局变量
全局变量的优点和缺点
优点:
- 增加了函数与函数之间的数据联系渠道,如果一个函数中改变了全局变量的值,就能影响到其他函数
相当于在各个函数之间有了直接的传递通道,不再需要通过实参和形参来传递参数
缺点:
-
只有在必要的时候才使用全局变量,因为全局变量在整个程序运行周期之间都占用内存,
而不像函数内部的局部变量,函数内部局部变量的特点是函数执行完毕后,这些局部变量所占的内存会被系统回收 -
降低了函数的通用性,因为函数执行实要依赖这些外部的全局变量,如果函数迁移到另外一个文件中,
那这些相关的外部变量就得一起跟着移植过去,并且如果你迁移到另外一个文件中也有同名全局变量,那就出现冲突了 -
全局量降低了程序的清晰性和可读性,读程序的人难以判断各个外部变量的值(函数可以修改全局变量的值)
#include <iostream>
int v_g = 100;//全局变量,在函数外定义的变量
int f1(int a) {
v_g = 88;
return 1;
}
char c1_g, c2_g;
char f2(int x, int y) {
int i, j;
return 0;
}
int main() {
int v = 1;
f1(v);
printf("v_g in main : %d", v_g);
return 0;
}
说明
-
如果某个函数想引用在它后面定义的全局变量,则可以用一个关键字叫extern做一个外部全局变量说明,
表示该变量在函数的外部定义.所以,全局变量放在所有函数之前,就可以省略全局变量说明 -
区分外部变量说明和外部变量说明:a)外部变量定义只能有一次,位置是所有函数之外,定义时会分配内存,定义时可以初始化值,
而同一个文件中,外部变量说明可以有很多次,外部变量说明不分配内存
#include <iostream>
extern int v_g;// 外部变量说明(不分配内存), 表示在某个地方定义了c1,c2
int f1(int a) {
v_g = 88;
return 1;
}
int v_g = 100;//全局变量,在函数外定义的变量
int main() {
int v = 1;
f1(v);
printf("v_g in main : %d", v_g);
return 0;
}
- 同一个源文件中,如果全局变量和局部变量重名,在局部变量范围内,全局变量不起作用
#include <iostream>
extern int v_g;// 外部变量说明(不分配内存), 表示在某个地方定义了c1,c2
int f1(int v_g) {
v_g = 88;//这里v_g是局部变量,要注意,仔细考虑一下,调用v_g并不会改变全局的v_g
return 1;
}
int v_g = 100;//全局变量,在函数外定义的变量
int main() {
int v = 1;
v_g = 3;
printf("v_g in main : %d\n", v_g);
{
int v_g;
v_g = 1;
printf("v_g in {} : %d\n", v_g);
}
f1(v);
printf("v_g in main after f1: %d", v_g);
return 0;
}