如何在头文件中定义一个字符串字符数组?

29

我有许多不同的三轴传感器,正在为它们编写测试代码。在每个传感器的 C 文件中,我都定义了相同的 char 字符串:

char axis[3][8] = {"X", "Y", "Z"}

当我使用“for”循环结果来打印失败的轴时,我会使用以下代码:

DEVICETEST_LOG("%s Failed %s axis for Min range\n",device_name[DUT], axis[i]);

我在考虑为了节省空间,能否在头文件中定义一个字符串数组以在整个代码中使用。

我尝试了很多方法,但是似乎无法定义一个字符串数组,在头文件中遍历该数组并通过编译。

5个回答

42

如果必须将其放在头文件中,请使用 externstatic

// option 1
// .h
extern char axis[3][8];

// .c
char axis[3][8] = { "X", "Y", "Z" };

// option 2
// .h
static char axis[3][8] = { "X", "Y", "Z" };

Extern告诉连接器,有一个名为axis的全局变量在我们的某个实现文件中定义(即在一个.c文件中),我需要在这里引用它。

static则相反,告诉编译器:我需要看到并使用这个变量,但不要将其导出到连接器,因此无法被extern引用或引起命名冲突。


1
请注意,当使用 static 并编译时加上 -Wunused 选项时,如果您在该编译单元中未使用该数组,则会收到有关此的警告。 - Victor

27
为了避免链接错误,你需要在头文件中将数组声明为extern,然后在代码模块之一中定义该数组一次
例如:
//myheader.h
extern const char* axis[3];

然后在另一个代码模块中:

//myfile.c
const char* axis[3] = { "X", "Y", "Z" };

1
啊,这很有道理,但似乎有些反常... 因此,我在所有地方包含的头文件将所有其他 C 文件指向“myfile.c”的本地定义。 - user1054210
即使我已经在其他c文件中包含了头文件,但我仍然遇到了编译错误“未定义的引用”。因此,在myheader.h中,我有>>extern char* AXIS [3] [8];而在myfile.c中,我有>>char* AXIS [3] [8] = {{"X"}, {"Y"}, {"Z"}};并且我在otherfile.c中包含了myheader.h。我还尝试了一些其他技巧,但它们没有同步。 - user1054210
如果还有其他问题,那么就是其他的问题了...如果你把宏从方程式中拿出来,只是尝试在另一个包含头文件的代码模块中访问数组,会发生什么?其次,应该只是 const char* AXIS[3] = { "X", "Y", "Z" };,因为这些都是字符串字面量...你从哪里得到的 8 - Jason
我把8放在那里是因为否则会出现编译错误。编译器声称“错误:格式'%s'期望'char *'但参数5的类型为'int'”,基本上在print语句中声明axis [i]分配给%s是错误的,因为它是int,即使它定义为char。 - user1054210
顺便说一下...嗯,我真是太蠢了...为什么要把它放在头文件中呢?只需在高级测试文件中创建一个全局变量,调用所有低级文件时在低级文件中进行外部定义即可。当我考虑这个问题时,我还没有喝足够的咖啡。 - user1054210

7

将以下内容添加到您的页头:

extern char *axis[];

将以下内容添加到项目中的一个源文件中:

char *axis[] = { "X", "Y", "Z", "Time", "Space", "The Scary Door" };

干得好!当我需要创建一个具有不确定数量元素的菜单时,我会使用它。这很完美,因为在编译时编译器会准确地设置数组长度,此外代码似乎更易读。 - b3h3m0th

3

将此放入您的头文件中

extern char axis[3][8];

并将此内容保存在C文件中:

char axis[3][8] = {"X", "Y", "Z"};

0

Michael Barr(Netrino)建议不要在头文件中声明存储。同样,Netrino嵌入式系统编码标准不赞成在头文件中使用extern存储。

我基本上同意这些原则,并发现将存储外部化到需要它的C文件中是一个好主意,仅限于那些文件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接