我有一个包含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;
Run Code Online (Sandbox Code Playgroud)
我很难理解为什么原始程序员这样做,所以我删除了定义Extern的东西.现在,我想我了解TU与计算器的帮助的事情: 1, 2, 3.
现在我明白我应该在库中的一个.c文件中定义全局变量,并在.h文件中使用extern.问题是我不想重复代码.
我应该回到那个#define外部伏都教吗?
这里的诀窍是.h文件以两种不同的方式使用 - 它被用作普通的.h文件,其中声明了所有的全局变量,extern并且它也用于定义全局变量(没有extern).这是一个丑陋的黑客,但你可以理解为什么有人觉得有必要,如果你有大量的全局变量(一个非常糟糕的软件设计的确定迹象!).
无论如何,有一个更优雅的解决方案 - 您可以将所有全局变量放在一个全局结构中,例如
//
// globals.h
//
typedef struct {
int a;
int b;
// ...
int z;
} Globals;
extern Globals globals; // declaration
Run Code Online (Sandbox Code Playgroud)
-
//
// globals.c
//
#include "globals.h"
Globals globals; // definition
Run Code Online (Sandbox Code Playgroud)
-
然后,当你需要引用全局时,例如globals.a而不仅仅是a,这可能看起来很不方便,但这可以说比仅仅在整个代码中分散裸露的全局变量更清晰,更易于管理.
在每个.c文件中定义Extern是一种糟糕的模式.删除它可能是最好的,但您需要以某种方式替换此功能.一种方法是您可以在.c文件中使用需要定义这些全局变量的#define.此定义将向.h发出信号,表示不是全局变量.
例如:一个库.c文件:
#define FOO_LIBRARY_C
#include "foo_library.h"
Run Code Online (Sandbox Code Playgroud)
其他.c文件:
#include "foo_library.h"
Run Code Online (Sandbox Code Playgroud)
foo_library.h:
#ifdef FOO_LIBRARY_C
int a,b,c
#else
extern int a,b,c
#endif
Run Code Online (Sandbox Code Playgroud)
要么
#ifdef FOO_LIBRARY_C
#define GLOBAL_PREFIX
#else
#define GLOBAL_PREFIX extern
#endif
GLOBAL_PREFIX int a,b,c
Run Code Online (Sandbox Code Playgroud)
这减少了在每个单个源文件(除了一个)中定义相同内容的需要,并有助于减少错误.我也不会称它为外部因为它可能只会造成混乱,因为它可能是也可能不是"外部"
也许我也缺少了一些东西,但是我总是对我创建的所有头文件使用包含防护:
foo.h:
#ifndef FOO_H
#define FOO_H
extern int foo;
#endif
Run Code Online (Sandbox Code Playgroud)
foo.c:
#include "foo.h"
int foo = 0;
Run Code Online (Sandbox Code Playgroud)
bar.c:
#include "foo.h"
#include <stdio.h>
int main(int argc, char** argv)
{
printf("foo:%d\n",foo);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
宏的东西对此很愚蠢。刚放
extern int myGlobal;
Run Code Online (Sandbox Code Playgroud)
在您的头文件和一个.c文件中(通常是一个与.h文件同名的文件),
int myGlobal;
Run Code Online (Sandbox Code Playgroud)
无需为此级别的“重复”感到压力。