Ich vermassele immer, wie man benutzt const int*
, const int * const
und int const *
korrekt. Gibt es eine Reihe von Regeln, die definieren, was Sie tun können und was nicht?
Ich möchte alle Do’s und Don’ts in Bezug auf Aufgaben, Versetzungen etc. kennen.

Matt Preis
Lesen Sie es rückwärts (wie gefahren von Im Uhrzeigersinn/Spiralregel):
int*
– Zeiger auf int
int const *
– Zeiger auf const int
int * const
– konstanter Zeiger auf int
int const * const
– const Zeiger auf const int
Jetzt das erste const
kann auf beiden Seiten des Typs sein, also:
const int *
== int const *
const int * const
== int const * const
Wenn du wirklich verrückt werden willst, kannst du folgende Dinge tun:
int **
– Zeiger auf Zeiger auf int
int ** const
– ein konstanter Zeiger auf einen Zeiger auf ein int
int * const *
– ein Zeiger auf eine Konstante, ein Zeiger auf ein Int
int const **
– ein Zeiger auf einen Zeiger auf eine Konstante int
int * const * const
– ein konstanter Zeiger auf einen konstanten Zeiger auf ein int
- …
Und um sicherzustellen, dass wir uns über die Bedeutung von im Klaren sind const
:
int a = 5, b = 10, c = 15;
const int* foo; // pointer to constant int.
foo = &a; // assignment to where foo points to.
/* dummy statement*/
*foo = 6; // the value of a can´t get changed through the pointer.
foo = &b; // the pointer foo can be changed.
int *const bar = &c; // constant pointer to int
// note, you actually need to set the pointer
// here because you can't change it later ;)
*bar = 16; // the value of c can be changed through the pointer.
/* dummy statement*/
bar = &a; // not possible because bar is a constant pointer.
foo
ist ein variabler Zeiger auf eine konstante ganze Zahl. Dadurch können Sie ändern, worauf Sie zeigen, aber nicht den Wert, auf den Sie zeigen. Am häufigsten tritt dies bei Strings im C-Stil auf, bei denen Sie einen Zeiger auf a haben const char
. Sie können ändern, auf welche Zeichenfolge Sie zeigen, aber Sie können den Inhalt dieser Zeichenfolgen nicht ändern. Dies ist wichtig, wenn sich der String selbst im Datensegment eines Programms befindet und nicht geändert werden soll.
bar
ist ein konstanter oder fester Zeiger auf einen Wert, der geändert werden kann. Das ist wie eine Referenz ohne den zusätzlichen syntaktischen Zucker. Aus diesem Grund würden Sie normalerweise eine Referenz anstelle von a verwenden T* const
Zeiger, es sei denn, Sie müssen dies zulassen NULL
Zeiger.

Shijing Lv
Für diejenigen, die die Regel im Uhrzeigersinn/Spirale nicht kennen: Beginnen Sie beim Namen der Variablen und bewegen Sie sich im Uhrzeigersinn (in diesem Fall rückwärts) zur nächsten Zeiger oder Art. Wiederholen, bis der Ausdruck endet.
Hier ist eine Demo:






Kaz-Drache
Ich denke, hier ist bereits alles beantwortet, aber ich möchte nur hinzufügen, dass Sie sich hüten sollten typedef
S! Sie sind NICHT nur Textersetzungen.
Zum Beispiel:
typedef char *ASTRING;
const ASTRING astring;
Die Art von astring
ist char * const
nicht const char *
. Dies ist ein Grund, warum ich immer dazu neige, zu sagen const
rechts vom Typ und niemals am Anfang.

Lukas
Wie so ziemlich alle darauf hingewiesen haben:
Was ist der Unterschied zwischen const X* p
, X* const p
und const X* const p
?
Sie müssen Zeigerdeklarationen von rechts nach links lesen.
-
const X* p
bedeutet “p zeigt auf ein X, das konstant ist”: Das X-Objekt kann nicht über p geändert werden.
-
X* const p
bedeutet “p ist ein konstanter Zeiger auf ein X, das nicht konstant ist”: Sie können den Zeiger p selbst nicht ändern, aber Sie können das X-Objekt über p ändern.
-
const X* const p
bedeutet “p ist ein konstanter Zeiger auf ein X, das konstant ist”: Sie können den Zeiger p selbst nicht ändern, noch können Sie das X-Objekt über p ändern.

