Фигурные скобки вокруг строкового литерала в объявлении массива char действительны? (например, char s [] = {"Hello World"})
случайно я обнаружил, что строка char s[] = {"Hello World"};
правильно скомпилирован и, похоже, обрабатывается так же, как char s[] = "Hello World";
. Не первый ({"Hello World"}
) массив, содержащий один элемент, который является массивом char, поэтому объявление для s должно читать char *s[]
? На самом деле, если я изменю его на char *s[] = {"Hello World"};
компилятор также принимает его, как и ожидалось.
поиск ответа, единственное место, которое я нашел, которое упомянуло это этот но нет со ссылкой на норматив.
Итак, мой вопрос, почему строку char s[] = {"Hello World"};
компилируется, хотя левая сторона типа array of char
и правая сторона имеет тип array of array of char
?
Ниже приведена рабочая программа:
#include<stdio.h>
int main() {
char s[] = {"Hello World"};
printf("%s", s); // Same output if line above is char s[] = "Hello World";
return 0;
}
Спасибо за любые разъяснения.
P. S. мой компилятор-это GCC-4.3.4.
6 ответов
это разрешено, потому что стандарт говорит так: C99 раздел 6.7.8, §14:
массив символьного типа может быть инициализирован символьным строковым литералом, необязательно заключенный в скобки. Последовательные символы символьного строкового литерала (включая завершающий нулевой символ, если есть номер или если массив неизвестного размера) инициализировать элементы массива.
это означает, что оба!--6-->
char s[] = { "Hello World" };
и
char s[] = "Hello World";
- это не более чем синтаксический сахар для
char s[] = { 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', 0 };
на связанной заметке (тот же раздел, §11), C также позволяет фигурные скобки вокруг скалярных инициализаторов, таких как
int foo = { 42 };
что, кстати, хорошо вписывается в синтаксис составных литералов
(int){ 42 }
фигурные скобки являются необязательными, и выражение эквивалентно просто массив char.
вы также можете написать это:
int a = {100}; //ok
в самом деле C++11
обобщает этот самый синтаксис, чтобы инициализировать не-массивы, а также массивы равномерно. Так C++11
, вы можете иметь эти:
int a{}; //a is initialized to zero, and it is NOT an array
int b[]{1,2,3,4}; //b is an array of size 4 containing elements 1,2,3,4
int c[10]{}; //all 10 elements are initialized to zero
int *d{}; //pointer initialized to nullptr
std::vector<int> v{1,2,3,4,5}; //vector is initialized uniformly as well.
Я могу ошибаться, но я думаю, что это не массив массивов символов, а блок содержит массив символов. int a = {1};
может также работать.
[...] На самом деле, если я изменю его на char * s [] = {"Hello World"}; компилятор принимает его также, как ожидалось
компилятор принимает его, потому что на самом деле вы делаете массив 2D элементов неопределенного размера,где вы сохранили только один элемент,"Hello World"
строку. Что-то вроде этого:--5-->
char* s[] = {"Hello world", "foo", "baa" ...};
вы не можете пропустить bracets
в этом случае.
это разрешено стандартом C++, а также, цитата:
массив узкого символьного типа ([basic.основополагающим]), массив, символьные типы char16_t, char32_t массив, или массив тип wchar_t может быть инициализирован узкий строковый литерал, строковый литерал строковые типы char16_t, char32_t строковый литерал, или широкий строковый литерал, соответственно, или соответствующим образом набранным строковым литералом заключенный в скобки ([Лекс.строка.)] [snip]