从其他常量数组初始化常量数组

4
以下代码片段:

如下所示:

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文件,但现在我很好奇——是否有一种方法可以在C预处理器中做到这样的事情(仅输入const数组的数据一次,但让其他多个const数组依赖于它们),而不是像定义每个源数组的每个元素的预处理器宏那样繁琐?
附言:如果有一些预处理器库可以做到这样的事情,我真的很感激提供代码示例。
2个回答

2

看起来你的原始数组实际上是一组特殊常量,而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 };

是这样的,但最终会有大量类似的,所以我想找一种比为每个都编写预处理器宏更简洁的方法。但如果没有的话,我可能最终会采用这种方法。 - Stan Liou
度量标准的大量数据是如何生成的?也许应该以#define形式生成,而不是作为数组? - Josh B

1

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

#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_ELXARR_BEGINX宏提供的额外步骤,预处理器有时会将FOO视为单个参数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接