局部变量和全局变量
目录
一、局部变量
二、全局变量
一、局部变量
不同函数的变量无法相互访问:
void func(int a)
{
int b, c;
……
for (int i = 0; i < 10; i++)
{
……
}
}
int main()
{
int m, n;
……
return 0;
}
func函数中定义了一个参数两个变量:a、b、c,还有一个i,这4个变量在main函数中是无法访问的;
同样的道理,在main函数中定义的m、n在func函数中也是无法访问到的,并不是说main是主函数就有特权可以访问的到,在C语言里函数的级别是一样的。
另外可以发现在func函数里有一个复合语句:由for语句构成的复合语句,在for语句第一个表达式这里定义了一个变量i,要注意在复合语句这一块for语句以及下面大括号括起来的这个语句块构成的复合语句,那么在这里的变量i作用范围就仅仅只限于这个复合语句里边,出了外边就访问不了了。
举个例子:
输入vi test1.c回车进入编译器:
#include <stdio.h>
int main( )
{
int i = 520;
printf("before, i = %d\n", i);
for (int = 0; i < 10; i++)
{
printf("%d\n",i) ;
}
printf("after, i = d\n", i);
return 0 ;
}
输入gcc -std=c99 test1.c && ./a.out回车得出结果:
before, i = 520
0
1
2
3
4
5
6
7
8
9
after, i =520
可以发现在for中重复去定义一个同名的变量编译器并没有报错,因为在同一个函数里边是没办法同时定义两个相同名字的变量的,这会发生冲突,但是编译器竟然没有报错,这是因为他们的作用范围不同,所以不会互相发生冲突。
这里值得一提的是for语句因为定义了同名的变量i,所以它屏蔽了外边的i,内部的屏蔽了外部的,那么在这内部打印出的i必然是指里边的,而在外部的依然还是外部的。
不仅是打印,其他的访问、修改,改动的都是里边的这个i,因为同名所以把外面的屏蔽了。
二、全局变量
全局变量
- 在函数里边定义的,叫做局部变量;在函数外边定义的,叫做外部变量,也叫全局变量。
- 有时候,可能需要在多个函数中使用共同的一个变量,那么就会用到全局变量。因为全局变量可以被本程序中其他函数所共用。
如果每一名犯人都是一个函数,要统计小郭到底被抱了多少次,那么就在函数外部定义一个全局变量来统计。
输入vi test2.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();
printf("小郭今天被抱了%d次! \n", count);
return 0;
}
输入gcc -std=c99 test2.c && ./a.out回车得出结果:
小郭今天被抱了4次!
因为count这个变量的定义在所有的函数的外部,所以它是全局变量,它的作用范围是整个程序,无论main函数也好ABC函数也罢,都可以对它进行访问和修改。所以这里初始化为零,之后count++,+1,又+1,又+1,因为这里调用了4次,a一次,b一次,c一次,b觉得很舒服又来了一次,所以小郭被抱了4次。
- 如果不对全局变量进行初始化,那么它会自动初始化为0。
- 如果在函数的内部存在一个与全局变量同名的局部变量,编译器并不会报错,而是再函数中屏蔽全局变量(也就是说在这个函数中,全局变量不起作用)。
例子:
输入vi test3.c回车进入编译器:
#include <stdio.h>
void func();
int a,b=520;
void func()
{
int b;
a= 880;
b= 120;
printf("In func, a = %d,b=%d\n", a, b);
}
int main( )
{
printf("In main, a = %d, b = %d\n", a, b) ;
func();
printf("In main, a = %d, b = %d\n", a, b);
return 0 ;
}
这个实验就是要看一下对这个局部变量b会对它进行屏蔽,所以说在这里的修改应该不会影响到这个全局变量b的值,这是第一个实验的目标。第二个实验是要证明说这个a如果没有对它进行初始化,它会自动初始化为0。
程序一执行就进入main函数,首先打印它,a没有对它进行初始化,打印的是0还有520,然后进入func函数,定义了一个局部变量b和全局变量是同名的,所以在func里边这个b把全局变量b屏蔽了,所以b=120,所以这里打印的应该是a=880。
输入gcc -std=c99 test3.c && ./a.out回车得出结果:
In main, a = 0, b = 520
In func, a =880, b =120
In main, a = 880, b =520
如果一个全局变量在函数的定义之后才被定义,会有什么事情发生呢,不妨试试看:
输入vi test4.c回车进入编译器:
#include <stdio.
void func( );
void func()
{
count++;
}
int count =0;
int main()
{
func( ) ;
printf(“%d\n”,count);
return 0;
}
输入gcc -std=c99 test4.c && ./a.out回车得出结果:
test4.c: In function ' func':
test4.c:7: error: 'count'undeclared(first use in this function)
test4.c:7: error:(Each undeclared identifier is reported only once
test4.c:7: error: for_each function it appears in. )
可以看见报错,需要用extern关键字:
#include <stdio.
void func( );
void func()
{
extern count;
count++;
}
int count =0;
int main()
{
func( ) ;
printf(“%d\n”,count);
return 0;
}
输入gcc -std=c99 test4.c && ./a.out回车得出结果:
1
这个技巧可以用在多个源文件之间。
不要大量的使用全局变量
- 使用全局变量会使程序占用更多的内存,因为全局变量从被定义时候开始,直到程序退出才被释放。
- 污染命名空间,虽然局部变量会屏蔽全局变量,但这样一来也会降低程序的可读性,人们往往很难一下子判断出每个变量的含义和作用范围。
- 提高了程序的耦合性,牵一发而动全身,时间久了,代码长了,都不知道全局变量被哪些函数修改过。