以下代码段:
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数组的数据,但有几个C预处理器中的其他const数组依赖于它们比(比方说)为每个源数组的每个元素定义预处理器宏更清晰吗?
P.S。如果有一些预处理器库可以做这样的事情,我真的很感激代码示例。
答案 0 :(得分: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 };
答案 1 :(得分: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
和ARR_BEGINX
宏提供的额外步骤,预处理器有时会将FOO
视为单个参数。