Буквальный инициализатор строки для массива символов

StackOverflow https://stackoverflow.com/questions/2036096

Вопрос

В следующих правилах по делу, когда массив распадается на указатель:

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, чтобы уточнить эти исключения. В вашем случае вы должны посмотреть на:

http://c-faq.com/decl/strlitinit.html

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top