局部变量和全局变量
局部变量
之前变量就是在内存中开辟一个存储数据的位置,并给它起个名字。因为那时候只有一个 main 函数,所以那时我们对它的作用范围一无所知,觉得定义了变量就随时随地可以使用它……直到我们学习函数才发现,不同函数之间定义的变量,它们是无法相互进行访问的。
C99 新标准
C99 标准允许在 for 语句的第一个表达式部分声明变量,它的作用范围仅限于复合语句的内部。
#include<stdio.h >
int main()
{
int i=520;
printf("before,i=%d\n",i);
for(int i=0;i<5;i++)//这里的i的作用范围仅限于for循环
{
printf("%d\n",i);
}
printf("after,i=%d\n",i);
return 0;
}
值得一提的是,这里 for 语句因为定义了同名的i变量,所以它屏蔽了第一个定义的i变量。换句话说,在 for 语句的循环体中,无法直接访问到外边的i变量。
C 语言允许在程序的任意位置声明变量
允许变量在需要时才声明是一件非常棒的事情,因为如果当你的函数体非常庞大的时候,你总不会愿意往前翻好几个屏幕去看某个变量 i、j、k 是什么意思吧。
有些朋友可能会有所担心:“要是到处定义变量,那一不小心重复定义了怎么办?”,其实这是编译器应该关心的问题(编译器会找出重复定义的变量并报错),你放心使用就可以了。
全局变量
在函数里边定义的,我们叫局部变量;在函数外边定义的,我们叫外部变量,也叫全局变量。有时候,我们可能需要在多个函数中使用共同的一个变量,那么就会用到全局变量。因为全局变量可以被本程序中其他函数所共用的。
假设有这么一个故事:有那么一个班级的学生特别喜欢吃螺蛳粉,采访:你今天吃螺蛳粉了吗?
a说:老好吃了,早上吃了一次!
b说: 那可不吗,我中午吃的,今晚继续吃!
c说:大家都吃,我也吃了,入坑了!
现在我们来写一个小程序统计大家一共吃螺蛳粉的次数:
#include<stdio.h>
void a();
void b();
void c();
int count=0;//在函数外定义的变量为全局变量
void a()
{
count++;
}
void b()
{
count++;
}
void c()
{
count++;
}
int main()
{
a();
b();
c();
b();//b夜宵又吃了一次
printf("计数为:%d\n",count);
return 0;
}
全局变量初始化
与局部变量不同,如果不对全局变量进行初始化,那么它会自动初始化为 0。
当局部变量和全局变量同名时
如果在函数的内部存在一个与全局变量同名的局部变量,编译器并不会报错,而是再函数中屏蔽全局变量(也就是说在这个函数中,全局变量不起作用)。
#include<stdio.h>
void func();
int a,b=520;
void func()
{
int b;//局部变量
a=886;//在函数func中并没有定义局部变量a,所以改动的就是全局变量a的值
b=120;//局部变量,并不影响全局变量
printf("in func,a=%d,b=%d",a,b);
}
int main()
{
printf("in main,a=%d,b=%d\n",a,b);//全局变量无定义的时候初始化为0
func();
printf("in main ,a=%d,b=%d",a,b);
return 0;
}
in main,a=0,b=520
in func,a=886,b=120
in main ,a=886,b=520
如果一个全局变量在使用之后才被定义
那么你可以在对该全局变量进行访问之前,使用 extern 关键字对该变量名进行修饰。这样就相当于告诉编译器:这个变量我在后边定义了,你先别急着报错。
#include<stdio.h>
void func();
void func()
{
//extern int count;//加上这句就不会报错,中间的类型可要可不要,最好还是加上数据类型
count++;
}
int count=0;
int main()
{
func();
printf("%d\n",count);
return 0;
}
[Error] 'count' undeclared (first use in this function)
不要大量的使用全局变量:
使用全局变量会使得程序占用更多的内存,因为全局变量从定义时候开始,知道程序结束才会被释放;
污染命名空间,虽然局部变量会屏蔽全局变量,但这样一来也会降低程序的可读性,人们往往很难一下子判断出每个变量的含义和作用范围。
提高了程序的耦合性,牵一发而动全身,时间久了,代码常量,我们就不知道全局变量被那些函数修改过。