Это разрешено в C? - PullRequest
       6

Это разрешено в C?

0 голосов
/ 06 ноября 2011

Я написал следующую строку на C. Я хочу знать, поддерживается ли язык. это выглядит так:

char * mode[7] = Config_Msg.DHCP ? "DHCP" : "Static";

В основном я хочу вставить в режим значение String "DHCP" или "STATIC", зависящее от значения в Config_Msg.DHCP.

Когда я компилирую в IAR, я получаю это предупреждение:

Warning[Pe520]: initialization with "{...}" expected for aggregate  

Что означает это предупреждение?

Ответы [ 5 ]

6 голосов
/ 06 ноября 2011

Предупреждение означает, что ответ на ваш вопрос - нет. То, что вы делаете, может быть сделано во время выполнения, но оно недопустимо в инициализаторе. Просто напишите:

char * mode;

mode = Config_Msg.DHCP ? "DHCP" : "Static";

При ближайшем рассмотрении это не источник вашего предупреждения. Вы неправильно объявили mode как массив из 7 указателей, поэтому компилятор ожидал инициализации формы:

char * mode[ 7 ] = { "one", "two", "three" };

(остальные четыре записи будут инициализированы всеми нулями).

3 голосов
/ 06 ноября 2011

Вы не можете назначать такие строки, поэтому вы должны сделать это так:

char mode[7];
strcpy(mode,Config_Msg.DHCP ? "DHCP" : "Static");

Обратите внимание, что я также исправил вашу декларацию для mode. Вы изначально объявили массив указателей.

В качестве альтернативы, вы также можете сделать это с указателем:

char *mode = Config_Msg.DHCP ? "DHCP" : "Static";
1 голос
/ 06 ноября 2011

Мистический ответ верен, но если вы хотите узнать причину , ваш код не может работать, он немного сложнее. Вы можете использовать строковый литерал в качестве инициализатора для массива char, но, как и для всех объектов массива, строковые литералы в выражении (например, выражение ?:, которое вы используете), кроме как операнд & или sizeof операторы, распадающиеся на указатели. Результатом вашего выражения ?: является указатель, а указатели не являются допустимыми инициализаторами для массивов.

0 голосов
/ 06 ноября 2011

Для начала char * mode[7] должно быть char mode[7] в вашем примере;вам нужен массив char s, а не массив char указателей .

На ваш вопрос, нет, вы не можете этого сделать.У вас есть два варианта:

  1. Объявить mode как char *mode и сделать его точкой до "DHCP" или "Static"
  2. Сохранить modeв виде массива char и скопируйте "DHCP" или "Static" в него.

Обратите внимание, что при первом способе ваши строки будут доступны только для чтения (т.е.хранится в сегменте .rodata), в отличие от второго способа, когда они будут скопированы в ваш массив и могут быть изменены.Однако я не думаю, что это будет проблемой для этого примера.

0 голосов
/ 06 ноября 2011

Переменная char *mode[7] - это массив указателей на символы.

А то, что вы просите, не разрешено. Но вы могли бы код

char mode[20];

strncpy(mode, sizeof(mode), Config_Msg.DHCP ? "DHCP" : "Static");

отредактированное дополнение

На самом деле, как отмечали другие, strncpy опасно, когда предел достигнут. Мой пример должен быть лучше

char mode[20];
memset (mode, 0, sizeof(mode));
strncpy (mode, sizeof(mode)-1, Config_Msg.DHCP ? "DHCP" : "Static");

Таким образом, последний байт mode остается нулевым байтом. Если вы абсолютно уверены, что строка mode может быть только "DHCP" или "Static", вы должны указать это в комментарии, и вы можете объявить mode минимальной длины (7, то есть число буквы статические плюс 1) и используйте только strcpy. Но представьте, что через несколько месяцев у вас будет другой режим, например "automatic". Если вы не прокомментировали свой код, вы облажаетесь.

Даже понимание собственного кода за несколько месяцев может быть болезненным. Вот почему хорошие комментарии важны.

...