Почему это не компилируется? Я получаю:Ошибка «Неверный инициализатор»
[Error] invalid initializer
#include <stdio.h>
int main()
{
int i = 2;
char s[100] = (i == 2)? "botton":"bottle";
printf ("%c", s[0]);
return 0;
}
Почему это не компилируется? Я получаю:Ошибка «Неверный инициализатор»
[Error] invalid initializer
#include <stdio.h>
int main()
{
int i = 2;
char s[100] = (i == 2)? "botton":"bottle";
printf ("%c", s[0]);
return 0;
}
Компиляция с -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
с этим инициализаторе, потому что это не является постоянной во время компиляции.
Инициализаторы для массива должны быть постоянным списком инициализаторов. s
является char
-array requires строковым литералом или константным инициализатором массива.
gcc имеет расширение, позволяющее инициализировать автоматические переменные с помощью не константных выражений, поэтому оно может работать для gcc. Другие компиляторы (например, clang) могли бы (!) Также разрешить это. В любом случае вам нужно иметь расширения.
Это верно для всех версий ISO-C (ссылки для C11).
Вы can, однако char *s
(const char *
если использовать только струнные-литералы). Это позволяет использовать нормальное выражение, в том числе непостоянное.
Должна ли эта работа тогда «char s [] = ((2 == 2)?» Botton »:« bottle »);' ?? – Haris
@haris: Я так думаю (не могу проверить прямо сейчас). C11, по-видимому, разрешает переменные инициализаторы для 'auto'. – Olaf
Инициализатор для массива не может быть произвольным выражением, постоянным или нет. Это должен быть список инициализаторов или строковый литерал (для массива символов). C11 не меняет этого. – interjay
Вопросы, требующие помощи по отладке («почему этот код не работает?») Должны включать в себя желаемое поведение, конкретную проблему или ошибку и кратчайший код, необходимый для воспроизведения в самом вопросе. Вопросы без четкого описания проблемы не полезны другим читателям. См.: Как создать минимальный, полный и проверенный пример. – Olaf
В соответствии с [стандартом C 2011] (http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf), раздел 6.7.9, может быть инициализирован массив 'char' с строковым литералом или скопированным списком инициализаторов. Условное выражение не является ни одной из этих вещей. –