Присвоение строк массивам символов

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

Пример 1:

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

Пример 2:

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

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

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

 char s[100] = "abcd"; 

в основном такой же, как

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

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

 s = "abcd" 

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

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

В C. не существует такой строки, как «строка». Строки – это массивы символов, которые заканчиваются NULL по соглашению. Поскольку вы не можете назначать массивы на C, вы также не можете назначать строки. Литеральным «привет» является синтаксический сахар для const char x[] = {'h','e','l','l','o','\0'};

Правильный способ:

 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 () или какой-то цикл для назначения каждого элемента массива.

Чтобы расширить ответ Спарра

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

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

Представьте, что есть 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] = '\0'; 

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

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

Где yylval – char *. strdup от этой работы.

Что я буду использовать

 char *s = "abcd"; 
  • Функция, возвращающая адрес локальной переменной ошибки в C
  • локальная переменная, инициализированная нулем в C
  • Ошибка сегментации, восстанавливающая строковый литерал
  • Побитовая функция поворота влево
  • Что означает void * и как его использовать?
  • Синхронизированный метод Java на объекте или методе?
  • Есть ли функция для округления поплавка на C или мне нужно написать собственное?
  • проблема с плавающей запятой в R?
  • Как отключить буферизацию stdout в C
  • Как представить 0,1 в арифметике с плавающей точкой и десятичной запятой
  • C - передача массива 2d в качестве аргумента функции?
  • Давайте будем гением компьютера.