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

Lesezeit: 11 Minuten

Ich vermassele immer, wie man benutzt const int*, const int * constund 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.

  • 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

Was ist der Unterschied zwischen const int const int
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.

  • Ich möchte eine Faustregel anhängen, die Ihnen helfen kann, sich daran zu erinnern, wie Sie feststellen können, ob ‘const’ für Zeiger oder für spitze Daten gilt: Teilen Sie die Anweisung am Sternzeichen auf, und wenn das Schlüsselwort const im linken Teil erscheint (wie in ‘const int * foo’) – es gehört zu punktierten Daten, wenn es im rechten Teil ist (‘int * const bar’) – es geht um den Zeiger.

    – Michael

    17. Juli 2009 um 17:26 Uhr

  • @Michael: Ein großes Lob an Michael für eine so einfache Regel zum Erinnern/Verstehen der const-Regel.

    – Shivabudh

    11. Februar 2010 um 19:00 Uhr

  • @ Jeffrey: Rückwärts lesen funktioniert gut, solange keine Klammern vorhanden sind. Nun gut… Typedefs verwenden

    – Muhende Ente

    28. Mai 2013 um 19:53 Uhr


  • +1, obwohl eine bessere Zusammenfassung wäre: Zeigerdeklarationen rückwärts lesendas heißt, in der Nähe von @Michaels Aussage: Stoppen Sie das normale Lesen von links nach rechts am Erste Sternchen.

    – Wolf

    18. Juni 2014 um 9:21 Uhr


  • @gedamial tut es, es funktioniert gut, aber Sie müssen es gleichzeitig zuweisen, wenn Sie es deklarieren (weil Sie einen “const pointer” nicht neu zuweisen können). const int x = 0; const int *const px = &x; const int *const *const p = &px; funktioniert prima.

    – RastaJedi

    8. August 2016 um 23:15 Uhr

1647297013 807 Was ist der Unterschied zwischen const int const int
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:

Zeiger auf int

const Zeiger auf int const

Zeiger auf int const

Zeiger auf const int

konstanter Zeiger auf int

  • @Jan der Link für das komplexe Beispiel hat keine Berechtigungen. Können Sie es direkt hier posten oder die Anzeigebeschränkungen aufheben?

    – R71

    8. April 2016 um 12:03 Uhr

  • @Rog Früher hatte es alle Open-Access-Berechtigungen … Ich habe den Artikel nicht geschrieben und habe leider selbst keine Zugriffsberechtigungen. Hier ist jedoch eine archivierte Version des Artikels, die immer noch funktioniert: archive.is/SsfMX

    – Jan Rüegg

    8. April 2016 um 13:34 Uhr

  • Das komplexe Beispiel ist immer noch von rechts nach links, enthält aber das Auflösen von Klammern, wie man es normalerweise tun würde. Die ganze Sache mit der Spirale im Uhrzeigersinn macht das nicht einfacher.

    – Matthäus Lesen

    18. September 2016 um 23:04 Uhr

  • Ultimatives Beispiel: void (*signal(int, void (*fp)(int)))(int); von archive.is/SsfMX

    – NaXa

    3. Mai 2017 um 19:04 Uhr

  • Verlassen Sie sich nicht auf diese Regel. Dies ist nicht universell. Es gibt einige Fälle, in denen es fehlschlägt.

    – Hacken

    12. Mai 2017 um 7:17 Uhr

Was ist der Unterschied zwischen const int const int
Kaz-Drache

Ich denke, hier ist bereits alles beantwortet, aber ich möchte nur hinzufügen, dass Sie sich hüten sollten typedefS! Sie sind NICHT nur Textersetzungen.

Zum Beispiel:

typedef char *ASTRING;
const ASTRING astring;

