命名冲突与static修饰符
两个具有相同名称的外部对象实际上代表的是同一个对象,即使编程人员的本意并非如此,系统也会如此处理。因此,如果在两个不同的源文件中都包括了定义
int a;
那么要么表示程序错误(如果链接器禁止外部变量重复定义的话),那么在两个源文件中共享a的同一个实例(无论两个源文件的外部变量a是否应该共享)。
即使其中a的一个定义是出现在系统提供的库文件中,也仍然进行同样的处理。
ANSI C定义了C标准函数库,列出了经常用到因而可能会引发命名冲突的所有函数。如果一个库函数需要调用另一个未在ANSI C标准中列出的库函数,那么它应该以“隐藏名称”来调用后者。这使得程序员可以定义一个函数,而不用担心库函数本应调用库文件中的函数,却调用了这个用户定义的函数。但大多数C语言实现并不是这样做的,因此命名冲突仍然是一个问题。
static修饰符是一个能够减少此类命名冲突的有用工具。
static int a;
其意义与下面的语句相同:
int a;
只不过,a的作用域限制在一个源文件内,对于其他源文件,a是不可见的。因此,如果若干个函数需要共享一组外部对象,可以将这些函数放到一个源文件中,把它们需要用到的对象也都在同一个源文件中以static修饰符声明。
static修饰符不仅适用于变量,也适用于函数。如果函数f需要调用函数g,而且只有函数f需要调用函数g,我们可以把函数f与函数g都放到同一个源文件中,并且声明函数g为static:
static int g(int x) {
/* g函数体 */
}
void f() {
/* 其他内容 */
b = g(a);
}
我们可以在多个源文件中定义同名的函数g,只要所有的函数g都被定义为static,或者仅其中一个函数g不是static。因此,为了避免可能出现的命名冲突,如果一个函数仅仅被同一个源文件的其他函数调用,我们就应该声明该函数为static。