Behrooz Tabesh
-
Konstante Referenz:
Ein Verweis auf eine Variable (hier int), die konstant ist. Wir übergeben die Variable hauptsächlich als Referenz, weil Referenzen kleiner sind als der tatsächliche Wert, aber es gibt einen Nebeneffekt, und zwar, weil es wie ein Alias für die tatsächliche Variable ist. Wir können die Hauptvariable versehentlich durch unseren vollen Zugriff auf den Alias ändern, also machen wir sie konstant, um diesen Nebeneffekt zu verhindern.
int var0 = 0;
const int &ptr1 = var0;
ptr1 = 8; // Error
var0 = 6; // OK
-
Konstante Zeiger
Sobald ein konstanter Zeiger auf eine Variable zeigt, kann er auf keine andere Variable zeigen.
int var1 = 1;
int var2 = 0;
int *const ptr2 = &var1;
ptr2 = &var2; // Error
-
Zeiger auf Konstante
Ein Zeiger, durch den der Wert einer Variablen, auf die er zeigt, nicht geändert werden kann, wird als Zeiger auf eine Konstante bezeichnet.
int const * ptr3 = &var2;
*ptr3 = 4; // Error
-
Konstante Zeiger auf eine Konstante
Ein konstanter Zeiger auf eine Konstante ist ein Zeiger, der weder die Adresse ändern kann, auf die er zeigt, noch den an dieser Adresse gehaltenen Wert ändern kann.
int var3 = 0;
int var4 = 0;
const int * const ptr4 = &var3;
*ptr4 = 1; // Error
ptr4 = &var4; // Error

Azeem
Die allgemeine Regel ist, dass die const
Schlüsselwort bezieht sich auf das, was ihm unmittelbar vorausgeht. Ausnahme, ein Start const
gilt für das Folgende.
const int*
ist das gleiche wie int const*
und Mittel “Zeiger auf Konstante int”.
const int* const
ist das gleiche wie int const* const
und Mittel “konstanter Zeiger auf konstante int”.
Bearbeiten:
Falls diese Antwort nicht ausreicht, könnten Sie Ihre Wünsche genauer beschreiben?

Gemeinschaft
Diese Frage zeigt genau Warum ich Dinge so mache, wie ich in meiner Frage erwähnt habe, ist const nach Typ-ID akzeptabel?
Kurz gesagt, ich finde, der einfachste Weg, sich an die Regel zu erinnern, ist, dass das “const” geht nach dem die Sache, auf die es sich bezieht. In Ihrer Frage bedeutet also “int const *”, dass int konstant ist, während “int * const” bedeuten würde, dass der Zeiger konstant ist.
Wenn sich jemand dafür entscheidet, es ganz nach vorne zu setzen (zB: “const int *”), gilt es in diesem Fall als besondere Ausnahme für das Ding dahinter.
Viele Leute verwenden gerne diese spezielle Ausnahme, weil sie denken, dass sie schöner aussieht. Ich mag es nicht, weil es eine Ausnahme ist und dadurch die Dinge verwirrt.
10033200cookie-checkWas ist der Unterschied zwischen const int*, const int * const und int const *?yes
Du kannst den … benutzen „Im Uhrzeigersinn/Spiralregel“ um die meisten C- und C++-Deklarationen zu entschlüsseln.
– James McNellis
13. Juni 2010 um 20:49 Uhr
cdecl.org ist eine großartige Website, die C-Deklarationen automatisch für Sie übersetzt.
– David
2. November 2010 um 19:37 Uhr
@Calmarius: Beginnen Sie dort, wo der Typname ist / sein sollte, bewegen Sie sich nach rechts, wenn Sie können, nach links, wenn Sie müssen.
int *(*)(char const * const)
. Beginnen Sie rechts von der Klammer*
dann müssen wir nach links gehen:pointer
. Außerhalb der Klammern können wir uns nach rechts bewegen:pointer to function of ...
. Dann müssen wir nach links gehen:pointer to function of ... that returns pointer to int
. Wiederholen Sie den Vorgang, um den Parameter zu erweitern (die...
):pointer to function of (constant pointer to constant char) that returns pointer to int
. Was wäre die äquivalente einzeilige Deklaration in einer leicht lesbaren Sprache wie Pascal?– Mark K. Cowan
9. Juli 2015 um 17:08 Uhr
@MarkKCowan In Pascal wäre es so etwas wie
function(x:^char):^int
. Dort implizieren Funktionstypen einen Zeiger auf eine Funktion, sodass sie nicht angegeben werden muss, und Pascal erzwingt keine const-Korrektheit. Es kann von links nach rechts gelesen werden.– Kalmarius
9. Juli 2015 um 20:54 Uhr
Das erste, was links von “const” steht, ist die Konstante. Wenn “const” das am weitesten links stehende Ding ist, dann ist das erste Ding rechts davon die Konstante.
– Cupcake
31. Juli 2016 um 4:41 Uhr