如何在C中访问正确的全局变量?

假设我在main.c中有一些全局变量GLOBAL,但我的main.c有一个#include“other.h”。 但是other.h也有全局变量GLOBAL。

当我在main中编写GLOBAL时,如何让编译器知道我的意思。 我可以使用“this”关键字吗?

我假设您已经在程序中定义了变量,而不是在使用#define的预处理器中定义。

如果要引用main.c中创建的那个,只需键入global。 要引用头文件中的那些,请使用关键字extern。

说实话,你最好将它们声明为两个单独的变量名称。

在C程序中,不能有两个具有相同名称的全局变量。 C可能允许通过暂定定义规则在同一文件范围中进行多个定义,但无论如何所有定义都将引用相同的变量。 所以,显然你的问题是基于不正确的前提。 这里没有“哪一个”的问题。 你只有一个变量。

例如,您可以在C转换单元中拥有一系列文件范围定义

 int i; int i; int i; 

这在C中是合法的(与C ++相反),并且所有这些定义实际上定义了相同的变量,而不是三个不同的变量。

当然,如果其中一个变量被定义为局部变量(如果是这样,你必须在你的问题中说明)(顺便说一下,为什么它被称为GLOBAL呢?),那么它将隐藏在中定义的变量的名称文件范围(或任何更高的范围)。 在这种情况下,无法访问C中的隐藏名称。重命名局部变量以避免隐藏全局变量。

你的意思是“other.h也有变量”也不清楚。 在这种情况下,“有”意味着什么? 变量是在other.h中定义的吗? 或刚刚宣布 ? 如果它刚刚被声明,那么它并没有真正“拥有”它。 如果在那里定义 ……那么,真正的问题是:为什么要在.h文件中定义变量?

你实际上没有两个变量。 只有一个,如果两个模块使用相同的名称声明相同的全局,您将获得编译器(或链接器)错误,或者编译器/链接器将决定您认为这是单个变量的冗余声明并合并它们。

像其他人提到的那样,避免使用相同的全局变量/函数名称。 养成为模块名称添加前缀的习惯。 即MODULE1_state,MODULE2_state等。

如果全局变量仅在一个源文件中使用,请不要在匹配的头文件中声明它。 相反,将其声明在源文件的顶部,并使用static关键字。 需要可以访问其他模块的变量需要使用extern关键字在头文件中声明。 这同样适用于全球职能。 它有助于维护您通常在面向对象语言(如C ++,Java,C#等)中使用的相同公共/私有规则。

例:

在module.h中:

 #ifndef MODULE_H /* Header guard */ #define MODULE_H /* Declarations for entities that CAN be accessed by other modules, ie "public". */ extern int MOD_publicVariable; extern void MOD_publicFunction(int arg); #endif // MODULE_H 

在module.c中:

 /* Definitions for entities that CAN be accessed by other modules, ie "public". */ int MOD_publicVariable = 42; void MOD_publicFunction(int arg) {...} /* Declarations for entities that CAN'T be accessed by other modules, ie "private". */ static double MOD_privateVariable = 12.34; static void MOD_privateFunction1(void); static void MOD_privateFunction2(void); /* Function definitions. */ void MOD_privateFunction1(void) { int localVariable; /* This doesn't need the module prefix. */ .... } void MOD_privateFunction2(void) { .... } 

模块前缀(MOD_)可以在模块之后直接命名,也可以使用缩写。 实验,你最终会选择你喜欢的约定。 始终如一地使用这样的前缀模拟OO语言中的类/模块/命名空间的概念。

确保您知道声明与定义之间的区别,以及extern与static之间的区别。

让我感到烦恼的是,C教科书和课程要么忽视或掩盖了多模块编程的艺术。

编辑:我忘了提到你通常不应该让其他模块可以访问全局变量(即使它们“私有”)。 如果其他模块需要访问该变量,请提供“public”“setter”和/或“getter”函数。

每个对象模块只能有一个定义。 第二个,如果具有相同的内容,将被忽略。 如果不同,将导致编译器错误。

这可能不是您正在寻找的答案,但为什么不首先尝试避免这种情况(并且可能(全部)使用全局变量?

首先,如果这是一个问题,那么你正在使用一个糟糕的库,如果可能的话应该重写/切换。 如果你不能,你可以做这样的事情:

other.h:

 int GLOBAL; //...other stuff 

main.c中

 int GLOBAL; #define GLOBAL OTHER_GLOBAL #include "other.h" #undef GLOBAL int main(int argc,char** argv) { printf("%i %i",GLOBAL,OTHER_GLOBAL); getchar(); return 0; } 

但是,如果像资本所暗示的那样, GLOBAL#define ed,这可能不起作用。 (但无论如何都值得一试。)