9

C ++中的全局变量和文件变量有什么区别?

谢谢!

4

4 回答 4

18

在 C 和 C++ 中,您可以使用声明前面的 static 关键字使全局变量只能从声明它的文件中访问。不使用 static 关键字的全局变量可以从编译到程序中的任何 C 或 C++ 文件中访问。

静态全局方法在 C++ 中被弃用,取而代之的是匿名命名空间。放置在匿名命名空间内的任何声明也只能从该文件中访问。

于 2009-02-10T22:50:43.837 回答
7

C++ 程序一次编译一个翻译单元(基本上这意味着每个 .cpp 文件都是独立编译的)。

默认情况下,非变量、非const函数inlinetypedefs 具有内部链接:这意味着它们对其他翻译单元不可见。如果其他翻译单元引用了具有内部链接的符号(在声明它之后,这需要变量的关键字extern),链接器将无法找到它们。

要明确要求内部链接,请使用关键字static,或者更好的是使用未命名的命名空间。

于 2009-02-10T23:11:24.427 回答
6

注意:这些规则适用于 C++ 和 C 一样,涉及类/结构/命名空间范围。(我没有注意到问题是关于 C++,而不是 C。)

请记住(在大多数情况下)C 源文件被编译成目标文件。目标文件有一个“导出”表,它告诉链接器(链接时)它提供了哪些符号。符号是指代函数或变量(在大多数情况下)的名称(其确切名称取决于 ABI)。

在 C 源文件中声明全局变量时,如下所示:

// fileA.c
int hello = 42;

void printMessage() {
    printf("Hello, %d world(s)!\n", hello);
}

hello并被printMessage出口。当 C 目标文件请求一个名为 ' hello' 的符号(假设是一个简单的 ABI)时,链接器将其与hello导出的fileA.c.

现在换一种情况。当您像这样声明文件局部变量时:

// fileB.c
static int world = 9001;

static void messagePrint() {
    printf("It's over %d!\n", world);
}

world并且messagePrint出口。当 C 目标文件请求一个名为 ' hello' 的符号时,链接器无法将其与helloof连接起来,因为其中(或其他)fileB.c没有关于它的信息。fileB.obj

怎么可能messagePrint知道world呢?两者都在同一个翻译单元中。范围在这里接管。我相信您会通过 Google 找到很多有关范围的信息。

(符号名称是否与 C 中的函数/变量名称标准匹配?我知道它与 C++ 不同(其中没有名称修饰的标准化),这就是我首先提到 ABI 的原因。)

(((如果 ABI 是正确的术语,甚至?;P))

于 2009-02-10T23:14:25.637 回答
0

唯一的区别是文件变量只能在文件内部访问。但它们的寿命相同。

于 2009-02-10T22:47:50.583 回答