Lecture d’une chaîne avec scanf

Je suis un peu confus à propos de quelque chose. J’avais l’impression que la manière correcte de lire une chaîne C avec scanf() allait dans le sens de

(peu importe le débordement de tampon possible, c’est juste un exemple simple)

 char ssortingng[256]; scanf( "%s" , ssortingng ); 

Cependant, le suivant semble fonctionner aussi,

 scanf( "%s" , &ssortingng ); 

Est-ce juste mon compilateur (gcc), pure chance ou autre chose?

Un tableau “se désintègre” en un pointeur vers son premier élément, donc scanf("%s", ssortingng) est équivalent à scanf("%s", &ssortingng[0]) . En revanche, scanf("%s", &ssortingng) passe un pointeur à caractère char[256] , mais il pointe vers le même endroit.

Ensuite, scanf , lors du traitement de la queue de sa liste d’arguments, essaiera d’extraire un caractère char * . C’est le bon choix quand vous avez passé la ssortingng ou la &ssortingng[0] , mais quand vous avez entré &ssortingng vous dépendez de quelque chose que la norme de langue ne garantit pas, à savoir que les pointeurs &ssortingng et &ssortingng[0] – les pointeurs vers des objects de différents types et tailles qui commencent au même endroit – sont représentés de la même façon.

Je ne crois pas avoir jamais rencontré un système sur lequel cela ne fonctionne pas et, dans la pratique, vous êtes probablement en sécurité. Néanmoins, c’est faux, et cela pourrait échouer sur certaines plates-formes. (Exemple hypothétique: une implémentation de “débogage” qui inclut des informations de type à chaque pointeur. Je pense que l’implémentation C sur les “Lisp Machines” de Symbolics a fait quelque chose comme ça.)

Je pense que ce qui suit est exact et que cela peut aider. N’hésitez pas à le corriger si vous trouvez des erreurs. Je suis nouveau chez C.

 char str[] 
  1. tableau de valeurs de type char, avec sa propre adresse en mémoire
  2. tableau de valeurs de type char, avec sa propre adresse en mémoire autant d’adresses consécutives que d’éléments dans le tableau
  3. y compris la terminaison null caractère '\0' &str , &str[0] et str , tous les trois représentent le même emplacement en mémoire qui est l’adresse du premier élément du tableau str

    char * strPtr = & str [0]; // déclaration et initialisation

alternativement, vous pouvez diviser ceci en deux:

 char *strPtr; strPtr = &str[0]; 
  1. strPtr est un pointeur sur un caractère
  2. strPtr points strPtr sur le tableau str
  3. strPtr est une variable avec sa propre adresse en mémoire
  4. strPtr est une variable qui stocke la valeur de l’adresse &str[0]
  5. strPtr propre adresse de strPtr en mémoire est différente de l’adresse de mémoire strPtr (adresse du tableau dans la mémoire, alias & str [0])
  6. &strPtr représente l’adresse de strPtr lui-même

Je pense que vous pouvez déclarer un pointeur sur un pointeur comme:

 char **vPtr = &strPtr; 

déclare et initialise avec l’adresse du pointeur strPtr

Sinon, vous pouvez diviser en deux:

 char **vPtr; *vPtr = &strPtr 
  1. *vPtr Points vPtr au pointeur strPtr
  2. *vPtr est une variable avec sa propre adresse en mémoire
  3. *vPtr est une variable qui stocke la valeur de l’adresse & strPtr
  4. commentaire final: vous ne pouvez pas faire str++ , l’adresse str est un const , mais vous pouvez faire strPtr++