我希望用户使用宏为变量赋值。
#define CountA 3
#define A0 0x01
#define A1 0x02
#define A2 0x03
CountA定义因应用程序而异,A0,A1,...,An也因应用程序而异。 I,E。那不是我自己的代码。它是使用我的核心的用户代码的一部分。
#define MakeDefinitionA(n) A##(n)
unsigned char n;
unsigned char data[CountA];
unsigned char cnt;
cnt = 0;
for (n = 0; n < (unsigned char)CountA; n++) {
data[cnt++] = MakeDefinitionA(n);
}
最后,我想从这样的用户代码中获取数据值。
我该怎么办?我应该修改那些代码?
答案 0 :(得分:0)
像这样使用#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#define DECL(z, n, text) BOOST_PP_CAT(text, n),
#define CountA 3
#define A0 0x01
#define A1 0x02
#define A2 0x03
int main() {
unsigned char n;
unsigned char data[CountA] = { BOOST_PP_REPEAT_FROM_TO(0, CountA, DECL, A) };
unsigned char cnt = CountA;
}
int main() {
unsigned char n;
unsigned char data[3] = { 0x01, 0x02, 0x03, };
unsigned char cnt = 3;
}
扩展到
raise
答案 1 :(得分:0)
没有必要使用宏。只需使用枚举和表格:
typedef enum
{
A0 = 0x01,
A1 = 0x02,
A2 = 0x03,
} A_t;
const A_t LIST [] =
{
A0,
A1,
A2
};
#define CountA ( sizeof(LIST)/sizeof(*LIST) )
int main( void )
{
unsigned char data[CountA];
unsigned char cnt;
for (size_t i = 0; i < CountA; i++) {
data[i] = LIST[i];
}
cnt = CountA;
return 0;
}
答案 2 :(得分:0)
@ Lundin建议使用枚举功能可以提高效率,但是我发现一旦列表超出半页左右,这种方法很难维护。这就是我采用这种方法的原因:
#define TAG_MAP { \
_MAP(TAG_BODY,"body"), \
_MAP(TAG_HEAD,"head"), \
_MAP(TAG_HTML,"html"), \
_MAP(TAG_UNKNOWN,"unknown"), \
}
#define _MAP(x,y) x
enum tags TAG_MAP;
#undef _MAP
#define _MAP(x,y) y
const char *tagstrings[] = TAG_MAP;
#undef _MAP
//usage: printf("%s\n",tagstrings[TAG_HTML]);
此方法可用于直接初始化data[]
,这基本上是for(;;)
循环的宏版本的更有效版本(您无法取消引用该值用于粘贴宏的变量)
这可以扩展到任意类型的任意数量的元素,甚至多个参数(如果你把它们放在最后并使用,...
和__VA_ARGS__
)我会经常使用它来保存排序列表可以使用快速二进制搜索解析为枚举,然后将该值用于各种查找表。
对于仅使用宏并使用 VA_ARGS 的更复杂示例,请参阅my quixotic libc 所有依赖于体系结构的东西都在1行上定义,并且各种预处理器指令将每个第n个参数映射到适当的定义。 系统调用使用另一种hack来调用sycall0 ... syscall6,具体取决于传递的参数数量。