有人可以解释内部/外部变量名称吗?

时间:2012-10-19 16:46:25

标签: c variables

在C书中,它说:

  

至少内部名称的前31个字符是重要的。对于函数名和外部变量,该数字可能小于31,因为外部名称可能由语言无法控制的汇编程序和加载程序使用。对于外部名称,该标准仅保证6个字符和单个案例的唯一性。 if,else,int,float等关键字是保留的:您不能将它们用作变量名。它们必须是小写的。

有人可以解释什么是“内部名称”,“外部名称”,“外部变量”? 如果你能做一个例子会更好。

4 个答案:

答案 0 :(得分:27)

抚摸着我的白胡子,用圣人和浮夸的声音说话,我说:

在过去,当FORTRAN和COBOL统治计算世界时,新兴语言C必须适应现有的工具链。这些工具链包括链接编辑器(a / k / a连接器,a / k / a加载器)和仅处理短6个字符符号(变量和函数)的汇编程序。

这些工具链的C编译器在写出要由链接编辑器使用的目标文件时,必须假装变量和函数名称很短。这是坏消息。好消息是C程序中有很多符号,不需要显示在目标文件中。

例如,函数的名称......例如“main”和“sqrt”...需要显示在对象模块中,因此来自其他对象模块的代码可以使用它们。 “extern”样式全局变量的名称也是如此。这些是外部名称。

但是C程序中的所有其他名称,例如函数范围中的变量名称,结构成员的名称等等,都不必将其放入对象模块中。这些被称为“内部名称。”

因此,例如,您可以在函数

中包含这些C变量
 int myFavoriteItem;
 int myFavoriteThing;

那没关系。但你可以将它们声明为外部变量,如下所示:

 extern int myFavoriteItem;
 extern int myFavoriteThing;

有些系统会将这些名称写入目标文件,就像它们长六个字母一样(因为目标文件不知道如何处理更长的名称)。然后,他们将查看目标文件,就好像它们已经被声明为这样。

 extern int myFavo;
 extern int myFavo;

那些将是重复声明。 C编译器需要捕获此类事件并抛出错误,而不是将重复声明写入目标文件。这对程序员来说是一个很大的帮助:生成的目标文件中的重复声明实际上隐藏了链接编辑器错误消息。

您引用的段落指定编译器必须至少识别内部名称的31个字符和外部名称的6个字符。现代编译器和工具链不再具有不同的名称长度限制。

答案 1 :(得分:4)

外部名称:

"外部"名称是其他编译单元可见的名称,例如非静态函数和使用" extern"关键词。这些名称必须暴露给链接器和加载器。在Ye Olden Days,一些连接器和装载器只能处理非常短的名称。

内部名称:

"内部"名称是在被编译的模块之外不可见的名称 - 基本上是"静态"范围或函数的任何本地函数。 C编译器必须处理这些名称,但不能处理其他任何名称

答案 2 :(得分:1)

“内部名称”是函数中的标识符名称(实际上是局部变量名称)。

“外部名称”将是其他标识符的名称,包括函数名称和在全局范围内声明的或使用存储类extern声明的任何标识符。

基本上,任何需要“外部可见”的东西只能保证有6个(非区分大小写)唯一字符,这是非常有限的。

在实践中,这不再是一个问题。 C99增加了这些限制,大多数现代编译器都会消除或显着增加这些限制。例如,在编译C时,所有标识符(内部或外部)中都有Visual C++ allows 247 characters for uniqueness

答案 3 :(得分:0)

外部名称是具有外部链接的标识符。对于具有外部链接的标识符,它必须是文件范围的非静态或特别声明为“extern”。例如:

int global_variable;

int main(void)
{
    int local_variable;
    extern int extern_variable;
    return 0;
}

在上面的示例中,标识符global_variableextern_variable是外部名称。 local_variable是内部名称。

请注意,实际上,重要字符的数量大于31和6.例如,默认情况下,Microsoft的C编译器对内部名称和外部名称使用247个重要字符。 GCC将内部名称的所有字符视为重要字符。外部名称的重要字符取决于链接器(在大多数平台上,相同的规则适用于内部名称;​​所有字符都很重要。)

ANSI标准只是说明实现的最小有效字符数是符合标准的。