我有2个定义,一个带字符串,另一个带数字。如何使用字符串和数字从定义中创建一个const数组。还有一些额外的常量应该在这个数组中。
如何编写此代码,使数组foobar中的0x22,0x41,0x42,0x42,0x21来自定义FOO和BAR?
#define FOO "AB"
#define BAR 33
extern int rs232_write(const unsigned char *data, unsigned char count);
const unsigned char foobar[] =
{
0x22,
FOO[0], /*what must i put here, this do not work*/
FOO[1],
0x42,
BAR,
};
int main(void)
{
rs232_write(foobar,sizeof(foobar));
return 1;
}
例如,在gcc中,我收到错误:
./001.c:9:5: error: initializer element is not constant
FOO[0], /*what must i put here*/
^
String的长度始终相同。 我也尝试了另一种方式:
#define FOO "AB"
#define BAR 33
extern int rs232_write(const unsigned char *data, unsigned char count);
const char foobar[] = \
"\x22" \
FOO \
"\x42" \
BAR /*what must i put here, this also not work*/
int main(void)
{
rs232_write(foobar,sizeof(foobar));
return 1;
}
这里我也遇到了错误,例如gcc prints:
./002.c:2:13: error: expected ‘,’ or ‘;’ before numeric constant
#define BAR 33
^
我在没有太多空间的微控制器上工作,所以我想避免在运行时创建数组,而我的编译器只支持C89。
答案 0 :(得分:1)
这应该有效:
#include<stdio.h>
#define FOO 'A','B'
#define BAR 33
const char foobar[] = {
0x22,
FOO,
0x42,
BAR,
'\0'
};
int main(void)
{
printf("%s\n", foobar);
return 0;
}
顺便说一句,以这种方式初始化阵列是非常糟糕的,也许你可以更好地解释你的目标。
答案 1 :(得分:1)
#include <stdio.h>
#include <stdlib.h>
#define FOO "ab"
#define BAR 33
#define STRINGIFY(x) STRINGIFY2(x)
#define STRINGIFY2(x) #x
const char foobar[] = "\x22" FOO "\x42" STRINGIFY(BAR);
int main(void)
{
printf("foobar = |%s| (%ld+1 characters)\n",
foobar, (long) sizeof(foobar) - 1);
return EXIT_SUCCESS;
}
运行此程序输出:
foobar = |"abB33| (6+1 characters)
答案 2 :(得分:1)
最简单,使用memcpy
:
#include <stdio.h>
#include <string.h>
#define FOO "AB"
#define BAR 33
extern int rs232_write(const unsigned char *data, unsigned char count);
unsigned char _foobar[] =
{
0x22,
0, 0,
0x42,
BAR,
};
const unsigned char *foobar;
int main(void)
{
foobar = (const unsigned char *)memcpy(_foobar + 1, FOO, 2) - 1;
rs232_write(foobar,sizeof(foobar));
return 0;
}
丑陋,使用X Macro和compound literal:
通过这种方式,您可以使用前两位数字:
const unsigned char foobar[] =
{
0x22,
'A', 'B',
0x42,
33,
};
或完整字符串"AB"
#include <stdio.h>
#define FOO X('A', 'B', '\0')
#define BAR 33
extern int rs232_write(const unsigned char *data, unsigned char count);
const unsigned char foobar[] =
{
0x22,
#define X(a, b, c) a, b
FOO,
#undef X
#define X(a, b, c) ((char []){a, b, c})
0x42,
BAR,
};
int main(void)
{
// rs232_write(foobar,sizeof(foobar));
printf("%s\n", FOO);
return 0;
}
输出:
AB
答案 3 :(得分:0)
问题是编译器在编译时不知道字符串文字"AB"
将放在内存中的位置。它的位置将在程序链接时或者可能在加载到内存时确定。
因此,使用它不会导致foobar
数组初始化所需的编译时常量。
在这种情况下,您真的别无选择,只能在运行时使用foobar[1]
和foobar[2]
设置。然而,即使在极小的嵌入式系统上,这也不会在内存或时间上产生太多开销。如果程序运行超过几秒钟,则很可能甚至无法测量。