共享 C 数组的最优雅的方式
在使用 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.hutilities.cworker.c
#ifndef _UTILITIES_H_
#define _UTILITIES_H_
#define IMPORTANT_ARRAY_LENGTH 10000
extern char important_array[IMPORTANT_ARRAY_LENGTH];
// ...
,
#ifndef _UTILITIES_C_
#define _UTILITIES_C_
#include "utilities.h"
char important_array[IMPORTANT_ARRAY_LENGTH];
// ...
。
#include "utilities.h"
// ...
important_array[0] = 0;
那么我的数组将是worker.c中的未定义符号 如果我不在 utilities.h
中使用 extern
关键字,那么它当然是一个重复的符号。 (奇怪的是,它编译时只显示一个警告,并且我可以从链接器文件中看到该大小被分配了多次。)
我真的必须在 worker.c
中声明我的数组吗?我想保持一切干净,并将所有声明仅放在一个位置:在头文件中。我只想宏定义一次(这是次要的,因为我可以使用 const,但我希望预处理器能够处理它,而不是占用空间)
I have to turn back to (embedded) C after some lengthy time with C++, and have the following problem:
I have a source module which is included a lot of times, let's call it utilities.h
and utilities.c
In it, I have an important array, let's call it
#define IMPORTANT_ARRAY_LENGTH 10000
char important_array[IMPORTANT_ARRAY_LENGTH];
I have a lot of other functions in this utilities
module, and they all work fine. However, in one of the other source files, let's call it worker.c
, I have to use this array. What is the "official", elegant way to do this, without having to put extern char important_array[IMPORTANT_ARRAY_LENGTH]
and the macro definition in the worker.c
?
If I do the following:
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;
then my array will be an undefined symbol in worker.c
. If I don't use the extern
keyword in utilities.h
, then of course, it's a duplicate symbol. (Strangely, it compiles with just a warning, and I can see from the linker file that the size is allocated multiple times.)
Do I really have to declare my array in worker.c
? I want to keep everything clean, and have all declarations in one place only: in a header file. And I want to have the macro definition only once (this is secondary, because I could use a const, but I want the preprocessor to handle it, and not take up place)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您所拥有的是执行此操作的规范方法:在头文件中包含
extern
声明,并在.c
文件中定义变量。不,不会。您的代码将很好地编译和链接。
What you have is the canonical way to do it: have an
extern
declaration in the header file, and define the variable in the.c
file.No, it won't. Your code will compile and link just fine.
我经常将定义放在标题中(我知道这是不受欢迎的)。
它将定义和声明紧密结合在一起,这是一件好事。
。
。
不存在做错的风险:如果你做错了,链接器会抱怨。
顺便说一句,类似的方法基本上做同样的事情,但可能更具可读性,是:
I often put the definition in the header (this is frowned upon, I know).
It keeps the definition and declaration close together, which is a Good Thing.
.
.
There is no risk of doing it wrong: the linker will complain if you do it wrong.
BTW a similar way to basically do the same, but maybe a bit more readable, is:
在每个翻译单元中拥有一个声明 (
extern...
) 和一个定义是实现此目的的最优雅的方法。因此,将
extern char important_array
保留在标头中,并将char important_array
保留在.c
文件之一中。Having one declaration (
extern...
) in each translation unit and exactly one definition is the most elegant way to do this.So leave the
extern char important_array
in the header andchar important_array
in one of the.c
files.在utilities.c 中创建一个名为“get_important_array”的新函数,该函数仅返回指向数组的指针并将原型放在utilities.h 中。之后,当您将utilities.h放在worker.c中时,您将以简单且有组织的方式访问 important_array 。
Create a new function at utilities.c called something like "get_important_array" that just returns a pointer to array and put the prototype at utilities.h. After that, when you put the utilities.h at worker.c you'll have important_array access in a simple, and organized way.