int main( const int argc , const char[] const argv)
Da in Effective C ++ Item # 3 "Const wann immer möglich verwenden" angegeben ist, denke ich: "Warum nicht diese 'konstanten' Parameter const
festlegen?".
Gibt es ein Szenario, in dem der Wert von argc
in einem Programm geändert wird?
argc
als deklarierenconst
.--argc
const
. Übergebenargc
alsconst int
Mittel, das Sie dannargc
beispielsweise nicht als Zähler innerhalb der Funktion verwenden können.const
ein Parameter zum Übergeben von Werten erstellt wird. Siehe z. B. stackoverflow.com/a/8714278/277304 und stackoverflow.com/a/117557/277304Antworten:
In diesem Fall ist die Geschichte ein Faktor. C definierte diese Eingaben als "nicht konstant", und die Kompatibilität mit (einem guten Teil) des vorhandenen C-Codes war ein frühes Ziel von C ++.
Einige UNIX-APIs, wie z. B.
getopt
, manipulieren tatsächlichargv[]
, sodass sie auch ausconst
diesem Grund nicht erstellt werden können .(Nebenbei: Interessanterweise gibt die Linux-Manpage an, dass ihre Argumente durchlässig sind , obwohl
getopt
der Prototyp vorschlägt, dass sie nicht geändert werden,argv[]
aber möglicherweise die Zeichenfolgen modifiziert, auf die verwiesen wirdgetopt
, und es scheint, dass sie wissen, dass sie ungezogen sind . Die Manpage beim Öffnen Die Gruppe erwähnt diese Permutation nicht.)Putting
const
aufargc
undargv
würde sich nicht viel kaufen, und es würde einige der alten Schule Programmierpraktiken ungültig machen , wie zum Beispiel:Ich habe solche Programme in C geschrieben und weiß, dass ich nicht allein bin. Ich habe das Beispiel von irgendwoher kopiert .
quelle
const
zuargv
, ohne dass dies zu Auswirkungen , was jede C - Funktion tun. Auchgetopt
wird als deklariertint getopt(int argc, char * const argv[], const char *optstring);
. Und hierconst
ist das nicht die oberste Ebene, sondern deklariert die Zeiger alsconst
Versprechen, sie nicht zu ändern (obwohl die Zeichenfolgen, auf die sie zeigen, möglicherweise geändert werden).getopt
Permutiert dasargv[]
Array standardmäßig, ändert jedoch nicht die Zeichenfolgen. (Das Wort permute stammt direkt von der Manpage.) Das bedeutet, dass dasargv
Array selbst nichtconst
einmal die Zeichenfolgen enthält, auf die es zeigt. Wie manipuliert das Permutieren desargv[]
Arrays es nicht ?char* const* ___argv
dort, aber die Schnittstelle haftet tatsächlichconst char **
. Solche Verwirrung. Ich hatte den Vorrang des[]
und des*
in Bezug auf das verwechseltconst
. Entschuldigen Sie.Die C-Norm (ISO / IEC 9899: 2011) lautet:
Beachten Sie den letzten Aufzählungspunkt. Es heißt, dass beide
argc
undargv
modifizierbar sein sollten. Sie müssen nicht geändert werden, können aber geändert werden.quelle
QApplication(argc,argv)
Konstruktor von Qt als Referenz definiertargc
wurde . Das hat mich überrascht.argc
ist normalerweise keine Konstante, da die Funktionssignatur fürmain()
Pre-Datesconst
.Da argc eine Stapelvariable ist, wirkt sich das Ändern nur auf Ihre eigene Befehlszeilenverarbeitung aus.
Es steht Ihnen natürlich frei, dies zu deklarieren,
const
wenn Sie möchten.quelle
Eine oberste Ebene
const
eines formalen Arguments ist nicht Teil des Funktionstyps. Sie können es nach Belieben hinzufügen oder entfernen: Es wirkt sich nur darauf aus, was Sie mit dem Argument in der Funktionsimplementierung tun können.So
argc
können Sie frei hinzufügen, fügen Sie einconst
.Aber für
argv
Sie können Sie die Zeichendaten nicht erstellen,const
ohne dabei die Funktionssignatur zu ändern. Dies bedeutet, dass es sich dann nicht um eine der Standardfunktionssignaturenmain
handelt und nicht alsmain
Funktion erkannt werden muss. Also keine gute Idee.Ein guter Grund dafür, die Standardargumente
main
in Nicht-Spielzeug-Programmen nicht zu verwenden, ist, dass sie in Windows keine tatsächlichen Programmargumente wie Dateinamen mit internationalen Zeichen darstellen können. Das liegt daran, dass sie in Windows nach sehr starker Konvention als Windows ANSI codiert sind. In Windows können Sie in Bezug auf dieGetCommandLine
API-Funktion eine portablere Argumentzugriffsfunktion implementieren .Zusammengefasst, nichts hindert Sie daran , das Hinzufügen
const
zuargc
, aber die nützlichsteconst
-ness aufargv
würde Ihnen eine Nicht-Standard -main
Funktion, höchstwahrscheinlich nicht als solche erkannt. Glücklicherweise (auf ironische Weise) gibt es gute Gründe, den Standard nicht zu verwendenmain
Standardargumente für tragbaren ernsthaften Code. Ganz einfach, für die Praxis unterstützen sie nur alte ASCII mit nur englischen Buchstaben.quelle
main
funktioniert die Standardsignatur einwandfrei und Sie können beliebige Unicode-Argumente empfangen.Die Signatur von
main
ist so etwas wie ein historisches Artefakt ausC
. HistorischC
nicht hatteconst
.Sie können Ihren Parameter jedoch deklarieren,
const
da die Auswirkungen von const nur die Kompilierungszeit sind.quelle
const
wurde zu C89 / C90 hinzugefügt; Zuvor war es nicht Teil von C.Weil
argc
es sich um eine lokale Variable handelt (und in C ++ nicht um eine Referenz oder etwasmain
anderes ) und weil der besondere Ort bedeutet, dass Abwärtskompatibilitäts-Spielereien ihr einen enormen Spielraum gewähren, ohne zwingenden Grund, Anwendungen zu zwingen , sie konstant zu machen.Diese und viele andere Variationen werden auf einer Vielzahl von C- und C ++ - Compilern kompiliert.
Letztendlich ist es also nicht so, dass argc nicht const ist, nur dass es nicht sein muss, aber es kann sein, wenn Sie es wollen.
http://ideone.com/FKldHF , C Beispiel:
http://ideone.com/m1qc9c , C ++ Beispiel
quelle
-std=c++11
. Clang akzeptiert es ebenfalls, gibt es aberwarning: only one parameter on 'main' declaration [-Wmain]
und MSVC protestiert nur gegen den fehlenden Rückgabetyp-Spezifizierer und das Fehlen eines Verweises auf argc. Wieder 'Shenanigans' und 'Spielraum' :)Abgesehen von den historischen Gründen ist ein guter Grund, argc und argv nicht beizubehalten,
const
dass die Compiler-Implementierung nicht weiß, was Sie mit den Argumenten für main tun werden. Sie weiß nur, dass sie Ihnen diese Argumente geben muss.Wenn Sie Ihre eigenen Funktionen und zugehörigen Prototypen definieren, wissen Sie, welche Parameter Sie vornehmen können
const
und welche Ihre Funktion ändern wird.Im Extremfall könnten Sie deklarieren, dass alle Parameter für alle Funktionen deklariert werden
const
sollen. Wenn Sie dann einen Grund hätten, sie zu ändern (z. B. einen Index dekrementieren, um ein Array zu durchsuchen), müssten Sie lokale Nichtvariablenconst
erstellen und kopieren Sie dieconst
Werte der Argumente in diese Variablen. Das sorgt für viel Arbeit und zusätzliches LOC ohne wirklichen Nutzen. Ein anständiger statischer Analysator erkennt, wenn Sie den Wert eines Arguments nicht ändern, und empfiehlt, den Parameter festzulegenconst
.quelle