C语言作用域
作用域是程序中的一段区域。在同一个作用域上,C程序中每个名字都与唯一的实体(意指基本类型和自定义类型)对应;只要在不同的作用域上,那么程序中就可以多次使用同一个名字,对应不同的作用域中的不同实体。
一个C语言可以由任意多的源文件组成,每个源文件可以有任意多的函数,在函数中可以包含任意多的复合语句块,复合语句中又可以嵌套任意多的复合语句子块;另外,一个程序还可以有任意多的函数原型、结构体类型和共用体类型声明。所以C语言的作用域分类如下:
1.文件作用域:一个C程序的所有源文件,具体到某个文件是指该文件头到文件尾
2.函数作用域:函数头到函数尾...}(实际上是函数头和函数体)
3.块作用域。
4.类型声明作用域:例如结构体的声明。
5.函数原型作用域:函数原型作用域是函数原型中括号内的区域,即形参列表所处的区域。
上述的几种作用域文件作用域是全局作用域,其余皆是局部作用域。
C语言实体规则(又称可见性):实体总是在作用域中的
规则一:同一个作用域内不允许有相同的名字的实体,不同作用域的实体互不相见,可以有相同的名字。
规则二:实体在包含它的作用域内,从定义或声明的位置开始,按文件行的顺序往后直到该作用域结束均是可见的,包含作用域内的所有子作用域及其嵌套。
规则三:若实体A在包含他的作用域内的子区域中出现了相同名字的实体B,则实体A被屏蔽,及实体A在子区域中可见的是实体B(实际上是内层屏蔽外层)
规则四:可以使用 extern 声明将变量或函数的实体的可见区域往前延伸,称为前置声明(forward declaration)
规则五:在全局作用域中,变量或函数实体若使用static修饰,则该实体对于其他源文件是屏蔽的,成为私有的。
测试程序:
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
int i=0;
int j=21;
{
i++;
j++;
printf("i=%d\tj=%d\n",i,j);
int i=12;
int j=13;
i++;
j++;
printf("i=%d\tj=%d\n",i,j);
}
return 0;
}
由此实际上我们可以看出:实际上出现这些情况的原因是因为编译器要确定是变量的声明还是使用因此要对源程序的变量进行一层一层的划分,该层找不到就跳到上一层去寻找,'{}'就形成了一道分界符,详见编译原理有关课程。
关于声明与定义:
声明有两重含义:表明名字已在别的地方有定义(实际上是使用性声明,不分配内存,用原先的内存),告知编译器。 二是表明名字已用,别的地方不能在使用该名字。
定义:表明首次出现,指明要让编译器分配东西给我。
关于函数的声明与定义:
由于编译器对每个文件的编译是独立的,所以在一个文件的中得到的声明信息不会传到另一个文件中,换言之,需要在另一个文件重新给出声明信息。如果是在与函数定义不同的源文件中出现了函数调用,
那么要在那个文件中再次出现函数原型,要不然在该文件中编译器无法识别报出语法错误。