Différence entre char* et const char*?

Quelle est la différence entre

char* name

qui indique une chaîne constante littérale, et

const char* name
131
demandé sur zergius 2012-03-23 08:09:43

9 réponses

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 changer le contenu de l'emplacement(des emplacements) vers lequel pointe ce pointeur. Aussi, les compilateurs sont tenus de donner des messages d'erreur lorsque vous essayez de le faire. Pour la même raison, conversion de const char * en char* est obsolète.

char* const est un indicateur immuable (il ne peut pas pointer vers un autre endroit) mais le contenu de l'endroit où il pointe est mutable .

const char* const est un indicateur immuable à un immuable caractère/chaîne.

311
répondu ankit.karwasra 2018-02-28 23:51:04
char *name

vous pouvez changer le caractère sur lequel name pointe, et aussi le caractère sur lequel il pointe.

const char* name

vous pouvez changer le caractère sur lequel name pointe, mais vous ne pouvez pas modifier le caractère sur lequel il pointe.

correction: Vous pouvez changer le pointeur, mais pas le char à laquelle name renvoie ( ) https://msdn.microsoft.com/en-us/library/vstudio/whkd4k6a (v = 100).aspx , voir"Exemples"). Dans ce cas , le spécificateur 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 decl, tandis que le const après * fait partie du déclarant.

Une séquence spécifiant une déclaration peut être suivie par plusieurs déclarants, 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 poser la question de la différence entre les deux déclarations lorsque le pointeur pointe vers une chaîne littérale.

dans ce cas, vous ne devrait pas modifier le char à laquelle name points, car il pourrait en résulter comportement non défini . Les caractères alphabétiques des chaînes de caractères peuvent être attribués dans des régions de mémoire en lecture seule (implémentation définie) et un programme utilisateur ne devrait pas les modifier de toute façon. Toute tentative de le faire entraîne un Comportement non défini.

donc la seule différence dans ce cas (de l'usage avec des 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 au cas où vous tenteriez de modifier la chaîne littérale dans le second cas.

Exemple D'Échantillon 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: erreur: passing argument 1 of ‘strcpy’ ignore qualificatifs de pointeur de type de cible

Avis le compilateur indique le second cas, mais pas pour le premier.

41
répondu Alok Save 2015-02-10 06:10:41
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] = '"151900920"'; // compile error
charconstp[3] = '"151900920"'; // compile error
charpconst[3] = '"151900920"'; // 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
14
répondu Afriza N. Arief 2012-03-23 04:37:29

dans aucun des cas vous ne pouvez modifier une chaîne de caractères littérale, que le pointeur de cette chaîne de caractères littérale soit déclaré comme 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 tentez de modifier la valeur pointée-à, mais si le pointeur est char * alors il ne le fait pas.

9
répondu caf 2012-03-23 04:22:48

le premier vous pouvez réellement changer si vous voulez, le second vous ne pouvez pas. Lisez à propos de l'exactitude const (il y a de bons guides sur la différence). Il y a aussi char const * name où vous ne pouvez pas le réutiliser.

2
répondu chikuba 2016-12-18 23:13:24

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 *?

1
répondu Jeff Wolski 2017-05-23 12:02:47

CASE 1:

char *str = "Hello";
str[0] = 'M'  //No warning or error, just Undefined Behavior

ce qui précède définit str pour pointer vers la valeur littérale" Hello " qui est codée en dur dans l'image binaire du programme, qui est marqué comme lecture seule dans la mémoire, signifie que tout changement dans cette chaîne littérale est illégal et qui lancerait des défauts de segmentation.

CASE 2:

const char *str = "Hello";
str[0] = 'M'  //Compiler issues a warning

CASE 3:

char str[] = "Hello";
str[0] = 'M'; // legal and change the str = "Mello".
1
répondu Mohit 2017-11-15 06:45:36

Juste pour donner un exemple supplémentaire:

    std::cout << typeid(2.3).name() << '\n'; // -----> prints "double" simply because
    //2.3 is a double
    //But the "double" returned by typeid(2.3).name() is indeed a 
    //const char * which consists of 'd','o','u','b','l','e'and'"151900920"'.
    //Here's a simple proof to this:
    std::cout << typeid(typeid(2.3).name()).name() << '\n'; //prints: "const char *"
    const char* charptr
    charptr = typeid(2.3).name();
    std::cout << charptr[3]; // --------->  prints: "b"

(j'utilise la bibliothèque typeinfo: http://www.cplusplus.com/reference/typeinfo/type_info/name )

    //Now let's do something more interesting:
    char* charptr2="hubble";
    strcpy(charptr, charptr2);  // --------> Oops! Sorry, this is not valid!

vous pouvez l'exécuter et voir les choses mieux pour vous-même.

0
répondu M-J 2017-06-12 17:46:45

la question Est Quelle est la différence entre

char *name

qui indique une chaîne constante littérale, et

const char *cname

i. e. 1519180920"

char *name = "foo";

et

const char *cname = "foo";

il n'y a pas beaucoup de différence entre le 2 et les deux peuvent être considérés comme corrects. En raison du long héritage du code C, la chaîne de caractères littéraux ont eu un type de char[] , Non const char[] , et il y a beaucoup de vieux codes qui acceptent également char * au lieu de const char * , même s'ils ne modifient pas les arguments.

la principale différence des 2 en général est que *cname ou cname[n] va évaluer à l des valeurs de type const char , tandis que *name ou name[n] va évaluer à l des valeurs de type char , qui sont modifiables l des valeurs . Un compilateur conforme est requis pour produire un message de diagnostic si cible de l'assignation n'est pas une valeur l modifiable ; il n'est pas nécessaire de produire un avertissement lors de l'assignation aux valeurs L de type char :

name[0] = 'x'; // no diagnostics *needed*
cname[0] = 'x'; // a conforming compiler *must* produce a diagnostics message

le compilateur n'est pas requis pour arrêter la compilation dans l'un ou l'autre cas; il suffit qu'il produise un avertissement pour la cession à cname[0] . Le programme résultant n'est pas un correct du programme. Le comportement de la construction est Non défini . Il peut s'écraser, ou même pire, il peut ne pas s'écraser, et peut changer la chaîne littérale en mémoire.

0
répondu Antti Haapala 2017-08-24 19:13:29