5

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预处理器是否提供了实现此目的的方法?

4

3 回答 3

7

没有标准的 C 预处理器变量。正如Oli Charlesworth建议的那样,如果您只想使用标准 C 来保留X-Macros,那么使用X-Macros可能是您最好的选择。如果确实有很多关联数据会涉及多个文件,那么您将需要使用代码生成器,例如GNU 自动生成器

于 2013-01-25T18:21:02.240 回答
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()

将明文代码放入自己的文件中可以更轻松地以防您将来可能需要为您的对象定义进行多个定义,因为您只需将明文代码修改添加到一个文件中即可。

我知道这并不理想,但这是您能做的最好的事情,因为您无法使用宏参数以某种方式修改预处理器代码。

于 2019-06-24T08:39:43.700 回答
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;
}

不过,我不是在宣传这个;如果没有更好的解决方案,请务必仔细考虑。:)

于 2013-01-25T18:25:25.263 回答