Ich führe einige Beispielprogramme durch, um mich mit C ++ vertraut zu machen, und bin auf die folgende Frage gestoßen. Hier ist zunächst der Beispielcode:
void print_string(const char * the_string)
{
cout << the_string << endl;
}
int main () {
print_string("What's up?");
}
Im obigen Code könnte stattdessen der Parameter für print_string gewesen sein const char * const the_string
. Welches wäre dafür richtiger?
Ich verstehe, dass der Unterschied darin besteht, dass einer ein Zeiger auf ein konstantes Zeichen ist, während der andere ein konstanter Zeiger auf ein konstantes Zeichen ist. Aber warum funktionieren beide? Wann wäre es relevant?
const char *
ist viel besser, weil dasconst
auf der gegenüberliegenden Seite ist.Veränderbarer Zeiger auf ein veränderliches Zeichen
Veränderbarer Zeiger auf ein konstantes Zeichen
Konstanter Zeiger auf ein veränderliches Zeichen
Konstanter Zeiger auf ein konstantes Zeichen
quelle
const char* p; --> constant pointer to mutable character
undchar *const p; --> mutable pointer to constant character
const char * p
als: "p ist ein Zeiger auf eine Zeichenkonstante" oder ein veränderlicher Zeiger auf ein konstantes Zeichen, wie James korrekt angibt. das gleiche mit dem zweiten :).const char * const
Mittel Zeiger sowie die Daten der Zeiger zeigt auf, sind beide konst!const char *
bedeutet, dass nur die Daten, auf die der Zeiger zeigt, const sind. Zeiger selbst ist jedoch nicht const.Beispiel.
quelle
(Ich weiß, dass dies alt ist, aber ich wollte es trotzdem teilen.)
Ich wollte nur auf Thomas Matthews Antwort eingehen. Die Rechts-Links-Regel für C-Typ-Deklarationen besagt ziemlich genau: Wenn Sie eine C-Typ-Deklaration lesen, beginnen Sie am Bezeichner und gehen Sie nach rechts, wenn Sie können, und nach links, wenn Sie nicht können.
Dies lässt sich am besten anhand einiger Beispiele erklären:
Beispiel 1
Beginnen Sie an der Kennung, wir können nicht nach rechts gehen, also gehen wir nach links
foo ist eine Konstante ...
Weiter links
foo ist ein ständiger Zeiger auf ...
Weiter links
foo ist ein konstanter Zeiger auf char ...
Weiter links
foo ist ein konstanter Zeiger auf die char- Konstante (Complete!)
Beispiel 2
Beginnen Sie an der Kennung, wir können nicht nach rechts gehen, also gehen wir nach links
foo ist eine Konstante ...
Weiter links
foo ist ein ständiger Zeiger auf ...
Weiter links
foo ist ein konstanter Zeiger auf char (Complete!)
Beispiel 1337
Beginnen Sie an der Kennung, aber jetzt können wir richtig gehen!
foo ist ein Array von 8 ...
Drücken Sie die Klammer, damit Sie nicht mehr nach rechts und nach links gehen können
foo ist ein Array von 8 Zeigern auf ...
Fertig in Klammern, kann jetzt nach rechts gehen
foo ist ein Array von 8 Zeigern auf eine Funktion, die ...
Nichts mehr rechts, geh nach links
foo ist ein Array von 8 Zeigern auf eine Funktion, die einen Zeiger auf eine ...
Weiter links
foo ist ein Array von 8 Zeigern auf Funktionen, die einen Zeiger auf eine Konstante zurückgeben ...
Weiter links
foo ist ein Array von 8 Zeigern auf Funktionen, die einen Zeiger auf einen konstanten Zeiger auf ...
Weiter links
foo ist ein Array von 8 Zeigern auf Funktionen, die einen Zeiger auf einen konstanten Zeiger auf ein Zeichen zurückgeben ...
Weiter links
foo ist ein Array von 8 Zeigern auf Funktionen, die einen Zeiger auf einen konstanten Zeiger auf eine char- Konstante zurückgeben (Complete!)
Weitere Erklärung: http://www.unixwiz.net/techtips/reading-cdecl.html
quelle
Viele Leute schlagen vor, den Typspezifizierer von rechts nach links zu lesen.
In beiden Formen zeigt der Zeiger auf konstante oder schreibgeschützte Daten.
In der zweiten Form kann der Zeiger nicht geändert werden. Der Zeiger zeigt immer auf dieselbe Stelle.
quelle
Der Unterschied besteht darin, dass
const
der Programmierer ohne das Extra innerhalb der Methode ändern kann, auf die der Zeiger zeigt. beispielsweise:Das wäre stattdessen illegal, wenn die Unterschrift wäre
void print_string(const char * const the_string)
Viele Programmierer empfinden das zusätzliche
const
Schlüsselwort (in den meisten Szenarien) als zu ausführlich und lassen es weg, obwohl es semantisch korrekt wäre.quelle
In letzterem Fall garantieren Sie, dass sowohl der Zeiger als auch das Zeichen nicht geändert werden. Im ersten Fall garantieren Sie nur, dass sich der Inhalt nicht ändert, aber Sie können den Zeiger bewegen
quelle
Es gibt keinen Grund, warum einer von beiden nicht funktionieren würde. Alles
print_string()
tun müssen, ist den Wert auszudrucken. Es wird nicht versucht, es zu ändern.Es ist eine gute Idee, eine Funktion zu erstellen, die Markierungsargumente nicht als const ändert. Der Vorteil ist, dass Variablen, die sich nicht ändern können (oder die Sie nicht ändern möchten), fehlerfrei an diese Funktionen übergeben werden können.
In Bezug auf die genaue Syntax möchten Sie angeben, welche Art von Argumenten "sicher" sind, um an die Funktion übergeben zu werden.
quelle
Ich denke, es ist selten relevant relevant, weil Ihre Funktion nicht mit Argumenten wie & * the_string oder ** the_string aufgerufen wird. Der Zeiger selbst ist ein Argument vom Typ Wert. Selbst wenn Sie ihn ändern, werden Sie die Kopie, die zum Aufrufen Ihrer Funktion verwendet wurde, nicht ändern. Die Version, die Sie anzeigen, stellt sicher, dass sich die Zeichenfolge nicht ändert, und ich denke, das ist in diesem Fall ausreichend.
quelle
const char *
bedeutet, dass Sie den Zeiger nicht verwenden können, um zu ändern, auf was gezeigt wird. Sie können den Zeiger jedoch so ändern, dass er auf etwas anderes zeigt.Erwägen:
Der Parameter ist ein nicht
const char *
konstanter Zeiger auf const char, sodass er in einen anderen Wert geändert werden kann (wie eine konstante Zeichenfolge). Wenn wir jedoch fälschlicherweise geschrieben haben*text = '\0'
haben, wird ein Kompilierungsfehler angezeigt.Wenn Sie nicht beabsichtigen, zu ändern, auf was der Parameter zeigt, können Sie den Parameter möglicherweise festlegen, dies ist
const char * const text
jedoch nicht üblich. Normalerweise erlauben wir Funktionen, die an Parameter übergebenen Werte zu ändern (da wir Parameter nach Wert übergeben, wirkt sich jede Änderung nicht auf den Aufrufer aus).Übrigens: Es ist eine gute Praxis, dies zu vermeiden,
char const *
da es oft falsch verstanden wird - es bedeutet dasselbe wieconst char *
, aber zu viele Leute lesen es als Bedeutungchar * const
.quelle
const char *
und der Unterschrift herauszufindenchar const *
- die Art und Weise, wie Sie Ihre BTW formuliert haben, hat wirklich geholfen!Fast alle anderen Antworten sind korrekt, aber sie übersehen einen Aspekt davon: Wenn Sie das Extra
const
für einen Parameter in einer Funktionsdeklaration verwenden, ignoriert der Compiler es im Wesentlichen. Lassen Sie uns für einen Moment die Komplexität Ihres Beispiels als Zeiger ignorieren und einfach einen verwendenint
.deklariert die gleiche Funktion wie
Nur in der Definition der Funktion ist das besonders
const
aussagekräftig:Diese Definition ist mit einer der obigen Erklärungen vereinbar. Der Anrufer ist es egal, dass
x
istconst
ein Implementierungsdetail, das am Anrufort nicht relevant ist.Wenn Sie einen
const
Zeiger aufconst
Daten haben, gelten dieselben Regeln:Nur wenige C ++ - Programmierer machen sich die Mühe, Parameter zu
const
erstellen, selbst wenn dies möglich ist, unabhängig davon, ob diese Parameter Zeiger sind.quelle
const
zu Ihrem Funktionsparameter in der Definition hinzufügen, aber keine Deklaration.Der Unterschied zwischen den beiden besteht darin, dass char * auf einen beliebigen Zeiger zeigen kann. Const char * verweist dagegen auf Konstanten, die im Abschnitt DATA der ausführbaren Datei definiert sind. Daher können Sie die Zeichenwerte einer const char * -String nicht ändern.
quelle
const char*
kann überall hin zeigen, wo es gefällt.