C: строковый литерал - вопрос - PullRequest
0 голосов
/ 22 марта 2011

Только в char *ptr = "Hello World" строковый литерал или оба "Hello World" строковые литералы?

#include <stdio.h>
#include <stdlib.h>

int main(void) {

    char array[] = { "Hello World" };
    char *ptr = "Hello World";

    printf( "%s\n", array );
    printf( "%s\n", ptr );

    printf( "%c\n", *array );
    printf( "%c\n", *ptr );

    printf( "%c\n", array[1] );
    printf( "%c\n", ptr[1] );

    return EXIT_SUCCESS;
}

# Hello World
# Hello World
# H
# H
# e
# e

Ответы [ 7 ]

5 голосов
/ 22 марта 2011

"Hello World" является строковым литералом - независимо от того, назначаете ли вы его char * или копируете его в char []

char * ptr = "Hello World"; действительно должно быть const char * ptr = "Hello World"; - строковые литералы могут быть неизменяемыми (в постоянной памяти), а использование const char * является дополнительной защитой от модификации.

char array[] = { "Hello World" }; безопасен - копирует строковый литерал из потенциальной памяти только для чтения в локальную переменную.

3 голосов
/ 22 марта 2011

"Hello world" всегда является строковым литералом, независимо от того, что вы с ним делаете.

char *ptr = "Hello World"; определяет указатель, который указывает на пространство, которое часто не модифицируется (поэтому вы должны обращаться с ним как const char * и ваш компилятор может на самом деле жаловаться, если вы этого не сделаете).

char array[] = { "Hello World" }; создает массив в стеке, поэтому он может быть изменен и примерно равен char array[sizeof("Hello World")]; strcpy(array, "Hello World");

2 голосов
/ 22 марта 2011

"Hello World" - строковый литерал.

В случае char *ptr = "Hello World"; ptr указывает на "Hello World", который присутствует в местоположении только для чтения. Любая попытка изменить его с помощью ptr вызовет неопределенное поведение.

Принимая во внимание, что в char array[] = { "Hello World" }; содержимое строкового литерала копируется в стек. Вам разрешено изменять этот контент без вызова UB.

Кстати, ISO C99 (раздел 6.4.5 / 6) говорит:

Не определено, различаются ли эти массивы при условии, что их элементы имеют соответствующие значения.

Это означает, что не определено, обрабатывает ли компилятор два (или более) вхождения "Hello World" различающихся.

1 голос
/ 22 марта 2011

Только сами "Hello World" являются строковыми литералами.

ptr - это указатель на char, инициализированный адресом первого элемента строкового литерала.

array - это массив, а не литерал.

0 голосов
/ 22 марта 2011

Когда вы объявляете массив символов [], вы объявляете массив символов (который доступен как для чтения, так и для записи), и этот массив инициализируется некоторой последовательностью символов

Если вы объявляете char *ptr, вы объявляете указатель, который указывает непосредственно на некоторый константный литерал (не копию), и вы можете просто прочитать его

0 голосов
/ 22 марта 2011

Это скомпилировано в строковый литерал в разделе только для чтения.

        .section        .rodata
.LC0:
        .string "Hello World"

Оба экземпляра объединены в один массив ... по крайней мере, на моей машине с gcc.

0 голосов
/ 22 марта 2011

"Hello World" - строковый литерал, независимо от того, где в коде он появляется. Ни ptr, ни array не являются строковыми литералами.

...