web-dev-qa-db-fra.com

Pourquoi une chaîne peut-elle être assignée à un pointeur char *, mais pas à un tableau char []?

Quelqu'un peut-il expliquer pourquoi cela fonctionne avec le pointeur:

char * str1;

str1 = "Hello1";

str1 = "new string";

// but not this
char str2 [] = "hello";
str2 = "four";

// or this
char str3 [];
str3 = "hello";
str3 = "hello";
61
nick

Pourquoi ça marche avec les pointeurs:
Quand tu dis char * str1 en C, vous allouez un pointeur dans la mémoire. Quand vous écrivez str1 = "Hello";, vous créez un littéral de chaîne en mémoire et vous le faites pointer par le pointeur. Lorsque vous créez un autre littéral de chaîne "new string" et l'assigner à str1, tout ce que vous faites est de changer le pointeur.

Pourquoi ça ne marche pas avec les tableaux:
Quand tu dis char str2 [] = "Hello", vous créez un littéral de chaîne et le placez dans le tableau lors de sa définition. Il est correct de ne pas donner de taille, car le tableau la calcule et ajoute un '\0' à elle. Vous ne pouvez rien réaffecter à ce tableau sans le redimensionner. C'est pourquoi str2 = "four" ne fonctionnera pas.

En cas de str3, c'est le même cas. Vous n'avez pas défini la taille du tableau dans la définition, elle a donc calculé que sa taille était 0. Vous ne pouvez rien affecter de nouveau sans redimensionner le tableau.

77
tryurbest

Un tableau et un pointeur sont des choses différentes, c'est pourquoi. Vous pouvez affecter à un pointeur, mais vous ne pouvez pas affecter à un tableau. Une exception spéciale est faite pour l'initialisation de tableaux de caractères avec des littéraux de chaîne.

char a[] = "Hello"; //initialize a char array with string literal. Special case, OK
char* p = "Hello"; //initializa a pointer with an array(which gets converted to pointer)
p = "My";   //assign pointer to point to another value. OK
a = "My";   //error, arrays cannot be assigned to. Use `strcpy`

Les littéraux de chaîne (tels que "Hello") ont le type char[N]N est le nombre de caractères (y compris le '\0' Final). Un tableau peut être converti en un pointeur vers son premier élément, mais les tableaux et les pointeurs ne sont pas la même chose, quels que soient les mauvais livres ou les mauvais enseignants.

19
Armen Tsirunyan

En d'autres termes, un tableau n'est pas un objet de première classe en C/C++. La seule façon d'assigner à un tableau est d'utiliser str (n) cpy ou memcpy.

Bien qu'un tableau se réduise en un pointeur lorsqu'il est passé à une fonction, il n'est pas possible d'assigner à un tableau, sauf au moment de la compilation comme initialisation.

7
Julian

Le cas des pointeurs Cela fonctionne parce que lorsque vous affectez comme str1="Hello", Vous créez en fait un littéral appelé hello en l'allouant quelque part dans la mémoire et en attribuant l'adresse du premier caractère du littéral au pointeur. Le pointeur n'étant pas constant, vous pouvez le réattribuer avec des adresses différentes. Et un autre point important à noter est que le littéral de chaîne créé est en mémoire en lecture seule.

Le cas avec tableau de caractères Vous pouvez lui attribuer un littéral de chaîne lors de l'initialisation, comme cela est supporté par la langue. Et ne confondez pas l'affectation avec l'initialisation. Pendant l’affectation, car il s’agit d’un tableau de caractères, vous devez modifier la valeur, caractère par caractère. Vous essayez d’adresser la première adresse du littéral chaîne au premier caractère du tableau (le nom du tableau renvoie l’adresse du premier élément de la chaîne). tableau) .Et ceci n’est clairement pas correct car le premier élément n’est pas un pointeur, il ne peut pas stocker l’adresse.

3
joker007

C'est simplement parce que, lorsque vous écrivez ce code:

char str2 [] = "hello";

ou même:

int arr[] = {1,2,4,4,5};

ça crée str2 ou arr en tant que pointeur constant. C'est pourquoi vous ne pouvez pas réaffecter d'autres valeurs à ces pointeurs. Par la suite, vous créez un pointeur normal et vous pouvez y affecter n'importe quoi.

3
Sawan