Affectation de chaînes à des tableaux de caractères

Je suis un peu surpris par ce qui suit.

Exemple 1:

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

Exemple 2:

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

Je me demande pourquoi la deuxième approche ne fonctionne pas. Cela semble naturel (ça marche avec d’autres types de données)? Quelqu’un pourrait-il m’expliquer la logique derrière cela?

Lors de l’initialisation d’un tableau, C vous permet de le remplir avec des valeurs. alors

 char s[100] = "abcd"; 

est fondamentalement le même que

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

mais cela ne vous permet pas de faire l’assignation puisque s est un tableau et non un pointeur libre. le sens de

 s = "abcd" 

est d’atsortingbuer la valeur de pointeur de “abcd” à “s”, mais vous ne pouvez pas changer s depuis lors, rien ne pointera vers le tableau.
Cela peut fonctionner et fonctionne si s est un caractère char* – un pointeur qui peut indiquer n’importe quoi.

si vous voulez copier la chaîne, utilisez simplement strcpy

Il n’y a pas de “chaîne” en C. Les chaînes sont des tableaux de caractères, terminés par NULL par convention. Comme vous ne pouvez pas affecter de tableaux en C, vous ne pouvez pas non plus les atsortingbuer. Le littéral “bonjour” est du sucre syntaxique pour les caractères const char x[] = {'h','e','l','l','o','\0'};

La manière correcte serait:

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

ou mieux encore:

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

L’initialisation et l’affectation sont deux opérations distinctes qui utilisent le même opérateur (“=”) ici.

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

Dans l’exemple que vous avez fourni, s est réellement initialisé à la ligne 1, pas à la ligne 2. Même si vous ne lui avez pas atsortingbué explicitement une valeur à ce stade, le compilateur l’a fait. À la ligne 2, vous effectuez une opération d’affectation et vous ne pouvez pas affecter un tableau de caractères à un autre tableau de caractères comme celui-ci. Vous devrez utiliser strcpy () ou une sorte de boucle pour assigner chaque élément du tableau.

Pour développer la réponse de Sparr

L’initialisation et l’affectation sont deux opérations distinctes qui utilisent le même opérateur (“=”) ici.

Pensez-y comme ceci:

Imaginez qu’il y ait 2 fonctions, appelées InitializeObject et AssignObject . Lorsque le compilateur voit thing = value , il regarde le contexte et appelle un object InitializeObject si vous faites une nouvelle thing . Si vous ne l’êtes pas, il appelle plutôt AssignObject .

Normalement, cela fonctionne bien car InitializeObject et AssignObject se comportent généralement de la même manière. Sauf en ce qui concerne les tableaux de caractères (et quelques autres cas extrêmes), auquel cas ils se comportent différemment. Pourquoi faire ceci? Eh bien, c’est un tout autre article impliquant la stack contre le tas et ainsi de suite.

PS: En passant, le fait de penser de cette manière vous aidera également à comprendre les constructeurs de copies et d’autres choses du genre si vous vous aventurez dans C ++.

Notez que vous pouvez toujours faire:

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

Vous pouvez utiliser ceci:

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

Où yylval est char *. Strdup de fait le travail.

Ce que je voudrais utiliser est

 char *s = "abcd";