最优雅的方式来共享一个C数组

时间:2012-02-22 12:52:57

标签: c global-variables

我必须在使用C ++一段时间后回到(嵌入)C,并遇到以下问题:

我有一个包含很多次的源模块,我们称之为utilities.hutilities.c 在其中,我有一个重要的数组,我们称之为

#define IMPORTANT_ARRAY_LENGTH  10000
char important_array[IMPORTANT_ARRAY_LENGTH];

我在这个utilities模块中有很多其他功能,它们都运行良好。但是,在其他一个源文件中,我们称之为worker.c,我必须使用此数组。什么是“官方”,优雅的方式,而不必将extern char important_array[IMPORTANT_ARRAY_LENGTH]和宏定义放在worker.c

如果我执行以下操作:

utilities.h

#ifndef _UTILITIES_H_
#define _UTILITIES_H_

#define IMPORTANT_ARRAY_LENGTH  10000
extern char important_array[IMPORTANT_ARRAY_LENGTH];

// ...

utilities.c

#ifndef _UTILITIES_C_
#define _UTILITIES_C_

#include "utilities.h"

char important_array[IMPORTANT_ARRAY_LENGTH];

// ...

worker.c

#include "utilities.h"
// ...
important_array[0] = 0;

然后我的数组将是worker.c中未定义的符号。如果我在extern中没有使用utilities.h关键字,那么当然,它是一个重复的符号。 (奇怪的是,它仅用警告编译,我可以从链接器文件中看到大小被多次分配。)

我真的必须在worker.c声明我的数组吗?我想保持一切干净,并且只在一个地方包含所有声明:在头文件中。我想只有一次宏定义(这是次要的,因为我可以使用const,但我希望预处理器能够处理它,而不是占用它)

4 个答案:

答案 0 :(得分:4)

你所拥有的是规范的方法:在头文件中有一个extern声明,并在.c文件中定义变量。

  

我的数组将是worker.c中未定义的符号

不,它不会。您的代码将编译并链接得很好。

答案 1 :(得分:2)

在每个翻译单元中都有一个声明(extern...),只有一个定义是最优雅的方法。

所以请将extern char important_array保留在标题中,将char important_array保留在其中一个.c文件中。

答案 2 :(得分:2)

我经常把这个定义放在标题中(我知道这是不赞成的)。 它使定义和声明保持紧密,这是一件好事。

/* file.c */
#define FILE_C 1
#include "file.h"

/* file.h */
#ifndef FILE_H
#define FILE_H 1

#define BIG_SIZE 13

#if FILE_C 
char the_array[BIG_SIZE];
#else
extern char the_array[BIG_SIZE];
#endif

#endif /* FlLE_H */

 /* other_file.c */
#include "file.h"

没有做错的风险:如果你做错了,链接器会抱怨。

BTW以类似的方式基本上做同样的事情,但可能更具可读性,是:

/* file.h */
#ifndef FILE_H
#define FILE_H 1

#if FILE_C
#define EXTERN /**/
#else
#define EXTERN extern
#endif

#define BIG_SIZE 13

EXTERN char the_array[BIG_SIZE];

...

#undef EXTERN
#endif /* FlLE_H */

答案 3 :(得分:1)

在utilities.c上创建一个名为“get_important_array”的新函数,它只返回一个指向数组的指针并将原型放在utilities.h中。之后,当您将utilities.h放在worker.c时,您将以简单有序的方式访问important_array。