同样是以一段代码开头:
/*************************************************************************/
#include <stdio.h>
int main(void)
{
int a;
for(int i = 0; i < 10; i++)
{
if(i > 5)
int m = i;
a = m;
}
return 0;
}
/***************************************************************************/
我们有时候就会写出像这样看似没有什么问题但是实际确实错误的代码,如果去编译的话,那么编译器一定会提示错误,说第9行(也就是 a = m; 这一行)的 m 没有定义。但是我们感到很奇怪的是命名我在第8行的时候就已经定义了的,为什么会有这个错误的提示呢?原因就在于m的作用域。我们很能理解整个main函数是一个代码块,但是同样要值得注意的是,if条件语句同样也是一个代码块,尽管它少了一个隐含的 { } 。而在代码块中定义的变量具有代码块作用域,从该变量被定义到包含该定义的代码块的末尾,该变量为可见,而在其他地方,该变量均不可见,即使是对于上层代码块for循环中,变量m依旧不可见。所以以后碰到这样的问题,我们一定要小心。要时刻注意自己定义的局部变量的作用域,可是即使是这样,我们有时候仍然会感到很困惑,我怎么知道它究竟在哪个代码块内?比如这样的例子:
/****************************************************************************/
int main(void)
{
int m;
{
int a = 5;
}
m = a;
}
/**************************************************************************/
如果编译的话,编译器同样会报错,提示第7行有未定义的变量a;可见,对于C而言,一个大括号就代表一个代码块,不管这个大括号有没有实际的意义。所以对于之前的if语句,为了能更好地显出代码的层次感,还是应该加上{ } 以避免不必要的错误发生。
总的来说,按照范围的不同,变量的作用域大体上可以分为 代码块作用域、函数作用域、文件作用域(也就是平常所说的全局变量)。其中具有代码块作用域和函数作用域的变量具有空链接,这意味着它们由其所定义的代码块或函数所私有。而具有文件作用域的变量具有内部链接和外部链接两种属性,一个具有外部链接的变量可以在一个多文件程序的任何地方使用,一个具有内部链接的变量则只能在所定义的文件内部使用。怎么区别呢?这时就要考虑关键字static了。 如下:
int a =5; //文件作用域,外部链接
static int b = 3; //文件作用域,内部链接
int main(void)
{
……
}