2009-10-29 3 views
2

Исходный вопрос:
void dash(int *n, char c) - это рисование символов c, разделенных символом «+».
Параметр n представляет собой массив из целых чисел, например. {1, 3, 2} и '-' для c должны давать «+ - + --- + - +», который отлично работает. Чтобы использовать тире, я делаю {int f={1, 3, 2}; dash(f, '-');}, что делает конструкцию copy & пассивной.

Сам вопрос:
Чтобы избежать Копируйте & склеивание Я хотел сделать #define F(X, Y) {int f=X; dash(f, Y);}, в результате красиво использовать F({1, 3, 2}, '-').
К сожалению, компилятор жалуется на аргументы F получения 4 (длина массива + 1) вместо 2.

Итак, как вы можете дать {1, 3, 2} в качестве параметра для макроса?Инициализация массива C с помощью макроса

+1

Непонятно, как 'dash' определяет количество элементов в массиве. Всегда ли 3? –

+0

Я реализовал его, чтобы остановиться на последнем Элементе, который должен быть 0. Но это не важно для самого вопроса, поэтому я оставил его здесь. –

ответ

4

Матрицы Variadic являются особенностью C99.

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

Итак, как вы можете дать {1, 3, 2} в качестве параметра в макросе?

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

Я думаю, что это должно быть #define F (Y, ...) dash ((int []) {__ VA_ARGS__}, Y} Обратите внимание на (int []) литье и пропущенную точку с запятой. – quinmars

+0

хорошие точки, исправлены – Will

+0

thx, теперь я могу дать вам +1 – quinmars

0

Попробуйте F(({1, 3, 2}), '-')

+0

Это не распространяется на правильные буквы C. –

1

Вместо того, чтобы пытаться использовать макрос, чтобы настроить и сделать эти звонки, я бы, вероятно, рассмотреть возможность изменения интерфейс dash() использовать: с переменным числом аргументов

#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(). В противном случае нет возможности узнать, когда он достиг конца массива. У вас есть несколько вариантов:

  • использует значение Sentinel, такие как 0, -1, или любое отрицательное число (как в примере выше) vararg
  • передать количество элементов в массиве в качестве еще одного аргумента
  • Установите размер массива как часть интерфейса dash(). В вашем примере dash() может потребовать передачи массива из 3-х типов. Не более, не менее (на самом деле все будет в порядке - они просто не будут использоваться). Если бы вы это сделали, исправление вашего макроса было бы намного проще, но я подозреваю, что не так, как вы хотите, чтобы тире себя вел.
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 }, '-') 
0

Вы можете передать { 1, 3, 2 } в качестве аргумента макроса, если вы определяете { 1, 3, 2 } как другой макрос

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

К сожалению, похоже, нет ди прямой способ сделать буквально то, что вы просите, то есть передать конкретно { 1, 3, 2 } в этой конкретной форме. Возможно, стоит переключиться на альтернативные методы, в том числе на C99-конкретные, предложенные в других ответах.

Смежные вопросы