Quelle est la différence entre:
char * const
et
const char *
Quelle est la différence entre:
char * const
et
const char *
Réponses:
La différence est qu'il const char *
s'agit d'un pointeur vers a const char
, tandis que char * const
c'est un pointeur constant vers a char
.
La première, la valeur pointée ne peut pas être modifiée mais le pointeur peut l'être. La seconde, la valeur pointée peut changer mais pas le pointeur (similaire à une référence).
Il y a aussi
const char * const
qui est un pointeur constant vers un caractère constant (donc rien à ce sujet ne peut être changé).
Remarque:
Les deux formes suivantes sont équivalentes:
const char *
et
char const *
La raison exacte de cela est décrite dans la norme C ++, mais il est important de noter et d'éviter la confusion. Je connais plusieurs normes de codage qui préfèrent:
char const
plus de
const char
(avec ou sans pointeur) afin que le placement de l' const
élément soit le même qu'avec un pointeur const
.
const int *foo,*bar;
que déclarerait les deux foo
et bar
serait int const *
, mais int const *foo, *bar
déclarerait foo
être int const *
et bar
être int *
. Je pense typedef int * intptr; const intptr foo,bar;
que déclarerait les deux variables int * const
; Je ne connais aucun moyen d'utiliser une déclaration combinée pour créer deux variables de ce type sans typedef.
I believe const int *foo,*bar; would declare both foo and bar to be int const *
: Oui. but int const *foo, *bar would declare foo to be a int const * and bar to be int *
: Non! Ce serait exactement la même chose que dans le cas précédent. (Voir ideone.com/RsaB7n où vous obtenez la même erreur pour foo et bar). I think typedef int * intptr; const intptr foo,bar; would declare both variables to be int * const
: Oui. I don't know any way to use a combined declaration to create two variables of that type without a typedef
: Eh bien, int *const foo, *const bar;
. Syntaxe du déclarant C ...
int const *foo, *volatile bar
-il bar
? Faites les deux const
et volatile
? La séparation nette de Pascal des noms de variables déclarées et de leurs types me manque (un pointeur vers un tableau de pointeurs vers des entiers serait var foo: ^Array[3..4] of ^Integer
; `. Ce serait une drôle de parenthèse imbriquée en C, je pense.
int const *foo, *volatile bar
", la partie type est int const
(s'arrête avant le *
) et les déclarants sont *foo
(l'expression *foo
dénote un int const
) et *volatile bar
; lire de droite à gauche (bonne règle pour les qualificatifs cv ), foo
est un pointeur vers un const int, et bar
est un pointeur volatil vers un const int (le pointeur lui-même est volatil, le pointé est [accédé comme] const).
[3..4]
syntaxe, de sorte que nous allons prendre un tableau de 10 éléments): int *(*foo)[10];
. Il reflète son utilisation (future) en tant qu'expression: *(*foo)[i]
(avec i
un entier dans la plage, [0, 10)
c'est-à-dire [0, 9]
) déréférencera d'abord foo
pour atteindre le tableau, puis accédera à l'élément à l'index i
(car postfix []
se lie plus étroitement que le préfixe *
), puis déréférencer cet élément, enfin donnant un int
(voir ideone.com/jgjIjR ). Mais typedef
c'est plus facile (voir ideone.com/O3wb7d ).
Pour éviter toute confusion, ajoutez toujours le qualificatif const.
int * mutable_pointer_to_mutable_int;
int const * mutable_pointer_to_constant_int;
int *const constant_pointer_to_mutable_int;
int const *const constant_pointer_to_constant_int;
p
ne se rapporte pas au type: (const int *const)
. Pour le meilleur ou pour le pire (pire si vous me le demandez), le qualificatif const, à la fois en C et C ++, est censé être postfix: cf fonction membre const void foo(int a) const;
. La possibilité de déclarer const int
est l'exception plutôt que la règle.
const
modifie toujours la chose qui la précède (à gauche de celle-ci), SAUF quand c'est la première chose dans une déclaration de type, où elle modifie la chose qui la suit (à sa droite).
Donc, ces deux sont les mêmes:
int const *i1;
const int *i2;
ils définissent des pointeurs vers a const int
. Vous pouvez modifier où i1
et les i2
points, mais vous ne pouvez pas modifier la valeur vers laquelle ils pointent.
Ce:
int *const i3 = (int*) 0x12345678;
définit un const
pointeur sur un entier et l'initialise pour pointer à l'emplacement de mémoire 12345678. Vous pouvez modifier la int
valeur à l'adresse 12345678, mais vous ne pouvez pas modifier l'adresse qui i3
pointe vers.
const * char
est un code C invalide et n'a pas de sens. Peut-être vouliez-vous demander la différence entre a const char *
et a char const *
, ou peut-être la différence entre a const char *
et a char * const
?
const char*
est un pointeur vers un caractère constant
char* const
est un pointeur constant vers un caractère
const char* const
est un pointeur constant vers un caractère constant
Règle générale: lisez la définition de droite à gauche!
const int *foo;
Signifie " foo
pointe ( *
) vers un int
qui ne peut pas changer ( const
)".
Pour le programmeur, cela signifie "Je ne changerai pas la valeur de ce qui foo
pointe vers".
*foo = 123;
ou foo[0] = 123;
serait invalide.foo = &bar;
est autorisée.int *const foo;
Signifie " foo
ne peut pas changer ( const
) et pointe ( *
) en int
".
Pour le programmeur, cela signifie "Je ne changerai pas l' adresse mémoire qui foo
fait référence à".
*foo = 123;
ou foo[0] = 123;
est autorisé.foo = &bar;
serait invalide.const int *const foo;
Signifie " foo
ne peut pas changer ( const
) et pointe ( *
) sur un int
qui ne peut pas changer ( const
)".
Pour le programmeur, cela signifie «Je ne changerai pas la valeur de ce qui foo
pointe vers, ni je ne changerai l' adresse qui foo
fait référence».
*foo = 123;
ou foo[0] = 123;
serait invalide.foo = &bar;
serait invalide.const char * x Ici, X est essentiellement un pointeur de caractère qui pointe vers une valeur constante
char * const x fait référence au pointeur de caractère qui est constant, mais l'emplacement qu'il pointe peut être modifié.
const char * const x est une combinaison de 1 et 2, signifie qu'il s'agit d'un pointeur de caractère constant qui pointe vers une valeur constante.
const * char x provoquera une erreur de compilation. il ne peut pas être déclaré.
char const * x est égal au point 1.
la règle générale est que si const est avec le nom var, le pointeur sera constant mais l'emplacement de pointage peut être modifié , sinon le pointeur pointera vers un emplacement constant et le pointeur peut pointer vers un autre emplacement mais le contenu de l'emplacement de pointage ne peut pas être modifié .
Le premier est une erreur de syntaxe. Peut-être que vous vouliez dire la différence entre
const char * mychar
et
char * const mychar
Dans ce cas, le premier est un pointeur vers des données qui ne peuvent pas changer, et le second est un pointeur qui pointera toujours vers la même adresse.
Beaucoup de réponses fournissent des techniques spécifiques, des règles empiriques, etc. pour comprendre cette instance particulière de déclaration de variable. Mais il existe une technique générique pour comprendre toute déclaration:
Règle horaire / spirale
UNE)
const char *a;
Selon la règle horaire / spirale, le a
pointeur sur le caractère est constant. Ce qui signifie que le caractère est constant mais que le pointeur peut changer. c'est-à a = "other string";
- dire est bien, mais a[2] = 'c';
ne parviendra pas à compiler
B)
char * const a;
Selon la règle, a
est le pointeur const vers un caractère. c'est-à-dire que vous pouvez faire a[2] = 'c';
mais vous ne pouvez pas fairea = "other string";
Je suppose que vous voulez dire const char * et char * const.
Le premier, const char *, est un pointeur sur un caractère constant. Le pointeur lui-même est modifiable.
Le second, char * const est un pointeur constant vers un caractère. Le pointeur ne peut pas changer, le caractère vers lequel il pointe peut.
Et puis il y a const char * const où le pointeur et le caractère ne peuvent pas changer.
Voici une explication détaillée avec le code
/*const char * p;
char * const p;
const char * const p;*/ // these are the three conditions,
// const char *p;const char * const p; pointer value cannot be changed
// char * const p; pointer address cannot be changed
// const char * const p; both cannot be changed.
#include<stdio.h>
/*int main()
{
const char * p; // value cannot be changed
char z;
//*p = 'c'; // this will not work
p = &z;
printf(" %c\n",*p);
return 0;
}*/
/*int main()
{
char * const p; // address cannot be changed
char z;
*p = 'c';
//p = &z; // this will not work
printf(" %c\n",*p);
return 0;
}*/
/*int main()
{
const char * const p; // both address and value cannot be changed
char z;
*p = 'c'; // this will not work
p = &z; // this will not work
printf(" %c\n",*p);
return 0;
}*/
// Some more complex constant variable/pointer declaration.
// Observing cases when we get error and warning would help
// understanding it better.
int main(void)
{
char ca1[10]= "aaaa"; // char array 1
char ca2[10]= "bbbb"; // char array 2
char *pca1= ca1;
char *pca2= ca2;
char const *ccs= pca1;
char * const csc= pca2;
ccs[1]='m'; // Bad - error: assignment of read-only location ‘*(ccs + 1u)’
ccs= csc; // Good
csc[1]='n'; // Good
csc= ccs; // Bad - error: assignment of read-only variable ‘csc’
char const **ccss= &ccs; // Good
char const **ccss1= &csc; // Bad - warning: initialization from incompatible pointer type
char * const *cscs= &csc; // Good
char * const *cscs1= &ccs; // Bad - warning: initialization from incompatible pointer type
char ** const cssc= &pca1; // Good
char ** const cssc1= &ccs; // Bad - warning: initialization from incompatible pointer type
char ** const cssc2= &csc; // Bad - warning: initialization discards ‘const’
// qualifier from pointer target type
*ccss[1]= 'x'; // Bad - error: assignment of read-only location ‘**(ccss + 8u)’
*ccss= ccs; // Good
*ccss= csc; // Good
ccss= ccss1; // Good
ccss= cscs; // Bad - warning: assignment from incompatible pointer type
*cscs[1]= 'y'; // Good
*cscs= ccs; // Bad - error: assignment of read-only location ‘*cscs’
*cscs= csc; // Bad - error: assignment of read-only location ‘*cscs’
cscs= cscs1; // Good
cscs= cssc; // Good
*cssc[1]= 'z'; // Good
*cssc= ccs; // Bad - warning: assignment discards ‘const’
// qualifier from pointer target type
*cssc= csc; // Good
*cssc= pca2; // Good
cssc= ccss; // Bad - error: assignment of read-only variable ‘cssc’
cssc= cscs; // Bad - error: assignment of read-only variable ‘cssc’
cssc= cssc1; // Bad - error: assignment of read-only variable ‘cssc’
}
Syntaxe:
datatype *const var;
char *const
relève de ce cas.
/*program to illustrate the behaviour of constant pointer */
#include<stdio.h>
int main(){
int a=10;
int *const ptr=&a;
*ptr=100;/* we can change the value of object but we cannot point it to another variable.suppose another variable int b=20; and ptr=&b; gives you error*/
printf("%d",*ptr);
return 0;
}
Syntaxe:
const datatype *var
ou datatype const *var
const char*
relève de ce cas.
/* program to illustrate the behavior of pointer to a constant*/
#include<stdio.h>
int main(){
int a=10,b=20;
int const *ptr=&a;
printf("%d\n",*ptr);
/* *ptr=100 is not possible i.e we cannot change the value of the object pointed by the pointer*/
ptr=&b;
printf("%d",*ptr);
/*we can point it to another object*/
return 0;
}
char * const et const char *?
const char * p;
// la valeur ne peut pas être modifiée
char * const p;
// l'adresse ne peut pas être modifiée
const char * const p;
// les deux ne peuvent pas être modifiés.
Le const
modificateur est appliqué au terme immédiatement à sa gauche. La seule exception à cela est quand il n'y a rien à sa gauche, alors cela s'applique à ce qui est immédiatement à sa droite.
Ce sont toutes des façons équivalentes de dire "pointeur constant vers une constante char
":
const char * const
const char const *
char const * const
char const const *
Deux règles
If const is between char and *, it will affect the left one.
If const is not between char and *, it will affect the nearest one.
par exemple
char const *. This is a pointer points to a constant char.
char * const. This is a constant pointer points to a char.
Je voudrais souligner que l'utilisation int const *
(ou const int *
) ne concerne pas un pointeur pointant vers une const int
variable, mais que cette variable est const
pour ce pointeur spécifique.
Par exemple:
int var = 10;
int const * _p = &var;
Le code ci-dessus compile parfaitement bien. _p
pointe vers une const
variable, var
même si elle-même n'est pas constante.
Je me souviens d'un livre tchèque sur C: lisez la déclaration que vous commencez avec la variable et allez à gauche. Donc pour
char * const a;
vous pouvez lire comme: " a
est une variable de type pointeur constant vers char
",
char const * a;
vous pouvez lire comme: " a
est un pointeur vers une variable constante de type char. J'espère que cela aide.
Prime:
const char * const a;
Vous lirez tel a
quel un pointeur constant vers une variable constante de type char.