我有一个包含100多个全局变量的包含文件。它正在库中使用,但是我链接lib的一些程序也需要访问全局变量。
它的构建方式:
// In one library .c file
#define Extern
// In the programs that use the globals
#define Extern extern
// In the .h file
Extern int a,b,c;
我很难理解为什么原始程序员会这样做,所以我删除了定义Extern的东西。现在我想借助stackoverflow了解TU的事情: 1, 2, 3
现在我明白我应该在库中的一个.c文件中定义全局变量,并在.h文件中使用extern。问题是我不想复制代码。
我应该回到那个#define外部伏都教吗?
答案 0 :(得分:8)
这里的技巧是.h文件以两种不同的方式使用 - 它被用作普通的.h文件,其中所有的全局变量都被声明为extern
,并且它也用于定义全局变量本身(没有extern
)。这是一个丑陋的黑客,但你可以理解为什么有人觉得有必要,如果你有大量的全局变量(软件设计非常糟糕的确定迹象!)。
无论如何,有一个更优雅的解决方案 - 您可以将所有全局变量放在一个全局结构中,例如。
//
// globals.h
//
typedef struct {
int a;
int b;
// ...
int z;
} Globals;
extern Globals globals; // declaration
-
//
// globals.c
//
#include "globals.h"
Globals globals; // definition
-
然后当你需要引用全局时,例如globals.a
而不仅仅是a
,这可能看起来很不方便,但这可以说比在整个代码中分散裸露的全局变量更清晰,更易于管理。
答案 1 :(得分:6)
在每个.c文件中定义Extern是一种糟糕的模式。删除它可能是最好的,但您需要以某种方式替换此功能。一种方法是您可以在.c文件中使用需要定义这些全局变量的#define。此定义将向.h发出信号,表示不是全局变量。
例如: 一个库.c文件:
#define FOO_LIBRARY_C
#include "foo_library.h"
其他.c文件:
#include "foo_library.h"
foo_library.h:
#ifdef FOO_LIBRARY_C
int a,b,c
#else
extern int a,b,c
#endif
或
#ifdef FOO_LIBRARY_C
#define GLOBAL_PREFIX
#else
#define GLOBAL_PREFIX extern
#endif
GLOBAL_PREFIX int a,b,c
这减少了在每个源文件(除一个)中定义相同内容的需要,并有助于减少错误。我也不会称它为外部因为它可能会造成混淆,因为它可能是也可能不是“外部”
答案 2 :(得分:3)
也许我也错过了一些东西,但我总是在我创建的所有头文件中使用包含警戒:
foo.h中:
#ifndef FOO_H
#define FOO_H
extern int foo;
#endif
foo.c的:
#include "foo.h"
int foo = 0;
bar.c:
#include "foo.h"
#include <stdio.h>
int main(int argc, char** argv)
{
printf("foo:%d\n",foo);
return 0;
}
答案 3 :(得分:3)
宏观的东西对此很愚蠢。只需加上
extern int myGlobal;
在头文件和ONE .c文件中(通常是与.h文件同名的文件),放
int myGlobal;
无需对此级别的“重复”感到压力。
答案 4 :(得分:2)
我可能会遗漏某些内容,但我发现#define
内容与使用extern
关键字之间没有区别。
基本上,您必须在.h文件中声明变量并在.c文件中定义它们。不要认为它代码重复 - 我认为改变观点是你可以在这里做的最好的事情:)。您可以编写更多代码行,但它们是可读的:D。
答案 5 :(得分:1)
在大型程序中,使用一行来声明和定义全局变量非常重要。因此,上述宏观方法是解决问题的正确方法。
// globals.h
#ifndef GLOBALS_H
#define GLOBALS_H
#ifndef EXTERN
#define EXTERN extern
#endif
EXTERN int i;
#endif
// globals.c
#define EXTERN
#include "globals.h"
答案 6 :(得分:0)
根据经验,不要使用全局变量。有时您需要在文件中使用静态变量,但最好尽量避免使用它们:
有时在C中你无法避免它们(特别是在某人继承的代码中),但最好是将它们排除在外。
关于声明 - 在这种情况下可能会有所帮助:
// globals.h
#ifndef GLOBALS_H
#define GLOBALS_H
#ifndef EXTERN
#define EXTERN extern
#endif
EXTERN int i;
#endif
// globals.c
#define EXTERN
#include "globals.h"
答案 7 :(得分:-1)
虽然这一开始很烦人,但它确实可以帮助您避免两次输入内容或忘记在.c文件中包含某些内容。 我见过:
#define FOO_C_
#include "foo.h"
#include "bar.h"
int foo_doit(int a, int b, int c) {
...
}
foo.h是:
#ifndef FOO_H_
#define FOO_H_
#ifdef FOO_C_
#define GLOBAL
#define DECLARE( type, name, value) type name = value
#else
#define GLOBAL extern
#define DECLARE( type, name, value) extern type name;
#endif
GLOBAL int foo_doit(int a, int b, int c);
GLOBAL int foo_it; // uninitialized global variable
DECLARE(char, that[], "that");
// and sometimes using:
#ifdef FOO_C_
char word[] = letters;
#else
extern char word[];
#endif
#endif // FOO_H_