Назначение строк массивам символов
Я немного удивлен следующим.
Пример 1:
char s[100] = "abcd"; // declare and initialize - WORKS
Пример 2:
char s[100]; // declare
s = "hello"; // initalize - DOESN'T WORK ('lvalue required' error)
мне интересно, почему второй подход не работает. Кажется естественным, что он должен (он работает с другими типами данных)? Может кто-нибудь объяснить мне логику этого?
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 от делает свою работу.
Comments