C 中有预处理变量吗?它可以简化我的定义。
目前我有这样的事情:
typedef struct mystruct {
int val1;
int val2;
int val3;
int val4;
} MYSTRUCT;
typedef struct mysuperstruct {
MYSTRUCT *base;
int val;
} MYSUPERSTRUCT;
#define MY_OBJECT_BEGIN(name, val1, val2, val3, val4) \
MYSTRUCT name##Base = { val1, val2, val3, val4 }; \
MYSUPERSTRUCT * name##Objs = {
#define MY_OBJECT_VALUE(name, val) \
{ &(name##Base), val },
#define MY_OBJECT_END() \
NULL \
};
以这种方式使用:
MY_OBJECT_BEGIN(obj1, 1, 2, 3, 4)
MY_OBJECT_VALUE(obj1, 5)
MY_OBJECT_VALUE(obj1, 6)
MY_OBJECT_VALUE(obj1, 7)
MY_OBJECT_END()
产生类似这样的东西:
MYSTRUCT obj1Base = { 1, 2, 3, 4 };
MYSUPERSTRUCT * obj1Objs = {
{ &(obj1Base), 5 },
{ &(obj1Base), 6 },
{ &(obj1Base), 7 },
NULL
}
很明显,重复使用对象名称是多余的。我想将MY_OBJECT_BEGIN定义中的名称存储到某个预处理器变量中,以便我可以通过以下方式使用它:
MY_OBJECT_BEGIN(obj1, 1, 2, 3, 4)
MY_OBJECT_VALUE(5)
MY_OBJECT_VALUE(6)
MY_OBJECT_VALUE(7)
MY_OBJECT_END()
标准 C 预处理器是否提供了实现此目的的方法?
答案 0 :(得分:7)
没有标准的C预处理器变量。正如Oli Charlesworth建议的那样,使用X-Macros可能是你最好的选择,如果你想用标准C保持它。如果真的有很多相关数据会触及几个文件,你会想要使用像GNU autogen这样的代码生成器。
答案 1 :(得分:1)
在某处创建一个H文件,该文件将清除所有与宏相关的可能定义,例如:
#ifdef OBJECT
# undef OBJECT
#endif
然后在您的项目中的某个位置为该H文件进行定义:
#define CLEAR "whatever/path/you/want/clear.h"
让您的宏使用OBJECT:
#define MY_OBJECT_BEGIN(val1, val2, val3, val4) \
MYSTRUCT OBJECT##Base = { val1, val2, val3, val4 }; \
MYSUPERSTRUCT * OBJECT##Objs = {
#define MY_OBJECT_VALUE(val) \
{ &(OBJECT##Base), val },
#define MY_OBJECT_END() \
NULL \
};
像这样使用它:
#include CLEAR
#define OBJECT obj1
MY_OBJECT_BEGIN(1, 2, 3, 4)
MY_OBJECT_VALUE(5)
MY_OBJECT_VALUE(6)
MY_OBJECT_VALUE(7)
MY_OBJECT_END()
#include CLEAR
#define OBJECT obj2
MY_OBJECT_BEGIN(1, 2, 3, 4)
MY_OBJECT_VALUE(5)
MY_OBJECT_VALUE(6)
MY_OBJECT_VALUE(7)
MY_OBJECT_END()
将清除代码放入自己的文件中会更容易,以防将来您可能需要对对象定义使用多个定义,因为那时您只需要对一个文件添加清除代码修改即可。
我知道这并不理想,但这是您可以做的最好的事情,因为您无法使用宏参数以某种方式修改预处理程序代码。
答案 2 :(得分:0)
这是我能够在预处理器定义中重复使用变量的最接近的通用技术:
#include <stdio.h>
#define INIT_VALS(SIZE) unsigned int value[SIZE]; unsigned int i = 0;
#define DEFINE_VAL(NEW_VAL) value[i++] = NEW_VAL;
#define PRINT_VAL(INDEX) printf("%d\n", value[INDEX]);
int main()
{
INIT_VALS(3)
DEFINE_VAL(42)
DEFINE_VAL(70)
DEFINE_VAL(80)
PRINT_VAL(0)
PRINT_VAL(1)
PRINT_VAL(2)
// Output:
// 42
// 70
// 80
return 0;
}
但是,我不是在推广这个;一定要仔细考虑是否没有更好的解决方案。 :)