假设我在main.c中有一些全局变量GLOBAL,但我的main.c有一个#include“other.h”。但是other.h也有全局变量GLOBAL。
当我在main中编写GLOBAL时,如何让编译器知道我的意思。我可以使用“this”关键字吗?
答案 0 :(得分:10)
C程序中不能有两个具有相同名称的全局变量。 C可能允许通过暂定定义规则在同一文件范围内进行多个定义,但无论如何所有定义都将引用相同的变量。所以,显然你的问题是基于不正确的前提。这里没有“哪一个”的问题。您只有一个变量。
例如,您可以在C翻译单元中使用一系列文件范围定义
int i;
int i;
int i;
这在C语言中是合法的(与C ++相反),所有这些定义实际上定义了相同的变量,而不是三个不同的变量。
当然,如果其中一个变量被定义为局部变量(如果是这样,你必须在你的问题中说明)(顺便说一句,为什么它被称为GLOBAL
呢?),那么它会隐藏在文件范围(或任何更高的范围)中定义的变量的名称。在这种情况下,无法访问C中的隐藏名称。重命名局部变量以避免隐藏全局变量。
你的意思是“other.h也有变量”也不清楚。在这种情况下,“有”意味着什么?变量是否在other.h中定义了?或者只是宣布?如果它刚刚被声明,那么它并没有真正“拥有”它。如果定义那么......那么真正的问题是:为什么要在.h文件中定义变量?
答案 1 :(得分:5)
你实际上没有两个变量。只有一个,如果两个模块使用相同的名称声明相同的全局,您将获得编译器(或链接器)错误,或者编译器/链接器将决定您认为这是单个变量的冗余声明并合并它们
答案 2 :(得分:2)
与其他人提到的一样,避免使用相同的全局变量/函数名称。养成为模块名称添加前缀的习惯。即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,
i.e. "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,
i.e. "public". */
int MOD_publicVariable = 42;
void MOD_publicFunction(int arg) {...}
/* Declarations for entities that CAN'T be accessed by other modules,
i.e. "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与静态之间的区别。
让我感到烦恼的是,C教科书和课程要么忽略或掩盖了多模块编程的艺术。
修改强> 我忘了提到你通常不应该让其他模块可以访问全局变量(即使它们“私有”)。如果其他模块需要访问该变量,请提供“public”“setter”和/或“getter”函数。
答案 3 :(得分:0)
每个对象模块只能有一个定义。第二个,如果具有相同的内容,将被忽略。如果不同,将导致编译器错误。
答案 4 :(得分:0)
这可能不是您正在寻找的答案,但为什么不首先尝试避免这种情况(并且可能(通过)使用全局变量?
答案 5 :(得分:0)
首先,如果这是一个问题,那么你正在使用一个糟糕的库,如果可能的话应该重写/切换。如果你做不到,你可以这样做:
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
,则可能无效。 (但无论如何它值得一试。)
答案 6 :(得分:-1)
我假设您已经在程序中定义了变量,而不是使用#define在预处理器中定义。
如果要引用main.c中创建的那个,只需键入global。要引用头文件中的那些,请使用关键字extern。
尽管说实话,你最好将它们声明为两个单独的变量名称。