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

时间:2010-01-15 01:13:09

标签: c

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

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

7 个答案:

答案 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。

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