Разница между char *str = … и char str[N] = …?

Возможный дубликат:
В чем разница между char s[] и char *s в C?
Вопрос об указателях и строках в C

Я читаю о строках в C и запутался. Я могу «объявить» строки двумя способами:

char *str = "This is string";
char str2[20] = "This is string"; 

В чем разница между двумя декларациями? Когда char str2[20] будет предпочтительнее char *str?


person rogi    schedule 25.08.2012    source источник
comment
c-faq.com/decl/strlitinit.html   -  person cnicutar    schedule 25.08.2012
comment
cs.bu.edu/teaching/cpp/string/array -vs-ptr   -  person amitchhajer    schedule 25.08.2012
comment
Прочитайте Разницу между char *str и char str[] и как они хранятся в памяти?   -  person Grijesh Chauhan    schedule 06.09.2013


Ответы (5)


char *str = "This is string";

Помещает строку в constant data section (also known as .rdata) программы. Эти данные нельзя изменить.

char str2[20] = "This is string";

В этом типе объявления данные предпочтительно находятся в stored in the stack area программы, если они объявлены внутри function scope, и в data section, если объявлены в global scope. Эти данные могут быть изменены.

Поэтому, если у вас есть необходимость изменить данные, используйте второй подход.

person perilbrain    schedule 25.08.2012
comment
Можете ли вы объяснить, где я сказал, что char *str = ".." — это распределение во время выполнения? Я думаю, что вы неправильно прочитали мой ответ (ошибочно или намеренно). - person Joe; 27.08.2012

В C строки представлены как последовательности char с символом NULL (он же 0, '\0'). Они хранятся в памяти, и вы работаете со способом ссылки на них. Вы определили два способа ссылки на него: char *, который является указателем на последовательность chars, и массив, который представляет собой непосредственную строку символов в качестве фактической переменной. Имейте в виду, что длина строки "abc" составляет 4 байта, поскольку в конце строки есть дополнительный символ NULL.

В дополнение к этому вы фактически назначаете строки в примере, который также включает строки, заданные во время компиляции.

Итак, два вопроса. Во-первых, о том, как вы представляете строки (char * против char[]), во-вторых, о строках времени компиляции.

Чтобы перейти к вашим примерам:

Первый создает в тексте программы константную строку и указатель на нее. В зависимости от компилятора он может храниться где угодно. Это эквивалент mallocing строки и хранения указателя на нее, за исключением того, что вы не должны изменять содержимое памяти. Это char *, поэтому вы можете изменить указатель так, чтобы он указывал куда-то еще, например, на другую строку malloced или на начало массива, который вы определили в примере 2.

Второй создает массив символов (способ представления строки). Массив сохраняется и размещается в стеке на время работы функции, и вы можете изменить его содержимое. Поскольку это не указатель, вы не можете изменить его так, чтобы он указывал на другую строку.

person Joe    schedule 25.08.2012
comment
Другими словами, первое объявление создает неизменяемую строку, а второе — изменяемую? - person rogi; 25.08.2012
comment
Нет, можно изменить строку, если хотите (в C можно делать практически все). Но вы не должны! Это просто разные способы создания строки. Вы должны прочитать о распределении памяти, чтобы понять лучше. - person Joe; 25.08.2012
comment
+десять тысяч за то, что вы можете делать почти все на C, Но вы не должны! - person Chani; 25.08.2012
comment
Я бы предпочел, чтобы вы проголосовали 9 999 раз, чем 10 000 раз! - person Joe; 25.08.2012
comment
Могут ли отрицатели, пожалуйста, указать причины для отказа? - person Joe; 27.08.2012

C не имеет строк. Все, что есть, это char массивы. А массивы в C — это просто указатели на первый элемент.

Самый простой способ сделать это на самом деле ваш первый вариант. Если не указать явную длину массива для литералов, это убережет вас от случайного выполнения чего-то вроде

char[3] = "abc";
person Joey    schedule 25.08.2012

Строки C постоянны в памяти, поэтому:

char *str = "This is string";

Сохраняет «Это строка» в памяти, и она не может быть изменена, вы можете только назначить другой адрес для str.

тем не мение

char str2[20] = "This si string"; 

это сокращение от

char String2[20]={'T','h','i','s',' ','s','i',' ','s','t','r','i','n','g','\0'};

который не хранит строку в памяти, хранит независимые байты.

Если вы хотите использовать постоянные строки, такие как сообщения, используйте первую строку. Если вы хотите использовать и манипулировать строками, как в текстовом процессоре, используйте second.

С Уважением

person Community    schedule 25.08.2012
comment
неизменяемый не совсем точен - person Joe; 25.08.2012

char *str = "This is string"; — это сохранит строку в текстовом сегменте как данные только для чтения и сохранит адрес в локальной переменной указателя str.

str[0] = 'a'; //This will leads to crash, because strings are in read only segment.
printf("%d",sizeof(str)); //This will print 4(in 32bit m/c) or 8(in 64 bit m/c)

char str2[20] = "This is string"; — это сохранит строку как массив символов в локальном стеке.

str2[0] = 'a'; //This will change the first character to a
printf("%d",sizeof(str2)); //This will print 20
person rashok    schedule 25.08.2012