256 votes

Différence entre char* et const char* ?

Quelle est la différence entre

char* name

qui pointe vers un littéral de chaîne constante, et

const char* name

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".

535voto

ankit.karwasra Points 681

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.

4 votes

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.

4 votes

@ankit.karwasra, Vous avez manqué un autre : char const *

0 votes

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.

45voto

Alok Save Points 115848
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.

Exemple en ligne :

#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.

0 votes

Merci je mélangeais avec la constante string literal, qui est définie comme : char* name = "String Literal" ; Changer "String Literal" est indéfini

0 votes

@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.

0 votes

Oui, c'était le but. Donc, dans ce cas, char* name et const char* name se comportent de la même manière, non ?

26voto

afriza Points 2388
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

1 votes

Aucun de vos pointeurs n'indique de "chaînes de caractères littéraux constants" comme dans la question.

1 votes

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).

0 votes

Pouvez-vous expliquer la dernière ligne que je n'ai pas comprise.

13voto

caf Points 114951

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.

1 votes

"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.

0 votes

@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à.

0 votes

@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.

1voto

Jeff Wolski Points 3956

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.com

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.

Powered by:

X