通过宏进行C数组初始化

时间:2009-10-29 12:01:29

标签: c arrays macros

问题的背景:
void dash(int *n, char c)用于绘制以“+”分隔的字符c 参数n是一个整数数组,例如{1,3}和{ - 1}的“ - ”应该给出“+ - + --- + - +”,这很好。 要使用短划线我会c,这使得构造副本和可接受。

问题本身:
为了避免复制和粘贴,我想做{int f={1, 3, 2}; dash(f, '-');}, 导致可用的#define F(X, Y) {int f=X; dash(f, Y);}。{ 不幸的是,编译器抱怨F得到4(数组的长度+ 1)参数而不是2.

那么如何将F({1, 3, 2}, '-')作为参数提供给宏?

4 个答案:

答案 0 :(得分:4)

Variadic宏是C99的一个特性。

#define F(Y,...) dash((int[]){__VA_ARGS__},Y)
  

那你怎么能给{1,3,2}   参数到宏?

F('-',1,3,2);

答案 1 :(得分:4)

这是我的版本:

#include <stdio.h> 

void dash(int len, int *n, char c){
  int i;
  printf("dash( %i, {", len );
  for( i=0; i<len-1; i++ )
    printf(" %i,", n[i] );
  printf(" %i }, '%c')\n", n[i], c );
}

#define NOPAREN(...) __VA_ARGS__ 
#define F1(arr,char)  { int f[]={NOPAREN arr}; dash(sizeof(f)/sizeof(f[0]),f,char); } 

#define F2(char,...)  { int f[]=__VA_ARGS__;   dash(sizeof(f)/sizeof(f[0]),f,char); } 

int main(void){
  F1( (1,3,2), '-' );
  F2( '-', {4,6,5} );
}

结果:

dash( 3, { 1, 3, 2 }, '-')
dash( 3, { 4, 6, 5 }, '-')

答案 2 :(得分:1)

我没有尝试使用宏来设置和调用这些调用,我可能会考虑将接口更改为dash()以使用varargs:

#include <stdarg.h>

void dash( char c, ...)
{
    // ...
}


int main() {
    dash( '+', 1, 3, 2, -1);   // note: negative number indicates 
                               //   the end of the list of numbers
    return 0;
}

使用varargs并不是世界上最好的东西(它们很难使用并且不是类型安全的),但我认为它会比你试图产生的宏观混合物更好。

另外,请记住,即使您坚持使用dash()的当前界面并想出一个可以满足您需要的宏,您仍然需要一种方法来指示数字序列的结束。被传递到dash()。否则,破折号无法知道何时到达阵列的末尾。你有几个选择:

  • 使用标记值,例如0,-1或任何负数(如上面的vararg示例中所示)
  • 将数组中的元素数作为另一个参数传递
  • 将数组的大小设置为dash()接口的一部分。在您的示例中,dash()可能需要传入一个包含3个整数的数组。不多也不少(实际上会更好 - 它们就不会被使用)。如果你这样做,修复你的宏会容易得多,但我怀疑这不是你想要破坏行为的方式。

答案 3 :(得分:0)

如果将{ 1, 3, 2 }定义为另一个宏,则可以将{ 1, 3, 2 }作为参数传递给宏

#define PARAMS { 1, 3, 2 }
F(PARAMS, '-')
#undef PARAMS

不幸的是,似乎没有直接的方法按字面意思做你要求的,即以这种特定形式专门传递{ 1, 3, 2 }。可能值得切换到其他方法,包括其他答案中建议的C99特定方法。