C / C ++ noob。我在头文件中定义了这个...
typedef unsigned char BitChar[9]; // 8 data bits and one width bit
extern BitChar BitFont[];
我在cpp文件中有这个...
BitChar BitFont[] = {
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,2, // 32 - Space
B10000000,B10000000,B10000000,B10000000,B10000000,B00000000,B10000000,B00000000,1, // 33 - !
...
B00000000,B00000000,B11100000,B11100000,B11100000,B00000000,B00000000,B00000000,3, // 127 - Unknown
};
它编译并且看起来运行得很好。但是,因为它永远不会改变,我认为它应该被标记为常数。我该如何标记?我所期待的,添加' const'会抛出编译错误,所以我很难过。这是错误...
error: invalid initialization of reference of type 'unsigned char (&)[9]' from expression of type 'const unsigned char [9]'
答案 0 :(得分:9)
只需添加const
即可。这个
extern const BitChar BitFont[];
...
const BitChar BitFont[] = {
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,2, // 32 - Space
B10000000,B10000000,B10000000,B10000000,B10000000,B00000000,B10000000,B00000000,1, // 33 - !
...
B00000000,B00000000,B11100000,B11100000,B11100000,B00000000,B00000000,B00000000,3, // 127 - Unknown
};
在C中应该可以正常工作。(假设您的编译器知道这些B00000000
标识符的含义。)
这在C ++中也可以完美地运行。 C ++版本中唯一的错误可能是基于C ++特定的const
属性。如果定义没有看到声明,那么你必须在定义中指定显式的extern
extern const BitChar BitFont[] = {
B00000000
...
因为在C ++中const
对象默认具有内部链接。但是,如果声明已包含extern
且定义可以看到声明,那么定义中的extern
是可选的。
您引用的错误消息表明您在代码中的某个位置尝试使用const限定的BitChar &
数组初始化类型为unsigned char (&)[9]
(aka BitChar
)的引用。这不起作用,因为它违反了const-correctness的基本规则。引用也必须符合const限定条件,即它必须更改为const BitChar &
(又名const unsigned char (&)[9]
)。
答案 1 :(得分:1)
请注意,CONST仍将消耗RAM空间。对于大型常量数组,您可能需要考虑将它们放入程序空间(也称为Flash或非易失性空间)。以下是一个例子。
const uint8_t BitFont[] PROGMEM = {
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,2, // 32 - Space
B10000000,B10000000,B10000000,B10000000,B10000000,B00000000,B10000000,B00000000,1, // 33 - !
B00000000,B00000000,B11100000,B11100000,B11100000,B00000000,B00000000,B00000000,3, // 127 - Unknown
};
#define BITFONT_X_SIZE (sizeof(BitFont)/sizeof(BitFont[0]))
void setup() {
Serial.println("");
Serial.print(F("BitFont[] = "));
for(int y = 0 ; y < BITFONT_X_SIZE ; y++) {
Serial.print(pgm_read_byte_near( &(BitFont[1]) ) );
Serial.print(F(","));
}
Serial.println("");
}
请注意,有三件事情发生了。首先,avr-gcc使用PROGMEM宏将其链接到程序空间。其次,pgm_read_byte_near函数用于从程序空间读取指针。因为它需要使用特殊的操作码来读取程序空间。
第三,与你的例子没有直接关系,但类似的是Serial.print()中使用的F()函数,它同样将常量字符串放入程序空间。否则,Serial.print中的字符串将使用静态ram。
或者你可以创建一个矩阵
#define BRICK_COLUMNS 9
const uint8_t BitFont[][BRICK_COLUMNS] PROGMEM = {
{B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,2}, // 32 - Space
{B10000000,B10000000,B10000000,B10000000,B10000000,B00000000,B10000000,B00000000,1}, // 33 - !
{B00000000,B00000000,B11100000,B11100000,B11100000,B00000000,B00000000,B00000000,3} // 127 - Unknown
};
#define BITFONT_X_SIZE (sizeof(BitFont)/sizeof(BitFont[0]))
void setup() {
Serial.println("");
for(int x = 0 ; x < BITFONT_X_SIZE ; x++) {
Serial.print(F("BitFont["));
Serial.print(x);
Serial.print(F("][y] = "));
for(int y = 0 ; y < BRICK_COLUMNS ; y++) {
Serial.print(pgm_read_byte_near ( &(BitFont[1]) ));
Serial.print(F(","));
}
Serial.println("");
}
Serial.println("");
}