C chaînes pointeur vs tableaux

Dupliquer possible:
Quelle est la difference entre char s [] et char * s en C?

Pourquoi est-ce:

char *ptr = "Hello!" 

différent de:

 char ptr[] = "Hello!" 

Plus précisément, je ne vois pas pourquoi vous pouvez utiliser (* ptr) ++ pour changer la valeur de ‘H’ dans le tableau, mais pas le pointeur.

Merci!

Vous pouvez (en général) utiliser l’expression (*ptr)++ pour modifier la valeur indiquée par ptr lorsque ptr est un pointeur et non un tableau (c’est-à-dire, si ptr est déclaré comme char* ptr ).

Cependant, dans votre premier exemple:

 char *ptr = "Hello!" 

ptr pointe sur une chaîne littérale, et les chaînes littérales ne peuvent pas être modifiées (elles peuvent en réalité être stockées dans une zone mémoire non inscriptible, telle que des pages ROM ou mémoire marquées en lecture seule).

Dans votre deuxième exemple,

 char ptr[] = "Hello!"; 

Le tableau est déclaré et l’initialisation copie les données du littéral chaîne dans la mémoire du tableau allouée. Cette mémoire de tableau est modifiable, donc (*ptr)++ fonctionne.

Remarque: pour votre deuxième déclaration, l’identifiant ptr lui-même est un identifiant de tableau, pas un pointeur et n’est pas une “valeur l”, il ne peut donc pas être modifié (même s’il se convertit facilement en pointeur dans de nombreuses situations). Par exemple, l’expression ++ptr serait invalide. Je pense que c’est l’argument que d’autres réponses essaient de faire.

Lisez la FAQ en langage C. Spécialement les sections tableau et pointeurs .

Les tableaux allouent automatiquement de l’espace. Ils ne peuvent pas être déplacés ni redimensionnés. Les pointeurs sont explicitement affectés au point atsortingbué à l’espace alloué et peuvent être déplacés.

Les noms de tableaux sont en lecture seule !

Si vous utilisez un littéral de chaîne "Hello!" , le littéral lui-même devient un tableau de 7 caractères et est stocké quelque part dans une mémoire de données. Cette mémoire peut être en lecture seule.

La déclaration

 char *ptr = "Hello!"; 

définit un pointeur sur char et l’initialise en y stockant l’adresse du début du littéral (le tableau de 7 caractères mentionné précédemment). Changer le contenu de la mémoire indiquée par ptr est illégal.

La déclaration

 char ptr[] = "Hello!"; 

définit un tableau de caractères ( char ptr[7] ) et l’initialise en copiant des caractères du littéral au tableau. Le tableau peut être modifié.

en C, les chaînes sont des tableaux de caractères. Un pointeur est une variable qui contient l’emplacement mémoire d’une autre variable. Un tableau est un ensemble d’éléments de données ordonnés. lorsque vous mettez ++ (*), vous obtenez une erreur de segmentation avec le pointeur.

Peut-être que vous ajoutez 1 à la chaîne entière (avec le pointeur), au lieu d’append 1 au premier caractère de la variable (avec le tableau).

Lorsque vous pointez un littéral de chaîne, vous ne devez pas déclarer les caractères modifiables, et certains compilateurs vous en avertiront:

 char *ptr = "Hello!" /* WRONG, missing const! */ 

La raison en est que d’autres ont noté que les littéraux de chaîne peuvent être stockés dans une partie immuable de la mémoire du programme.

La bonne “annotation” pour vous est de vous assurer que vous avez un pointeur sur un caractère constant:

 const char *ptr = "Hello!" 

Et maintenant, vous voyez directement que vous ne pouvez pas modifier le texte stocké au pointeur.