2015-09-09 2 views
-1

Почему это не компилируется? Я получаю:Ошибка «Неверный инициализатор»

[Error] invalid initializer

#include <stdio.h> 
int main() 
{ 
    int i = 2; 
    char s[100] = (i == 2)? "botton":"bottle"; 
    printf ("%c", s[0]); 
    return 0; 
} 
+3

Вопросы, требующие помощи по отладке («почему этот код не работает?») Должны включать в себя желаемое поведение, конкретную проблему или ошибку и кратчайший код, необходимый для воспроизведения в самом вопросе. Вопросы без четкого описания проблемы не полезны другим читателям. См.: Как создать минимальный, полный и проверенный пример. – Olaf

+1

В соответствии с [стандартом C 2011] (http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf), раздел 6.7.9, может быть инициализирован массив 'char' с строковым литералом или скопированным списком инициализаторов. Условное выражение не является ни одной из этих вещей. –

ответ

4

Компиляция с -Wall показывает ошибку:

$ gcc -Wall test.c 
test.c:5:10: error: array initializer must be an initializer list or string literal 
    char s[100] = (i == 2)? "botton":"bottle"; 
     ^
1 error generated. 

Однако, вы можете инициализировать strcpy():

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int main() 
{ 
    int i = 2; 
    char s[100] = {0}; 
    strcpy(s, (i == 2) ? "botton" : "bottle"); 
    printf("%c\n", s[0]); 
    return EXIT_SUCCESS; 
} 

Когда переменная s[] инициализирован, значение инициализации должно быть известно во время компиляции. Тест равенства (i == 2) возникает во время выполнения, поэтому он не может генерировать действительный инициализатор.

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

char *s = (i == 2) ? "botton" : "bottle"; 

Вы не можете, однако, использовать static char *s с этим инициализаторе, потому что это не является постоянной во время компиляции.

+1

Да, это правильно, но не должно 'char s [] = ((i == 2)?" Botton ":" bottle ");' work – Haris

+1

Все еще озадачен ... – Sam

+0

@haris, у которого есть тот же вопрос –

0

Инициализаторы для массива должны быть постоянным списком инициализаторов. s является char -array requires строковым литералом или константным инициализатором массива.

gcc имеет расширение, позволяющее инициализировать автоматические переменные с помощью не константных выражений, поэтому оно может работать для gcc. Другие компиляторы (например, clang) могли бы (!) Также разрешить это. В любом случае вам нужно иметь расширения.

Это верно для всех версий ISO-C (ссылки для C11).

Вы can, однако char *s (const char * если использовать только струнные-литералы). Это позволяет использовать нормальное выражение, в том числе непостоянное.

+0

Должна ли эта работа тогда «char s [] = ((2 == 2)?» Botton »:« bottle »);' ?? – Haris

+0

@haris: Я так думаю (не могу проверить прямо сейчас). C11, по-видимому, разрешает переменные инициализаторы для 'auto'. – Olaf

+0

Инициализатор для массива не может быть произвольным выражением, постоянным или нет. Это должен быть список инициализаторов или строковый литерал (для массива символов). C11 не меняет этого. – interjay

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