3

如下代码片段:

static const double foo[3] = { 1.0, 2.0, 3.0 };
static const double bar[3] = { foo[0]*foo[0], 3*foo[1], foo[2]+4.0 };

生成一个编译器错误,指出初始化值不是常量。

有一些数据数组(可以假定为固定大小)和其他一些数据数组,它们以相当简单的方式依赖和相关,这对于在编译时而不是运行时进行预计算很有用。但由于可能需要更改源数据,我希望此类更改避免手动重新计算依赖数组。

我想可以制作一些生成 .h 文件的实用程序,但此时我很好奇 - 有没有办法做这样的事情(只输入一次 const 数组的数据,但有几个其他 const 数组依赖于它们)在C预处理器中比(比如说)为每个源数组的每个元素定义一个预处理器宏更干净?

PS如果有一些预处理器库可以做这样的事情,我真的很感激一个代码示例。

4

2 回答 2

1

听起来您的原始数组实际上是特殊常量的列表,并且foo只是它们的集合。

您可以使用定义和构造数组以供以后在程序中使用来实现类似的功能:

#define SpecialA 1.0
#define SpecialB 2.0
#define SpecialC 3.0

static const double foo[3] = { SpecialA, SpecialB, SpecialC };
static const double bar[3] = { SpecialA*SpecialA, 3*SpecialB, SpecialC+4.0 };
于 2013-10-14T05:02:52.393 回答
0

在摆弄了一些预处理器之后,结果证明它比我想象的要容易。目标是只为源数组输入一次数据,同时避免单独定义每个条目。这可以通过将数组的内容定义为预处理器宏来实现:

#define FOO      1.0, 2.0, 3.0
static const double foo[] = { FOO };
static const double bar[] = { ARR_EL(0,FOO)*ARR_EL(0,FOO), \
                              3.0*ARR_EL(1,FOO), ARR_EL(2,FOO)+4.0 };
/* Whatever else */

其中辅助宏如下:

/* ARR_EL(n,...) returns nth element of the array */
#define ARR_EL(n,...)      ARR_EL0(ARR_BEGIN(n,__VA_ARGS__))
#define ARR_EL0(...)       ARR_ELX(__VA_ARGS__)
#define ARR_ELX(e0,...)    (e0)

/* ARR_BEGIN(n,...) returns subarray starting with nth element */
#define ARR_BEGIN(n,...)   ARR_BEGIN##n(__VA_ARGS__)
#define ARR_BEGIN0(...)    __VA_ARGS__ /* Why is this even here? */
#define ARR_BEGIN1(...)    ARR_BEGINX(__VA_ARGS__)
#define ARR_BEGINX(e0,...) __VA_ARGS__
#define ARR_BEGIN2(...)    ARR_BEGIN1(ARR_BEGIN1(__VA_ARGS__))
#define ARR_BEGIN3(...)    ARR_BEGIN2(ARR_BEGIN1(__VA_ARGS__))
#define ARR_BEGIN4(...)    ARR_BEGIN3(ARR_BEGIN1(__VA_ARGS__))
/* Extendible in the obvious way */

在 gcc (cpp 4.1.1) 和 tcc 中测试,但我相信这应该都是标准的 C99。

ARR_ELX如果没有andARR_BEGINX宏提供的额外步骤,预处理器有时会将FOO其视为单个参数。

于 2013-10-15T13:45:46.377 回答