Frage Was ist der Unterschied zwischen const int *, const int * const und int const *?


Ich vermassle 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 alle Verbote in Bezug auf Aufgaben, Weitergabe an die Funktionen usw. kennen.


992
2017-07-17 13:28


Ursprung


Antworten:


Lies es rückwärts (wie von Clockwise / Spiralregel):

  • int* - Zeiger auf int
  • int const * - Zeiger auf const int
  • int * const - const Zeiger auf int
  • int const * const - const Zeiger auf const int

Jetzt der erste const kann auf beiden Seiten des Typs so sein:

  • const int * == int const *
  • const int * const == int const * const

Wenn Sie wirklich verrückt werden wollen, können Sie Folgendes tun:

  • int ** - Zeiger auf Zeiger auf int
  • int ** const - ein const-Zeiger auf einen Zeiger auf einen int
  • int * const * - Ein Zeiger auf einen const Zeiger auf einen int
  • int const ** - ein Zeiger auf einen Zeiger auf einen const int
  • int * const * const - ein const-Zeiger auf einen const-Zeiger auf einen int
  • ...

Und um sicherzugehen, dass wir uns über die Bedeutung von const

const int* foo;
int *const bar; //note, you actually need to set the pointer 
                //here because you can't change it later ;)

foo ist ein variabler Zeiger auf eine konstante ganze Zahl. Auf diese Weise können Sie ändern, auf was Sie zeigen, aber nicht auf den Wert, auf den Sie zeigen. Meistens wird dies bei C-artigen Strings beobachtet, bei denen Sie einen Zeiger auf a haben const char. Sie können ändern, auf welche Zeichenfolge Sie verweisen, aber Sie können den Inhalt dieser Zeichenfolgen nicht ändern. Dies ist wichtig, wenn sich die Zeichenfolge selbst im Datensegment eines Programms befindet und nicht geändert werden sollte.

bar ist ein konstanter oder fester Zeiger auf einen Wert, der geändert werden kann. Dies ist wie eine Referenz ohne den zusätzlichen syntaktischen Zucker. Wegen dieser Tatsache würden Sie normalerweise eine Referenz verwenden, wo Sie eine verwenden würden T* const Zeiger, sofern Sie nicht zulassen müssen NULL Zeiger.


1740
2017-07-17 13:29



Für diejenigen, die nicht über Clockwise / Spiral Rule wissen: Beginnen Sie mit dem Namen der Variablen, bewegen Sie sich im Uhrzeigersinn (in diesem Fall rückwärts) zum nächsten Zeiger oder Art. Wiederholen Sie den Vorgang, bis der Ausdruck endet.

Hier ist eine Demo:

pointer to int

const pointer to int const

pointer to int const

pointer to const int

const pointer to int


232
2017-07-10 02:15



Ich denke, hier ist schon alles beantwortet, aber ich möchte nur hinzufügen, dass du dich davor hüten solltest typedefs! Sie sind nicht nur Textersatz.

Beispielsweise:

typedef char *ASTRING;
const ASTRING astring;

Die Art von astring ist char * constnicht const char *. Dies ist einer der Gründe, warum ich immer tendiere const rechts vom Typ und niemals am Anfang.


123
2017-07-17 13:39



Wie so ziemlich jeder betont hat:

Was ist der Unterschied zwischen const X* p, X* const p und const X* const p?

Sie müssen Zeigerdeklarationen lesen   rechts nach links.

  • const X* p bedeutet "p zeigt auf ein X, das const ist": Das X-Objekt kann nicht über p geändert werden.

  • X* const p bedeutet "p ist ein const-Zeiger auf ein X, das nicht-const 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 const-Zeiger auf ein X, das const ist": Sie können weder den Zeiger p selbst ändern noch das X-Objekt über p ändern.


