27

在 C 书中,它说:

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

有人可以解释什么是“内部名称”、“外部名称”、“外部变量”吗?如果能举个例子就更好了。

4

4 回答 4

36

我抚摸着我的白胡子,用圣洁而浮夸的声音说:

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

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

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

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

因此,例如,您可以在函数中包含这些 C 变量

 int myFavoriteItem;
 int myFavoriteThing;

那很好。但是您可以将它们声明为外部变量,如下所示:

 extern int myFavoriteItem;
 extern int myFavoriteThing;

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

 extern int myFavo;
 extern int myFavo;

这些将是重复的声明。C 编译器需要捕获这种事情并抛出错误,而不是向目标文件写入重复的声明。这对程序员有很大帮助:目标文件中的重复声明会生成非常模糊的链接编辑器错误消息。

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

于 2012-10-19T17:06:21.467 回答
4

外部名称:

“外部”名称是对其他编译单元可见的名称,例如使用“extern”关键字声明的非静态函数和变量。这些名称必须暴露给链接器和加载器。在过去的日子里,一些链接器和加载器只能处理非常短的名称。

内部名称:

“内部”名称是在正在编译的模块之外不可见的名称——基本上是任何具有“静态”作用域的名称,或者是函数本地的任何名称。C 编译器必须处理这些名称,而不是其他任何东西

于 2016-07-28T07:15:42.580 回答
1

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

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

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

在实践中,这不再是一个问题。C99 增加了这些限制,大多数现代编译器取消或显着增加了这些限制。例如,Visual C++在编译 C 时允许所有标识符(内部或外部)中的唯一性为 247 个字符。

于 2012-10-19T16:52:13.543 回答
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 标准简单地规定了实现符合标准的有效字符的最小数量。

于 2012-10-19T17:08:43.483 回答