Инициализатор строковых строк для массива символов
В следующих правилах для случая, когда массив распадается на указатель:
Значение lvalue [см. вопрос 2.5] типа array-of-T, которое появляется в выражении, распадается (с тремя исключениями) на указатель на его первый элемент; тип результирующего указателя - указатель на Т.
(Исключения составляют, когда массив является операндом оператора sizeof и или, или является литерала для инициализатора строки для массива символов.)
Как понять случай, когда массив является "литеральным инициализатором строки для массива символов"? Например, пожалуйста.
Спасибо!
Ответы
Ответ 1
Три исключения, в которых массив не распадается на указатель, следующие:
Исключение 1.. Когда массив является операндом sizeof
.
int main()
{
int a[10];
printf("%zu", sizeof(a)); /* prints 10 * sizeof(int) */
int* p = a;
printf("%zu", sizeof(p)); /* prints sizeof(int*) */
}
Исключение 2.. Когда массив является операндом оператора &
.
int main()
{
int a[10];
printf("%p", (void*)(&a)); /* prints the array address */
int* p = a;
printf("%p", (void*)(&p)); /*prints the pointer address */
}
Исключение 3.. Когда массив инициализируется литеральной строкой.
int main()
{
char a[] = "Hello world"; /* the literal string is copied into a local array which is destroyed after that array goes out of scope */
char* p = "Hello world"; /* the literal string is copied in the read-only section of memory (any attempt to modify it is an undefined behavior) */
}
Ответ 2
Предположим, что объявления
char foo[] = "This is a test";
char *bar = "This is a test";
В обоих случаях тип строкового литерала "This is a test
" является "15-элементным массивом char". В большинстве случаев выражения массива неявно преобразуются из типа "N-element array of T" в "указатель на T", и выражение вычисляется по адресу первого элемента массива. В объявлении для bar
это именно то, что происходит.
В декларации для foo
, однако, выражение используется для инициализации содержимого другого массива и поэтому не преобразуется в тип указателя; вместо этого содержимое строкового литерала копируется в foo
.
Ответ 3
Это строковый инициализатор строки для массива символов:
char arr[] = "literal string initializer";
Также может быть:
char* str = "literal string initializer";
Определение из K & R2:
Строковый литерал, также называемый строкой константа, представляет собой последовательность символов окруженный двойными кавычками, как в "...". Строка имеет тип `` массив символы '' и класс хранения static (см. Par.A.3 ниже) и инициализируется с указанными символами. Будь то идентичные строковые литералы различны определяется реализацией, а поведение программы, которая пытается изменить строковый литерал undefined.
Ответ 4
Похоже, вы вытащили эту цитату из часто задаваемых вопросов comp.lang.c(может быть, старая версия или, может быть, печатная версия, она не совсем соответствует текущему состоянию онлайн):
http://c-faq.com/aryptr/aryptrequiv.html
Соответствующий раздел ссылается на другие разделы ЧаВо, чтобы уточнить эти исключения. В вашем случае вы должны посмотреть:
http://c-faq.com/decl/strlitinit.html