用C语言定义数组
我有几个450个元素的字符数组(存储位图数据以显示在lcd屏幕上)。我想将它们放在头文件下并定义它们,但我不断收到编译错误。在C中如何执行此操作用C语言定义数组,c,arrays,header-files,c-preprocessor,C,Arrays,Header Files,C Preprocessor,我有几个450个元素的字符数组(存储位图数据以显示在lcd屏幕上)。我想将它们放在头文件下并定义它们,但我不断收到编译错误。在C中如何执行此操作 #定义数字[450]{0、1等} #定义数字{0、1等} #定义数字[450]然后设置数字 还有更多…嗯。。。您当然不需要使用define。只需将它们作为常量、静态数组添加到头中 /* prevents multiple, redundant includes */ /* make sure to use a symbol that is fairly
#定义数字[450]{0、1等}
#定义数字{0、1等}
#定义数字[450]
然后设置数字
还有更多…嗯。。。您当然不需要使用define。只需将它们作为常量、静态数组添加到头中
/* prevents multiple, redundant includes */
/* make sure to use a symbol that is fairly sure to be unique */
#ifndef TEST_H
#define TEST_H
/* your image data */
const char image[] = { 1, 2, 3, 4, ... };
#endif
另外,如果您需要有关编译错误的帮助,那么您应该发布代码。因为您正在LCD上显示,我假设这是一个嵌入式系统 不要将数据放入标题中
将数据放入普通C或C++文件中。编译这个。它可能只包含数据,这没关系,并且易于更新
然后使用头文件授予对数据的访问权限 例如,在images.c文件中:#include "images.h"
const byte numbers1[MAX_NUMBERS1] = { ... };
byte numbers2[MAX_NUMBERS2]; // will be initialsied to 0
那么,h是:
#ifndef _IMAGES_H_
#define _IMAGES_H_
typedef unsigned char byte;
#define MAX_NUMBERS1 (450)
// different constants in case you change something
#define MAX_NUMBERS2 (450)
// even better if you can do const static int MAX_NUMBERS1=450;
// but depends on the compiler
extern const byte numbers1[MAX_NUMBERS1] = { ... };
extern byte numbers2[MAX_NUMBERS2]; // will be initialised to 0
#endif
然后程序中的所有其他.c文件都可以访问它们
将变量的定义放入头文件(几乎)总是一个坏主意
变量的声明,例如。
extern字节数2[MAX_numbers2]代码>
告诉C编译器在最终链接程序的其他地方有一个名为numbers2
的数组变量。如果链接器没有(从其他地方)获得该定义,那么它将引发一个错误,因为没有分配给变量的空间
变量的定义(注意不要外部),例如。
字节数2[MAX_numbers2]代码>
有效地告诉C编译器有一个名为numbers2
的数组变量,它应该在这里分配空间,从这个源文件生成的目标代码中分配空间,这将用于在最终的链接程序中保存变量的值
当C编译器看到一个声明(前面有extern
)时,它不会为numbers2
分配空间,而是在看到实际定义时分配空间(noextern
)
因此,如果将任何变量的实际定义放在头文件中,并将其包含在多个源代码文件(.c)中,c编译器将不止一次地为该变量分配空间。然后链接器将给出一个错误(通常是相同名称的多个定义)
还有一个更微妙的问题。如果在首次开发程序时,头文件仅包含一个源文件,则程序将正确编译和链接。然后,在以后的某个日期,如果第二个源文件包含头(可能有人刚刚将原始源代码文件拆分为两个文件),链接器将引发“多个定义”错误。这可能会让人非常困惑,因为程序用于编译和链接,显然没有任何更改
摘要
切勿通过在头文件中放置定义来为变量分配空间。仅将变量声明放入头文件中 我也有类似的问题。在我的例子中,我需要一个常量数组,以便用作其他静态数组的大小。当我试图使用
const int my_const_array[size] = {1, 2, 3, ... };
然后宣布:
int my_static_array[my_const_array[0]];
我从编译器中得到一个错误:
array bound is not an integer constant
所以,最后我做了以下几点(也许有更优雅的方法):
为什么不发布到目前为止的代码以及出现的编译器错误?你不能定义类似的东西。想想看;每次使用它都会声明一个新数组。当然,这将导致多重重新定义。宏只是文本替换。自己替换文本,看看它是否有意义。是的,但是当标题被多次调用(程序的多个部分需要它)时,我会出错。然后你使用一个,然后再次显示示例。我不知道“调用标题”是什么意思,但我想你的意思是包含。所以,就像我说的。。。例子。我们不是通灵者,你知道。:)谢谢我将尝试我没有想到的#ifndef
。是不是不将其包含在头文件中的原因,因为它是嵌入式系统,会占用更多磁盘空间?@Abdul-我希望这更清楚。如果是嵌入式系统,则可能没有磁盘。没有磁盘的嵌入式系统中存储的可执行二进制文件在哪里?@Abdul-对于大多数微控制器(如ATmega、Arm Cortex-M)或外部闪存芯片,可执行文件通常存储在片内闪存中。PC的初始引导加载过程存储在主板上的Quad SPI Flash()中,当该过程在通电或复位时运行,它将开始从磁盘加载操作系统。@Abdul-最小化程序大小是为了确保其仅为一个数据实例。在标题中定义数据可能会导致链接程序时失败,也可能会浪费空间。如果链接器找到多个同名数据实例,并且没有足够的信息丢弃除一个以外的所有实例,则链接器将失败。或者创建多个数据实例。这是由于在头文件中将数据定义为“静态”的情况下,将头文件包含到多个源代码(.c)文件中链接器将它们构建到可执行程序中,从而浪费空间(在磁盘和内存中)。
#define element(n,d) ==(n) ? d :
#define my_const_array(i) (i) element(0,1) (i) element(1,2) (i) element(2,5) 0