Назначение строк массивам символов


Я немного удивлен следующим.

Пример 1:

char s[100] = "abcd"; // declare and initialize - WORKS

Пример 2:

char s[100]; // declare
s = "hello"; // initalize - DOESN'T WORK ('lvalue required' error)

мне интересно, почему второй подход не работает. Кажется естественным, что он должен (он работает с другими типами данных)? Может кто-нибудь объяснить мне логику этого?

8   51  
2009-02-24 01:47:18

8 ответов:

при инициализации массива, C позволяет заполнить его значениями. так что

char s[100] = "abcd";

в основном то же самое, что

int s[3] = { 1, 2, 3 };

но это не позволяет вам делать assignmend, так как s является массивом, а не свободным указателем. значение

s = "abcd" 

это присвоить значение указателя "abcd" на "s", но вы не можете изменить s, так как тогда ничто не будет указывать на массив.
Это может и работает если S -char* - это указатель, который может указывать на что угодно.

если вы хотите скопировать строку просто используйте strcpy

нет такой вещи, как "строка" в C. строки-это массивы char, заканчивающиеся NULL по Конвенции. Поскольку вы не можете назначать массивы в C, вы также не можете назначать строки. Буквальное "привет" - это синтаксический сахар для const char x[] = {'h','e','l','l','o',''};

правильно будет так:

char s[100];
strncpy(s, "hello", 100);

или еще лучше:

#define STRMAX 100
char    s[STRMAX];
size_t  len;
len = strncpy(s, "hello", STRMAX);

Инициализация и назначение-это две различные операции, которые здесь используют один и тот же оператор ("=").

1    char s[100];
2    s = "hello";

в приведенном примере s фактически инициализируется в строке 1, а не в строке 2. Даже если вы не назначили ему значение явно в этот момент, компилятор сделал это. В строке 2 вы выполняете операцию назначения, и вы не можете назначить один массив символов другому массиву символов, как это. Вам придется использовать strcpy () или какой-то цикл, чтобы назначить каждый элемент массива.

расширить на Я думаю так!--10-->

Инициализация и назначение-это две различные операции, которые здесь используют один и тот же оператор ("=").

подумайте об этом так:

представьте, что есть 2 функции, называемые InitializeObject и AssignObject. Когда компилятор видит thing = value, Он смотрит на контекст и вызывает один InitializeObject Если вы делаете новый thing. Если вы этого не сделаете, он вместо этого звонит AssignObject.

обычно это нормально, так как InitializeObject и AssignObject обычно ведут себя одинаково. За исключением случаев, когда речь идет о массивах символов (и нескольких других крайних случаях), в этом случае они ведут себя по-разному. Зачем это делать? Ну, это целый другой пост с участием стека против кучи и так далее и тому подобное.

PS: в стороне, думая об этом таким образом, также поможет вам понять конструкторы копирования и другие подобные вещи, если вы когда-нибудь рискнете в C++

обратите внимание, что вы еще можете сделать:

s[0] = 'h';
s[1] = 'e';
s[2] = 'l';
s[3] = 'l';
s[4] = 'o';
s[5] = '';

вы можете использовать это:

yylval.sval=strdup("VHDL + Volcal trance...");

где yylval - это char*. strdup от делает свою работу.

что я хотел бы использовать

char *s = "abcd";