【问题标题】:C extern variable accessC 外部变量访问
【发布时间】:2012-03-29 09:50:08
【问题描述】:

我有一个声明了外部变量的头文件。

所以它在这个 a.h 文件中看起来像这样

  extern uint16_t externVariable;

所以我有 2 个 .c 文件 b 和 c ,我想在其中访问 a.h 文件中的 extern 变量。在 b 和 c .c 文件中,我已经包含了 a.h 文件

当我没有在 b 中声明变量但在 c 中声明(没有 extern 一词)时,类似于

 uint16_t externVariable;

它工作正常。但是当它在 b 和 c 中时,我有一些编译错误。有没有办法解决这个问题?

这样做的原因是因为我在 .c 文件中有代码,我想将代码分成 2 个不同的 .c 文件以保持整洁和清晰。

【问题讨论】:

  • 你真的要说“一些编译错误”吗?您无法指定错误是什么?
  • 顺便说一句:您已将此问题标记为 C,但您指的是 .cpp 文件,这是 C++ 的典型扩展名。 C 与 C++ 不同。

标签: c extern


【解决方案1】:

变量只能在一个源代码文件中声明。 (在您的示例中为文件b.c)。

通过在头文件中声明 extern,甚至在多个 .c 文件的顶部声明它,您实质上是在声明“该变量并不存在于这里,它是外部的。但它确实存在,而且它将对您可见。”

变量应该只“存在”在一个文件中。

如果您尝试使其在多个源文件中“生效”(例如,通过在 b.cc.c 中声明它),您将收到您看到的错误。

【讨论】:

  • 值得一提的是,链接器会发出错误,因为它在两个不同的文件中看到相同的名称。这就像在两个不同的源文件中定义相同的函数并链接结果。
  • 另外值得注意的是,非外部声明应该在一个只会编译一次的文件中声明,即。 not 通常在标题中。如果它在标题中并且标题包含在多个位置,您可能会收到类似@NiklasB 的错误。提及。
【解决方案2】:

"extern" 告诉 C 编译器这个函数或变量是在别处声明的,所以即使没有在头文件中声明它们并在 .c 文件中包含 .h 也可以使用它们。请注意,“extern”表示此变量不是初始声明,初始声明不得包含 extern 关键字。

在您的情况下,您在一个文件中声明了一个外部变量,而没有添加“静态”关键字,因此该变量的范围将是整个项目。然后你声明了“uint16_t externVariable;”在 2 个地方,编译器认为它们都是初始声明具有相同的名称,因此开始了冲突。

例如,你可以这样做:

示例 1:

a.c: uint16_t externVariable;

b.c: extern uint16_t externVariable;

不用担心你的头文件,你可以在 a.c 和 b.c 中使用 externVariable。

示例 2:

a.c: #include "a.h"

b.c: #include "a.h"

a.h: uint16_t externVariable;

这行得通。

示例 3:

a.c: extern uint16_t externVariable;

b.c: uint16_t externVariable;

c.c: uint16_t externVariable;

这不起作用,因为您在多个地方声明了 externVariable。

示例 4:

a.c: 静态 uint16_t externVariable;

b.c: 静态 uint16_t 外部变量;

这将起作用,因为“静态”关键字限制了它们的范围,因此它们不会发生冲突。

示例 5:

a.c: 静态 uint16_t externVariable;

b.c: 静态 uint16_t 外部变量;

c.c: extern uint16_t externVariable;

这仍然不起作用,因为“静态”关键字限制了它们的范围,并且编译器无法找到您在 c.c. 中声明 externVariable 的位置

您也可以查看 TCPL,它对这些关键字给出了更大的了解,希望这些示例可以帮助:)

【讨论】:

    【解决方案3】:

    extern 的想法是让编译器知道这个变量是在不同的源文件中分配的,所以你确实不需要需要在另一个源文件中再次声明它。只需将其保留在一个文件中(我会说 a.cpp,因为它在 a.h 中)并包含 a.h,它将适用于所有 .cpp 文件。

    【讨论】:

      猜你喜欢
      • 2023-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多