Passer un littéral de chaîne en tant que paramètre de fonction défini en tant que pointeur

Je lis le chapitre sur les tableaux et les pointeurs dans The C Programming Language de Kernighan et Richie.

Ils donnent l’exemple:

/* strlen:  return length of ssortingng s */ int strlen(char *s) {     int n;     for (n = 0; *s != '\0'; s++)         n++;     return n; } 

Et puis dites:

“Puisque s est un pointeur, l’incrémenter est parfaitement légal; s++ n’a aucun effet sur la chaîne de caractères de la fonction appelée strlen , mais incrémente simplement la copie privée du pointeur de strlen. Cela signifie que des appels comme

 strlen("hello, world");  /* ssortingng constant */ strlen(array);           /* char array[100]; */ strlen(ptr);             /* char *ptr; */ 

tout le travail.”

J’ai l’impression de comprendre tout cela, à l’exception du premier exemple: Pourquoi ou comment le caractère littéral de la chaîne "hello, world" traité comme un caractère? Comment est-ce un pointeur? La fonction atsortingbue-t-elle ce littéral de chaîne à la valeur de sa variable locale *s , puis utilise-t-elle s comme nom / pointeur de tableau?

Pour comprendre comment une chaîne telle que “Hello World” est convertie en pointeur, il est important de comprendre que la chaîne est en réalité une donnée hexadécimale commençant à une adresse et se déplaçant jusqu’à trouver une NULL

Cela signifie donc que chaque constante de chaîne telle que “Hello World” est stockée quelque part dans la mémoire.

La possibilité serait:

 0x10203040 : 0x48 [H] 0x10203041 : 0x65 [e] 0x10203042 : 0x6C [l] 0x10203043 : 0x6C [l] 0x10203044 : 0x6F [o] 0x10203045 : 0x20 [' '] 0x10203046 : 0x57 [W] 0x10203047 : 0x6F [o] 0x10203048 : 0x72 [r] 0x10203049 : 0x6C [l] 0x1020304A : 0x64 [d] 0x1020304B : 0x00 [\0] 

Ainsi, lorsque cette fonction est appelée avec les valeurs ci-dessus dans la mémoire, [le côté gauche correspond à l’adresse suivie de ‘:’ et le côté droit correspond à la valeur ascii du caractère]

 int strlen(const char *s) { int n; for (n = 0; *s != ′\0′; s++) n++; return n; } strlen("Hello World"); 

à ce moment, ce qui est passé à strlen est la valeur 0x10203040 qui est l’adresse du premier élément du tableau de caractères.

Avis, l’adresse est passée par valeur .. par conséquent, strlen a sa propre copie de l’adresse de “Hello World”. à partir de n = 0 , après la mise à jour, je trouve \0 dans la mémoire, j’incrémente n et aussi l’adresse dans s (qui est ensuite incrémentée à 0x10203041 ) et ainsi de suite, jusqu’à trouver \0 à l’adresse 0x1020304B et renvoie la chaîne longueur.

"hello, world"

est un tableau de char (type est char[13] ). La valeur d’un tableau de char dans une expression est un pointeur sur char . Le pointeur pointe sur le premier élément du tableau (c’est-à-dire que la valeur de "hello, world" est &"hello, world"[0] ).

Notez que:

  • Un pointeur est (fondamentalement) une valeur pointant vers une adresse mémoire.
  • Une chaîne statique comme "hello, word" est stockée quelque part en mémoire

Ainsi, un pointeur pourrait aussi facilement pointer sur une chaîne statique que sur toute autre structure (dynamic) stockée en mémoire (comme un tableau de caractères). Il n’y a vraiment aucune différence avec les autres exemples fournis.

La fonction atsortingbue-t-elle ce littéral de chaîne à la valeur de sa variable locale * s, puis utilise-t-elle s comme nom / pointeur de tableau?

Oui