Инициализация массива без запятой


В следующем коде я получаю вывод типа (последний дает ошибку сегментации)

 U   
 s    
 HelloThisisatest    
 Segmentation fault (core dumped)

, но я не понимаю, почему. код -

int main()
{
   char *a[]={"Hello" "This" "is" "a" "test"};
   printf("%cn",a[1][0]);
   printf("%cn",a[0][8]);
   printf("%sn",a[0]);
   printf("%sn",a[3]);
   return 0;
}

Другой вопрос, Можем ли мы инициализировать 2-D массив без использования запятой? Другая ситуация, которую я получил, когда я заменяю ns на ts, то выходные данные изменяются, как

"U s HelloThisisatest (null)"

Почему?

3 3

3 ответа:

Это происходит потому, что в C две соседние строки объединяются в одну. Так "Привет" "мир" фактически одну строку "файл HelloWorld".

  • В вашем случае массив указателя фактически содержит одну единственную строку "HelloThisisatest". В первом printf вы получаете доступ к местоположению 1, которое является неопределенным поведением.

  • Следующий printf обращается к символу 8 строки, который является s .

  • Третий printf печатает всю строку, хранящуюся на местоположение 0, которое является "HelloThisisatest"

  • Последний printf пытается получить доступ к расположению массива 3, которое является неопределенным поведением, так как оно не инициализировано.

EDIT

См. пункт 6 раздела 5.1.1.2 стандарта C11/C99, в котором говорится:

Соседние строковые литеральные токены объединяются.

У вас есть массив указателей на char. Однако существует только один такой указатель, поэтому код типа:

a[1][0]

Перекрывает массив. Первый индекс всегда должен быть равен 0 для данного конкретного массива.

Вы можете сделать следующее:

char a[][20] = {"Hello", "This", "is", "a", "test"};

Обратите внимание, что второе измерение должно иметь размер (20)

Теперь вы можете напечатать все слова:

printf("%s\n",a[0]);
printf("%s\n",a[1]);
printf("%s\n",a[2]);
printf("%s\n",a[3]);
printf("%s\n",a[4]);