nanataw, la forme correcte de ton programme serait:
Code :
- #include <stdio.h>
- #include <string.h>
- int main(void)
- {
- const char (*a) = "test";
- a++;
- printf("%c\n", *a) ;
- return 0;
- }
|
*a est un const char donc a est un pointeur sur un const char.
Et c'est très bien ainsi, car quand on fait
Code :
- #include <stdio.h>
- #include <string.h>
- int main(void)
- {
- char *a = "test";
- a++;
- printf("%c\n", *a) ;
- return 0;
- }
|
dans les faits, a pointe en réalité des const char et vouloir modifier la valeur d'un caractère pointé par a va déclencher une run-time error.
Alors que ce sera détecté à la compilation si l'on déclare a comme un pointeur sur un const char.
C'est toute la différence avec ce qui est fait ici:
Code :
- #include <stdio.h>
- #include <string.h>
- int main(void)
- {
- char a[] = "test";
- char *p = a;
- ++p;
- printf("%c\n", *p) ;
- return 0;
- }
|
a est un tableau qui initialisé par copie de la zone contenant "test". C'est le seul cas ou on n'a pas besoin de donner sa taille au tableau, RdC, car le compilateur la calcule avant de créer le tableau, à partir de la taille de ce qui doit être copié. a est ici un char[5].
De ce fait, son contenu est modifiable.
Donc
char *a = "test"; // a pointe en fait sur des chars non modifiables (dans une zone créée a la compilation), et on ne le dit pas, dangereux
const char (*a) = "test"; // a pointe en fait sur des chars non modifiables, et on le dit, OK
char a[] = "test"; // a est un char[5] créé a l'exécution, qui contient une copie de "test", donc modifiable, OK
Noter que dans tous les cas, on est la merci d'un run-time error par dépassement de la taille du tableau. Donc faire un test if (*p) avant d'avancer son pointeur peut être utile.
Dans la pratique:
J'ai une chaine "test" utilisée uniquement en lecture: const char (*a) = "test";
J'ai une chaine "test" dont certains caractères peuvent être modifié: char a[] = "test"; c'est un cas assez rare
J'ai une chaine initialisée à "test" complètement modifiable, même en taille: char *a = strdup("test'); qu'on oubliera pas de libérer avec un free après utilisation, et on fait du realloc si sa taille devient insuffisante.
Et... bien souvent
J'ai une chaine initialisée à "test" complètement modifiable, même en taille, mais dont je sais qu'elle ne sera jamais plus grande que TAILLE_MAX
char a[TAILLE_MAX+1] = "test";
(ici le compilo crée le tableau avec la taille donnée, puis fait la copie (éventuellement avec troncature si la taille du tableau est trop petite)).
L'avantage de cette technique, c'est que c'est le programme qui va gérer automatiquement la libération du tableau lorsqu'il sort du scope.
A+,
Message édité par gilou le 01-12-2017 à 11:39:06
---------------
There's more than what can be linked! -- Iyashikei Anime Forever! -- AngularJS c'est un framework d'engulé! --