Was ist der Unterschied zwischen:
char * const
und
const char *
Was ist der Unterschied zwischen:
char * const
und
const char *
Antworten:
Der Unterschied besteht darin, dass const char *
es sich um einen Zeiger auf a handelt const char
, während char * const
es sich um einen konstanten Zeiger auf a handelt char
.
Der erste Wert, auf den gezeigt wird, kann nicht geändert werden, der Zeiger jedoch. Der zweite Wert, auf den gezeigt wird, kann sich ändern, der Zeiger jedoch nicht (ähnlich einer Referenz).
Da ist auch ein
const char * const
Dies ist ein konstanter Zeiger auf ein konstantes Zeichen (daher kann nichts daran geändert werden).
Hinweis:
Die folgenden zwei Formen sind äquivalent:
const char *
und
char const *
Der genaue Grund hierfür ist im C ++ - Standard beschrieben, es ist jedoch wichtig, die Verwirrung zu beachten und zu vermeiden. Ich kenne mehrere Codierungsstandards, die Folgendes bevorzugen:
char const
Über
const char
(mit oder ohne Zeiger), so dass die Platzierung des const
Elements dieselbe ist wie bei einem Zeiger const
.
const int *foo,*bar;
würde beides erklären foo
und bar
sein int const *
, aber int const *foo, *bar
würde erklären foo
, ein int const *
und bar
zu sein int *
. Ich denke typedef int * intptr; const intptr foo,bar;
, beide Variablen würden deklariert int * const
; Ich kenne keine Möglichkeit, eine kombinierte Deklaration zu verwenden, um zwei Variablen dieses Typs ohne typedef zu erstellen.
I believe const int *foo,*bar; would declare both foo and bar to be int const *
: Ja. but int const *foo, *bar would declare foo to be a int const * and bar to be int *
: Nein! Es wäre genau das gleiche wie im vorherigen Fall. (Siehe ideone.com/RsaB7n, wo Sie den gleichen Fehler für foo und bar erhalten). I think typedef int * intptr; const intptr foo,bar; would declare both variables to be int * const
: Ja. I don't know any way to use a combined declaration to create two variables of that type without a typedef
: Nun, int *const foo, *const bar;
. C-Deklaratorsyntax ...
int const *foo, *volatile bar
ich tun bar
? Machen Sie es beide const
und volatile
? Ich vermisse Pascals saubere Trennung von Namen deklarierter Variablen und ihren Typen (ein Zeiger auf ein Array von Zeigern auf ganze Zahlen wäre var foo: ^Array[3..4] of ^Integer
; `. Das wäre eine lustige Sache in verschachtelten Klammern in C, denke ich.
int const *foo, *volatile bar
" ist der Typ Teil int const
(stoppt vor dem *
) und die Deklaratoren sind *foo
(der Ausdruck *foo
bezeichnet ein int const
) und *volatile bar
; Lesen von rechts nach links (gute Regel für cv-Qualifier ), foo
ist ein Zeiger auf einen const int, und bar
ist ein flüchtiger Zeiger auf ein const int (der Zeiger selbst ist flüchtig, auf das spitze int wird [als] const zugegriffen).
[3..4]
Syntax nicht sicher , also nehmen wir ein Array von 10 Elementen) : int *(*foo)[10];
. Es spiegelt seine (zukünftige) Verwendung als Ausdruck wider: *(*foo)[i]
(mit i
einer Ganzzahl im Bereich [0, 10)
dh [0, 9]
) wird zuerst dereferenziert foo
, um auf das Array zuzugreifen, dann auf das Element am Index zuzugreifen i
(da das Postfix []
enger als das Präfix bindet *
) und dieses Element schließlich dereferenziert Nachgeben eines int
(siehe ideone.com/jgjIjR ). Aber typedef
macht es einfacher (siehe ideone.com/O3wb7d ).
Um Verwirrung zu vermeiden, hängen Sie immer das const-Qualifikationsmerkmal an.
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
bezieht sich nicht auf den Typ : (const int *const)
. Zum Guten oder Schlechten (schlechter, wenn Sie mich fragen) ist das const-Qualifikationsmerkmal sowohl in C als auch in C ++ als Postfix: cf const-Member-Funktion gedacht void foo(int a) const;
. Die Möglichkeit zu deklarieren const int
ist eher die Ausnahme als die Regel.
const
Ändert immer das, was davor steht (links davon), AUSSER wenn es das erste in einer Typdeklaration ist, wo es das Ding ändert, das danach kommt (rechts davon).
Diese beiden sind also gleich:
int const *i1;
const int *i2;
sie definieren Zeiger auf a const int
. Sie können wo i1
und i2
Punkte ändern , aber Sie können den Wert, auf den sie zeigen, nicht ändern.
Dies:
int *const i3 = (int*) 0x12345678;
Definiert einen const
Zeiger auf eine Ganzzahl und initialisiert ihn so, dass er auf den Speicherplatz 12345678 zeigt. Sie können den int
Wert an der Adresse 12345678 ändern, aber die Adresse, auf die i3
zeigt, kann nicht geändert werden .
const * char
ist ungültiger C-Code und bedeutungslos. Vielleicht wollten Sie den Unterschied zwischen a const char *
und a fragen char const *
, oder vielleicht den Unterschied zwischen a const char *
und a char * const
?
const char*
ist ein Zeiger auf ein konstantes Zeichen
char* const
ist ein konstanter Zeiger auf ein Zeichen
const char* const
ist ein konstanter Zeiger auf ein konstantes Zeichen
Faustregel: Lesen Sie die Definition von rechts nach links!
const int *foo;
Bedeutet " foo
Punkte ( *
) auf eine int
, die sich nicht ändern kann ( const
)".
Für den Programmierer bedeutet dies "Ich werde den Wert dessen, auf was foo
zeigt, nicht ändern ".
*foo = 123;
oder foo[0] = 123;
wäre ungültig.foo = &bar;
ist erlaubt.int *const foo;
Bedeutet " foo
kann nicht ändern ( const
) und zeigt ( *
) auf ein int
".
Für den Programmierer bedeutet dies "Ich werde die Speicheradresse, auf die foo
Bezug genommen wird, nicht ändern ".
*foo = 123;
oder foo[0] = 123;
ist erlaubt.foo = &bar;
wäre ungültig.const int *const foo;
Bedeutet " foo
kann sich nicht ändern ( const
) und zeigt ( *
) auf ein int
, das sich nicht ändern kann ( const
)".
Für den Programmierer bedeutet dies "Ich werde weder den Wert der foo
Punkte ändern, noch die Adresse , foo
auf die verwiesen wird ".
*foo = 123;
oder foo[0] = 123;
wäre ungültig.foo = &bar;
wäre ungültig.const char * x Hier ist X im Grunde ein Zeichenzeiger, der auf einen konstanten Wert zeigt
char * const x bezieht sich auf einen konstanten Zeichenzeiger, aber die Position, auf die er zeigt, kann geändert werden.
const char * const x ist eine Kombination aus 1 und 2, dh es handelt sich um einen konstanten Zeichenzeiger, der auf einen konstanten Wert zeigt.
const * char x verursacht einen Compilerfehler. es kann nicht deklariert werden.
char const * x ist gleich Punkt 1.
Als Faustregel gilt: Wenn const den Namen var hat, ist der Zeiger konstant, aber die Zeigeposition kann geändert werden. Andernfalls zeigt der Zeiger auf eine konstante Position und der Zeiger kann auf eine andere Position zeigen, der Inhalt der Zeigeposition kann jedoch nicht geändert werden .
Viele Antworten bieten spezifische Techniken, Daumenregeln usw., um diese spezielle Instanz der Variablendeklaration zu verstehen. Es gibt jedoch eine generische Technik, um jede Erklärung zu verstehen:
Im Uhrzeigersinn / Spiralregel
EIN)
const char *a;
Gemäß der Regel im Uhrzeigersinn / Spirale a
ist der Zeiger auf ein Zeichen konstant. Das heißt, das Zeichen ist konstant, aber der Zeiger kann sich ändern. dh a = "other string";
ist in Ordnung, kann aber a[2] = 'c';
nicht kompiliert werden
B)
char * const a;
Gemäß der Regel a
ist const Zeiger auf ein Zeichen. dh Sie können tun, a[2] = 'c';
aber Sie können nicht tuna = "other string";
Ich nehme an, Sie meinen const char * und char * const.
Das erste, const char *, ist ein Zeiger auf ein konstantes Zeichen. Der Zeiger selbst ist veränderbar.
Das zweite, char * const, ist ein konstanter Zeiger auf ein Zeichen. Der Zeiger kann sich nicht ändern, das Zeichen, auf das er zeigt, kann.
Und dann gibt es const char * const, wo sich Zeiger und Zeichen nicht ändern können.
Hier ist eine detaillierte Erklärung mit 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’
}
Syntax:
datatype *const var;
char *const
fällt unter diesen Fall.
/*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;
}
Syntax:
const datatype *var
oder datatype const *var
const char*
fällt unter diesen Fall.
/* 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 und const char *?
const char * p;
// Wert kann nicht geändert werden
char * const p;
// Adresse kann nicht geändert werden
const char * const p;
// beide können nicht geändert werden.
Das const
Modifikator wird auf den Begriff unmittelbar links davon angewendet. Die einzige Ausnahme ist, wenn links nichts ist, dann gilt dies für das, was unmittelbar rechts davon ist.
Dies sind alles äquivalente Arten, "konstanter Zeiger auf eine Konstante char
" zu sagen :
const char * const
const char const *
char const * const
char const const *
Zwei Regeln
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.
z.B
char const *. This is a pointer points to a constant char.
char * const. This is a constant pointer points to a char.
Ich möchte darauf hinweisen, dass es bei der Verwendung von int const *
(oder const int *
) nicht um einen Zeiger geht, der auf eine const int
Variable zeigt, sondern dass diese Variable const
für diesen bestimmten Zeiger bestimmt ist.
Beispielsweise:
int var = 10;
int const * _p = &var;
Der obige Code wird einwandfrei kompiliert. _p
zeigt auf eine const
Variable, obwohl sie var
selbst nicht konstant ist.
Ich erinnere mich aus dem tschechischen Buch über C: Lesen Sie die Erklärung, dass Sie mit der Variablen beginnen und nach links gehen. So für
char * const a;
Sie können lesen als: " a
ist eine Variable vom Typ Konstantenzeiger auf char
",
char const * a;
Sie können lesen als: " a
ist ein Zeiger auf eine konstante Variable vom Typ char. Ich hoffe, das hilft.
Bonus:
const char * const a;
Sie lesen den a
konstanten Zeiger auf eine konstante Variable vom Typ char.