在C99宏中循环构造

时间:2013-05-14 12:34:39

标签: c macros c99

我想生成一个带有任意逻辑的数组初始化器,遗憾的是需要一些循环。

#define RANDOM_ARRAY(n) \
    ...

double array[] = RANDOM_ARRAY(10);

假设上面的代码为10个元素的数组生成初始值设定项。是否可以在C99中定义这样的宏(带循环)?

注意:如果函数调用就足够了(它必须能够在全局初始化器中调用它,而不是在第二个函数中),它不必是宏;

3 个答案:

答案 0 :(得分:3)

不幸的是,无法在C中创建递归(或循环)宏函数。但是,如果初始化程序的最大长度合理,则可以使用此类构造:

#define INITIALIZER(N)  { INITIALIZER_ ## N }
#define INITIALIZER_1   1
#define INITIALIZER_2   INITIALIZER_1, 2
#define INITIALIZER_3   INITIALIZER_2, 3


int
main(void)
{
    int tab[3] = INITIALIZER(3);

    return 0;
}

答案 1 :(得分:2)

C预处理器不支持循环,所以你想要的不是(容易)。

我添加了'(easy)',因为有些方法可以使用像boost's ITERATE之类的东西来获得类似循环的行为。这使用递归文件包含来模拟循环。但我不确定你是否想走那么远。

答案 2 :(得分:1)

由于您在C99中工作,您当然可以创建一个执行初始化的宏,但您将无法使其看起来像初始化程序:

#define INCREMENTING_ARRAY(t,a,n)    t a[n]; do {\
                                     for(size_t i = 0; i < n; ++i)\
                                       a[i] = i;\
                                     } while(0);

这会创建一个数组,其元素初始化为递增,例如。

用法:

int main(void)
{
  INCREMENTING_ARRAY(int, dozen, 12);
  int i;

  for(i = 0; i < sizeof dozen / sizeof *dozen; ++i)
    printf("array at %d = %d\n", i, dozen[i]);

  return 0;
}

这是有效的,因为在C99中你可以自由地混合声明和代码,所以宏用法之后的int i;就可以了。在C89中,它不会起作用。