2012-12-21 4 views
1

Я хотел бы взять массив строк в макросе. Во-первых: это возможно?Массив строк в макросе

ЕСЛИ да, могу ли я называть их один за другим на основе индекса, когда я их использую?

Что-то вроде этого:

#define VAR "abc", "def", "xyz" 

Затем, когда я хочу использовать «Защиту» где-то,

FUNC(VAR[1]); 
+1

Можете ли вы привести пример того, как вы хотите использовать макрос? Может быть, фрагмент кода? –

+0

Я отредактировал главный вопрос. Мне хотелось бы что-то вроде этого? Возможно ли, если нет, то какое будет ближайшее решение? Спасибо – Sunny

ответ

1
#define VAR(...) const char *FOO[] = { __VA_ARGS__ } 
... 
VAR("abc", "xyz"); 
printf("%s\n", FOO[0]); 

Но обратите внимание:

  1. Макросы являются злом.
  2. Объявить переменную в макросе является наихудшей идеей.
+1

Я подписываюсь на второй пункт :) Но было бы очень важно объявить переменную как 'char const * []' как минимум. И тогда, когда вы это делаете, да, это зло, никогда не следует так поступать. Укажите имя переменной в качестве аргумента. –

+0

@JensGustedt, спасибо, я изменил на 'const char *'. Не знаю, как быть с именем, OP хочет только макрос, который получает строки в качестве параметров. Думаю, может быть недоразумение. – maverik

0

Макрос будет расширяться с текстом на право так попытайтесь ответить на ваш вопрос для сам.

Вот способ, чтобы попытаться понять макро-s:

FUNC(VAR[1]); <=> FUNC("abc", "def", "xyz"[1]); 

Будет ли один на право делать то, что вы ожидаете? Нет? Поэтому вы не можете использовать его так. Однако вы можете использовать его для инициализации статического массива, а затем, например, обращаться к массиву по индексу.

EDIT: вот как я предлагаю вам использовать MACRO:

char* a[] = {VAR}; 
FUNC(a[0]); 
+0

спасибо за объяснение. Не могли бы вы также предоставить exp для решения, которое вы упомянули. Спасибо – Sunny

+1

На самом деле один справа является совершенно законным синтаксисом C++, насколько я могу судить - он просто не делает то, что хочет Солнечный. – sepp2k

+0

@ sepp2k зависит от аргументов, которые принимает FUNC, но я думаю, что он ожидает одну строку, поэтому, вероятно, этот код не сможет скомпилироваться. –

2

Может быть мой код полезным для Вас:

#include<stdio.h> 
#include<stdlib.h> 
#define STRING_ARRAY "ONE", "TWO", "THREE", "NULL" 

int main(){ 

    char* STRING[] = {STRING_ARRAY}; 

    int i=0; 
    scanf("%d",&i); 
    printf("%s\n",STRING[i]); 
    return EXIT_SUCCESS; 
} 

Это также работает:

:~$ gcc x.c -o x 
:~$ ./x 
1 
TWO 
e:~$ ./x 
2 
THREE 

Вы должны изменить в MACRO только при повторной компиляции.

+0

** Тернарный оператор **. Когда злоупотребления макросами просто недостаточно. – LihO

+0

@LihO: Как насчет второго пути? –

+0

Гораздо лучше. Но дело в том, что единственной целью этого макроса в этом случае является замена строки 'char * STRING [] = {STRING_ARRAY};' с символом 'char * STRING [] = {" ONE "," TWO "," THREE " , "NULL"}; 'перед компиляцией этого исходного файла, что делает этот макрос немного бесполезным. – LihO

0

Начиная с C99 вы можете использовать составные литералы

#define VAR ((char const*[]){ "abc", "def", "xyz" }) 

, а затем использовать это как VAR[2] или так.

Составной литерал похож на листинг инициализатора, здесь это массив базового типа char const*. const важен для того, чтобы вы случайно не пытались изменить строковые литералы.

Любой современный компилятор должен иметь возможность сворачивать все различные вхождения этого массива и литералов строк в один экземпляр.

+0

Я использую это в цикле, и он не работает: VAR [i]; ? – Sunny

+0

@ Сонный, «не работает»? Не могли бы вы быть более конкретными? –

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