我必须在使用C ++一段时间后回到(嵌入)C,并遇到以下问题:
我有一个包含很多次的源模块,我们称之为utilities.h
和utilities.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,但我希望预处理器能够处理它,而不是占用它)
答案 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。