共享 C 数组的最优雅的方式

发布于 2025-01-07 19:51:35 字数 1239 浏览 1 评论 0原文

在使用 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.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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

哽咽笑 2025-01-14 19:51:35

您所拥有的是执行此操作的规范方法:在头文件中包含 extern 声明,并在 .c 文件中定义变量。

我的数组将是worker.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.

my array will be an undefined symbol in worker.c

No, it won't. Your code will compile and link just fine.

壹場煙雨 2025-01-14 19:51:35

我经常将定义放在标题中(我知道这是不受欢迎的)。
它将定义和声明紧密结合在一起,这是一件好事。

/* 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"

不存在做错的风险:如果你做错了,链接器会抱怨。

顺便说一句,类似的方法基本上做同样的事情,但可能更具可读性,是:

/* 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 */

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.

/* 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"

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:

/* 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 */
恬淡成诗 2025-01-14 19:51:35

在每个翻译单元中拥有一个声明 (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 and char important_array in one of the .c files.

司马昭之心 2025-01-14 19:51:35

在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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文