Quelle est la différence entre
char* name
qui pointe vers un littéral de chaîne constante, et
const char* name
Quelle est la différence entre
char* name
qui pointe vers un littéral de chaîne constante, et
const char* name
char*
est un mutable pointeur vers un mutable caractère/chaîne.
const char*
est un mutable pointeur vers un immuable caractère/chaîne. Vous ne pouvez pas modifier le contenu de l'emplacement (ou des emplacements) vers lequel ce pointeur pointe. En outre, les compilateurs sont tenus d'émettre des messages d'erreur lorsque vous essayez de le faire. Pour la même raison, la conversion de const char *
à char*
est déprécié.
char* const
est un immuable pointeur (il ne peut pas pointer vers un autre endroit) mais le contenu de l'emplacement sur lequel il pointe est mutable .
const char* const
est un immuable pointeur vers un immuable caractère/chaîne.
La confusion peut être dissipée par l'utilisation d'une variable après les déclarations mentionnées ci-dessus et en donnant une référence à cette variable.
Je pense que deux options avec des caractères/chaînes de caractères mutables sont très dangereuses, car on peut faire une erreur de segmentation de la mémoire, et si on est vraiment intelligent, on peut pirater l'ordinateur. C'est pourquoi les compilateurs montrent toujours des avertissements dans ces implémentations, je pense.
char *name
Vous pouvez modifier l'image à laquelle name
et aussi l'omble sur lequel il pointe.
const char* name
Vous pouvez modifier l'image à laquelle name
mais vous ne pouvez pas modifier l'omble sur lequel il pointe.
correction : Vous pouvez changer le pointeur, mais pas l'image à laquelle name
pointe vers ( https://msdn.microsoft.com/en-us/library/vstudio/whkd4k6a(v=vs.100).aspx (voir "Exemples"). Dans ce cas, le const
s'applique à char
et non l'astérisque.
Selon la page MSDN et http://en.cppreference.com/w/cpp/language/declarations le const
avant le *
fait partie de la séquence du spécificateur de déclin, tandis que l'élément const
après *
fait partie du déclarateur.
Une séquence de spécificateurs de déclaration peut être suivie de plusieurs déclarateurs, c'est pourquoi const char * c1, c2
déclare c1
comme const char *
et c2
comme const char
.
EDIT :
D'après les commentaires, votre question semble porter sur la différence entre les deux déclarations lorsque le pointeur pointe vers un littéral de chaîne de caractères.
Dans ce cas, vous ne devrait pas modifier l'omble auquel name
points, car cela pourrait entraîner Comportement indéfini . Les chaînes de caractères peuvent être allouées dans des régions de mémoire en lecture seule (définies par l'implémentation) et un programme utilisateur ne doit en aucun cas les modifier. Toute tentative de le faire entraîne un comportement indéfini.
Ainsi, la seule différence dans ce cas (d'utilisation avec les chaînes de caractères) est que la deuxième déclaration vous donne un léger avantage. Les compilateurs vous donneront généralement un avertissement si vous tentez de modifier le littéral de chaîne dans le second cas.
#include <string.h>
int main()
{
char *str1 = "string Literal";
const char *str2 = "string Literal";
char source[] = "Sample string";
strcpy(str1,source); //No warning or error, just Undefined Behavior
strcpy(str2,source); //Compiler issues a warning
return 0;
}
Sortie :
cc1 : les avertissements sont traités comme des erreurs
prog.c : Dans la fonction 'main' :
prog.c:9 : error : passing argument 1 of 'strcpy' discards qualifiers from pointer target type
Remarquez que le compilateur avertit pour le deuxième cas mais pas pour le premier.
Merci je mélangeais avec la constante string literal, qui est définie comme : char* name = "String Literal" ; Changer "String Literal" est indéfini
@user1279782 : Err, Attendez ! Est-ce que vous parlez de pointes pointant vers des littéraux de chaîne ici ? Dans ce cas, vous ne devrait pas modifier l'omble auquel le name
des points dans les deux cas. Cela pourrait aboutir à l'UB.
Oui, c'était le but. Donc, dans ce cas, char* name et const char* name se comportent de la même manière, non ?
char mystring[101] = "My sample string";
const char * constcharp = mystring; // (1)
char const * charconstp = mystring; // (2) the same as (1)
char * const charpconst = mystring; // (3)
constcharp++; // ok
charconstp++; // ok
charpconst++; // compile error
constcharp[3] = '\0'; // compile error
charconstp[3] = '\0'; // compile error
charpconst[3] = '\0'; // ok
// String literals
char * lcharp = "My string literal";
const char * lconstcharp = "My string literal";
lcharp[0] = 'X'; // Segmentation fault (crash) during run-time
lconstcharp[0] = 'X'; // compile error
// *not* a string literal
const char astr[101] = "My mutable string";
astr[0] = 'X'; // compile error
((char*)astr)[0] = 'X'; // ok
Aucun de vos pointeurs n'indique de "chaînes de caractères littéraux constants" comme dans la question.
Il convient de noter que la modification du char *
donne un défaut de segmentation puisque nous essayons de modifier une chaîne littérale (qui est présente dans la mémoire en lecture seule).
Dans les deux cas, vous ne pouvez pas modifier un littéral de chaîne de caractères, que le pointeur vers ce littéral de chaîne de caractères soit déclaré en tant que char *
ou const char *
.
Cependant, la différence est que si le pointeur est const char *
alors le compilateur doit donner un diagnostic si vous essayez de modifier la valeur pointée, mais si le pointeur est char *
alors ce n'est pas le cas.
"Dans aucun cas vous ne pouvez modifier une chaîne littérale, indépendamment du fait que... [il] est déclaré comme char * ou const char *" Je suis d'accord pour dire que le programmeur ne devrait pas essayer, mais êtes-vous en train de dire que tous les compilateurs C, sur toutes les plates-formes, rejetteront le code, s'arrangeront pour que le code échoue au moment de l'exécution, ou autre chose ? Je pense qu'un fichier pourrait contenir la définition et l'initialisation, et un autre fichier pourrait contenir extern ... name
et ont *name = 'X';
. Sur un "bon système d'exploitation", cela pourrait échouer, mais sur les systèmes embarqués, je m'attendrais à ce qu'il fasse quelque chose de spécifique à la plate-forme ou au compilateur.
@gbulmer : Vous ne pouvez pas modifier une chaîne littérale dans un programme C correct. Ce que peut donner un programme C incorrect qui s'y essaye n'est ni ici ni là.
@gbulmer : Une définition utile est un programme qui ne brise aucune des contraintes spécifiées par le standard du langage C. En d'autres termes, un programme qui modifie une chaîne de caractères littérale est incorrect de la même manière qu'un programme qui déréférence un pointeur nul ou effectue une division par 0 est incorrect.
En fait, char* name
n'est pas un pointeur vers une constante, mais un pointeur vers une variable. Vous parlez peut-être de cette autre question.
Quelle est la différence entre char * const et const char * ?
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
0 votes
Que voulez-vous dire par " constant string literal" en C (pas en C++)
1 votes
... on peut faire en sorte que char *name pointe vers une chaîne littérale constante
0 votes
La constante dans "constant string literal" est redondante, puisque tous les string literals sont en théorie des entités constantes. C'est le contenu de la variable qui peut être rendu constant ou mutable. La déclaration "const" va simplement générer une erreur de compilation si vous essayez de changer le contenu du caractère pointé par "name".
1 votes
Simple : "char *name" name est un pointeur vers char, c'est-à-dire que les deux peuvent être changés ici. "const char *name" name est un pointeur vers const char, c'est-à-dire que le pointeur peut changer mais pas le char.
1 votes
Lisez ces choses de droite à gauche.