44
2017-07-17 13:36



  1. Konstante Referenz:

    Eine Referenz 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 deshalb, 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 es konstant, um diesen Nebeneffekt zu verhindern.

    int var0 = 0;
    const int &ptr1 = var0;
    ptr1 = 8; // Error
    var0 = 6; // OK
    
  2. Konstante Zeiger

    Sobald ein konstanter Zeiger auf eine Variable zeigt, kann er nicht auf eine andere Variable zeigen.

    int var1 = 1;
    int var2 = 0;
    
    int *const ptr2 = &var1;
    ptr2 = &var2; // Error
    
  3. Zeiger auf konstant

    Ein Zeiger, durch den man den Wert einer Variablen, auf die er zeigt, nicht ändern kann, ist als Zeiger auf die Konstante bekannt.

    int const * ptr3 = &var2;
    *ptr3 = 4; // Error
    
  4. Konstanter 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 Wert, der an dieser Adresse beibehalten wird.

    int var3 = 0;
    int var4 = 0;
    const int * const ptr4 = &var3;
    *ptr4 = 1;     // Error
     ptr4 = &var4; // Error
    

39
2018-05-17 20:21



Diese Frage zeigt genau warum ich gerne die Dinge so mache, wie ich es in meiner Frage erwähnt habe ist const nach Typ id akzeptabel?

Kurz gesagt, ich finde den einfachsten Weg, sich an die Regel zu erinnern, dass das "const" geht nach die Sache, für die es gilt. In Ihrer Frage bedeutet "int const *" also, dass das int konstant ist, während "int * const" bedeutet, dass der Zeiger konstant ist.

Wenn jemand entscheidet, es ganz vorne zu setzen (zB: "const int *"), dann gilt das als besondere Ausnahme für die Sache danach.

Viele Leute benutzen diese spezielle Ausnahme gerne, weil sie denken, dass sie schöner aussieht. Ich mag es nicht, weil es eine Ausnahme ist und somit Dinge verwirrt.


15
2017-07-17 13:52



Die allgemeine Regel ist, dass die const Das Schlüsselwort gilt für das, was ihm unmittelbar vorangeht. Ausnahme, ein Start const gilt für das Folgende.

  • const int* ist das gleiche wie int const* und Mittel "Zeiger auf Konstanten int".
  • const int* const ist das gleiche wie int const* const und Mittel "konstanter Zeiger auf konstantes int".

Bearbeiten: Für die Dos und Don'ts, wenn diese Antwort ist nicht genug, könnten Sie genauer sein, was Sie wollen?


14
2017-07-17 13:30



Einfache Verwendung von 'const'

Am einfachsten ist es, eine benannte Konstante zu deklarieren. Um dies zu tun, deklariert man eine Konstante so, als wäre sie eine Variable, aber füge 'const' davor hinzu. Man muss es sofort im Konstruktor initialisieren, da man den Wert natürlich später nicht setzen kann, da dies den Wert verändern würde. Beispielsweise,

const int Constant1=96; 

erstellt eine ganzzahlige Konstante, die einfallslos 'Constant1' genannt wird, mit dem Wert 96.

Solche Konstanten sind nützlich für Parameter, die im Programm verwendet werden, aber nicht geändert werden müssen, nachdem das Programm kompiliert wurde. Es hat einen Vorteil für Programmierer über den C-Präprozessor '#define' Befehl, da es vom Compiler selbst verstanden und verwendet wird, nicht nur durch den Präprozessor vor dem Erreichen des Hauptcompilers in den Programmtext eingefügt wird, so dass Fehlermeldungen viel hilfreicher sind .

Es funktioniert auch mit Zeigern, aber man muss vorsichtig sein, wo "const" zu bestimmen, ob der Zeiger oder was es zeigt, konstant ist oder beides. Beispielsweise,

const int * Constant2 

erklärt, dass Constant2 ein variabler Zeiger auf eine konstante Ganzzahl und ist

int const * Constant2

ist eine alternative Syntax, die das gleiche tut, während

int * const Constant3

erklärt, dass Constant3 ist ein konstanter Zeiger auf eine Variable Integer und

int const * const Constant4

erklärt, dass Constant4 ein konstanter Zeiger auf eine konstante Ganzzahl ist. Grundsätzlich gilt "const" für alles, was sich unmittelbar links befindet (außer wenn es dort nichts gibt, gilt es für das, was unmittelbar rechts ist).

Ref: http://duramecho.com/ComputerInformation/WhyHowCppConst.html


12
2017-07-17 13:31