Die Art von astring ist char * constnicht const char *. Dies ist ein Grund, warum ich immer dazu neige, zu sagen const rechts vom Typ und niemals am Anfang.

  • Und für mich ist das der Grund, Zeiger nie zu typedef. Ich sehe keinen Vorteil in Dingen wie typedef int* PINT (Ich nehme an, es ist etwas, das aus Praktiken in C stammt, und viele Entwickler haben es weiter gemacht). Super, das habe ich ausgetauscht * mit einer Pes beschleunigt das Tippen nicht und führt das von Ihnen erwähnte Problem ein.

    – Mephane

    28. Januar 2011 um 13:01 Uhr

  • @Mephane – das sehe ich. Mir erscheint es jedoch irgendwie rückwärtsgewandt, eine nette Sprachfunktion zu vermeiden, um weiterhin eine außergewöhnliche syntaktische Regel (über die Platzierung von “const”) zu verwenden, anstatt die außergewöhnliche syntaktische Regel zu vermeiden, damit Sie diese Sprachfunktion sicher nutzen können .

    – TED

    17. Oktober 2012 um 14:06 Uhr


  • @Mephane PINT ist in der Tat eine ziemlich dumme Verwendung einer Typedef, insbesondere weil ich denke, dass die Systemspeicher Bier für den Speicher verwenden. typedef s sind jedoch ziemlich nützlich für den Umgang mit Zeigern auf Funktionen.

    – Annäherung an DarknessFish

    26. Dezember 2013 um 21:07 Uhr

  • @KazDragon DANKE! Ohne sie hätte ich all diese Typdefinitionen durcheinander gebracht PVOID, LPTSTR Zeug in der Win32-API!

    – David Lee

    8. Mai 2014 um 12:29 Uhr


  • @Mephane: Ich musste pSomething ein paar Mal verwenden, wenn ich bestimmte Legacy-Makros verwendete, die geschrieben wurden, um einen Typ zu akzeptieren, aber auseinanderbrechen würden, wenn der Typ kein einzelner alphanumerischer Bezeichner wäre. 🙂

    – Groo

    8. Mai 2017 um 16:37 Uhr

1647297016 432 Was ist der Unterschied zwischen const int const int
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.

Was ist der Unterschied zwischen const int const int
Behrooz Tabesh

  1. 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
    
  2. 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
    
  3. 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
    
  4. 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
    

1647297017 531 Was ist der Unterschied zwischen const int const int
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?

1647297017 11 Was ist der Unterschied zwischen const int const int
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.

  • Ich bin bei diesem Thema hin- und hergerissen. Logisch macht es Sinn. Die meisten C++-Entwickler würden jedoch schreiben const T* und es ist natürlicher geworden. Wie oft benutzt du jemals a T* const Wie auch immer, normalerweise reicht eine Referenz aus. Ich wurde von all dem einmal gebissen, als ich einen wollte boost::shared_ptr<const T> und schrieb stattdessen const boost::shared_ptr<T>. Gleiches Problem in etwas anderem Kontext.

    – Matt Preis

    17. Juli 2009 um 14:08 Uhr

  • Tatsächlich verwende ich häufiger konstante Zeiger als Konstanten. Außerdem muss man sich überlegen, wie man auf Pointer auf Pointer (usw.) reagiert. Zugegebenermaßen sind die seltener, aber es wäre schön, so zu denken, dass man mit solchen Situationen souverän umgehen kann.

    – TED

    17. Juli 2009 um 14:19 Uhr

  • Der andere nette Vorteil, const rechts vom Typ zu platzieren, ist, dass jetzt alles links von any steht const ist der Typus dessen, was konstant ist, und alles rechts davon ist das, was tatsächlich konstant ist. Nehmen int const * const * p; als Beispiel. Nein, ich schreibe normalerweise nicht so, das ist nur ein Beispiel. Zuerst const: Geben Sie int ein, und das int, das const ist, ist der Inhalt des const-Zeigers, der der Inhalt von ist p. Zweite Konstante: Typ ist Zeiger auf const int, const oblect ist der Inhalt von p

    – dgnuff

    15. März 2018 um 7:18 Uhr

1003320cookie-checkWas ist der Unterschied zwischen const int*, const int * const und int const *?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy