Буквальный инициализатор строки для массива символов
Вопрос
В следующих правилах по делу, когда массив распадается на указатель:
LVALUE [см. Вопрос 2.5] типа массива T, который появляется в распадах выражения (за тремя исключениями) в указатель на его первый элемент; Тип результирующего указателя является указатель-t.
(Исключениями являются, когда массив является операндом размера или оператора или является буквальным инициализатором строки для массива символов.)
Как понять случай, когда массив является «буквальной стрункой для массива символов»? Какой -то пример, пожалуйста.
Спасибо!
Решение
Три исключения, в которых массив не распадается в указатель, являются следующими:
Исключение 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's address */
int* p = a;
printf("%p", (void*)(&p)); /*prints the pointer's 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) */
}
Другие советы
Предположим заявления
char foo[] = "This is a test";
char *bar = "This is a test";
В обоих случаях тип струнного буквального »This is a test
"IS" 15-элементный массив ЧАР ". При большинстве случаев выражения массива неявно преобразуются из типа« n-элементный массив T »в« Указатель T », а выражение оценивается по адресу первого элемента массив. В объявлении для bar
, это именно то, что происходит.
В заявлении о foo
, однако, выражение используется для инициализации содержимого другого массива, и поэтому нет преобразован в тип указателя; Вместо этого содержимое из литературы струны скопированы в foo
.
Это буквальный инициализатор струны для массива символов:
char arr[] = "literal string initializer";
Также может быть:
char* str = "literal string initializer";
Определение из K & R2:
Строка буквала, также называемая строковой константой, представляет собой последовательность символов, окруженная двойными кавычками, как в «...». Строка имеет тип «массив символов» и класс хранения Static (см. Par.a.3 ниже) и инициализируется с помощью заданных символов. Являются ли идентичные строковые литералы различными, определяется реализацией, и поведение программы, которая пытается изменить строковую литературу, не определено.
Похоже, вы вытащили эту цитату из FAQ Comp.Lang.c (возможно, старая версия или, может быть, печатная версия; она не совсем соответствует текущему состоянию онлайн):
http://c-faq.com/aryptr/aryptrequiv.html
Соответствующий раздел ссылается на другие разделы FAQ, чтобы уточнить эти исключения. В вашем случае вы должны посмотреть на: