Ist es sicher, argc und argv in der Hauptfunktion umzubenennen?


82

Viele Programme verwenden Standardnamen für eine Reihe von Argumenten und Zeichenfolgenarrays. Der Prototyp der Hauptfunktion sieht aus wie : int main(int argc, char *argv[]);. Aber würde ich etwas kaputt machen, wenn ich benutzerdefinierte Namen für diese Variablen wähle?

Z.B int main(int n_of_args, char *args[]);

Im Kontext des Compilers ist alles in Ordnung. Diese Variablen sind für die Hauptfunktion lokal, daher können sie beliebige Namen haben. Und der einfache Code baut und läuft perfekt. Diese Namen können jedoch vom Präprozessor verwendet werden. Ist es also sicher, diese Argumente umzubenennen?

PS Persönlich finde ich diese Namen schlecht, weil sie sehr ähnlich aussehen und sich nur in einem Buchstaben unterscheiden. Aber JEDER benutzt sie aus irgendeinem Grund.


21
Ja, völlig sicher.
David Hoelzer

55
Wie alle Antworten sagen, ja, es ist sicher. Aber bitte tu das nicht. Jeder weiß was argcund argvist. n_of_argsund argskönnte für jemanden klarer sein, der C oder C ++ nicht kennt - aber das ist nicht Ihr Publikum.
Keith Thompson

4
Sie können dies tun, es ist nicht genug Grund, dies zu tun. Jeder weiß, was das sind, und sie erwarten, dass sie so sind.
SergeyA

10
Wenn die Frage genau lautet "Würde ich etwas brechen, wenn ich benutzerdefinierte Namen wähle", lautet die genaue Antwort "Ja, Sie würden die gut etablierte Tradition brechen";)
Frax

12
Dreh sie einfach um! .. und von Anfang an legen Sie einen Grundstein für die Arbeitsplatzsicherheit :)
Yano

Antworten:


121

Ja, es ist sicher, solange Sie gültige Variablennamen verwenden. Es handelt sich um lokale Variablen, sodass ihr Gültigkeitsbereich nicht über die mainFunktion hinausgeht .

Aus Abschnitt 5.1.2.2.1 des C-Standards :

Die beim Programmstart aufgerufene Funktion wird benannt main. Die Implementierung deklariert keinen Prototyp für diese Funktion. Es muss mit einem Rückgabetyp von intund ohne Parameter definiert werden:

int main(void) { /*  ... */ }

oder mit zwei Parametern (hier als argcund bezeichnet argv, obwohl beliebige Namen verwendet werden können, da sie lokal für die Funktion sind, in der sie deklariert sind ):

int main(int argc, char *argv[]) { /* ...   */ }

oder gleichwertig; oder auf eine andere implementierungsdefinierte Weise

Abgesehen davon, wenn Sie etwas anderes als verwenden argcund argvandere verwirren, die Ihren Code lesen und an die herkömmlichen Namen für diese Parameter gewöhnt sind. Also besser auf der Seite der Hellsichtigkeit irren.


38

Die Namen argcund argvwurden tatsächlich vom C ++ - Standard vor C ++ 11 vorgeschrieben. Es hieß:

Alle Implementierungen müssen beide der folgenden Definitionen von main zulassen:

int main ()

und

int main ( int argc , char * argv [])

und fuhr fort, die Anforderungen an argcund zu diskutieren argv.

Technisch gesehen war jedes Programm mit unterschiedlichen Namen nicht standardkonform, und der Compiler durfte es ablehnen. Natürlich hat das kein Compiler getan. Siehe diesen Thread in comp.std.c ++ oder Abschnitt 3.6.1 dieses C ++ 03-Standardentwurfs .

Dies war mit ziemlicher Sicherheit nur ein Versehen und wurde in C ++ 11 geändert, was stattdessen besagt

Alle Implementierungen müssen beides zulassen

  • eine Funktion von () Rückgabe intund
  • eine Funktion von ( int, Zeiger auf Zeiger auf char) Rückgabeint

als Typ von main(8.3.5). In der letzteren Form wird zum Zwecke der Darstellung der erste Funktionsparameter argcund der zweite Funktionsparameter aufgerufen argv,…


29

Natürlich können Sie diese Parameter sicher umbenennen , wie Sie möchten

 int main(int wrzlbrnft, char* _42[]) {
 }

Namen sind in Sand geschrieben. Sie haben keinen Einfluss auf den endgültig kompilierten Code.


Das einzige, was zählt, ist, dass die Parametertypen Deklaration und Definition tatsächlich übereinstimmen.

Die Signatur der main()Funktion wird als deklariert

 int main(int, char*[]);

Wenn Sie sie tatsächlich in einer Implementierung verwenden müssen, müssen Sie sie benennen. Welche Namen verwendet werden, ist, wie bereits erwähnt, eigentlich irrelevant.


5
nur einige Bezeichner sind "in den Sand geschrieben", wie Sie es ausdrücken. Funktionsnamen sind es sicherlich nicht.
Steve Cox

1
@SteveCox "Funktionsnamen sind es sicherlich nicht." Am Ende sind sie. Nur die Anzahl der Sandkörner :-P ...
πάντα ῥεῖ

3
ok aber ernst Nach der Kompilierung enthält der Objektcode noch Funktionsnamen. Andernfalls würde das Verknüpfen nicht funktionieren
Steve Cox

4
@ πάνταῥεῖ: Wenn Sie keine besonderen Anstrengungen unternehmen, um sie zu entfernen, bleiben die Funktionsnamen in der endgültigen ausführbaren Datei erhalten.
Nick Matteo

1
@ Kundor: Nach dem Verknüpfen unter Windows behalten alle nicht speziellen Funktionen die Namen nicht bei
Dani

15

Ja. Es ist sicher, es sieht komisch aus, aber es wird nichts kaputt machen.


7

Ja, es ist sicher, unterschiedliche Namen zu verwenden.

Persönlich würde ich es jedoch nicht empfehlen, da es traditionell ist argcund argvjedem anderen C-Programmierer, der jemals mit Ihrem Code arbeiten könnte, so bekannt und vertraut ist. Auf lange Sicht wird die Verwendung Ihrer eigenen, speziellen, unterschiedlichen Namen bei Ihren Lesern weitaus mehr Verwirrung und / oder Frustration hervorrufen, als es Sie jemals retten wird, weil Sie Ihre Namen besser mögen.

"Wenn du in Rom bist, mach wie es die Römer tun."


Es gibt jedoch nur wenige ganz offensichtliche Szenarien, in denen unterschiedliche Namen verwendet werden müssen. Eine berüchtigte ist die Initialisierung von GLUT, glutInit(&argc, argv)bei der die Argumente unterschiedlich deklariert und initialisiert werden müssen, damit GLUT keine Befehlszeilenargumente auffrisst, es sei denn, wir möchten dies. SO Link
Benutzer3078414

@ user3078414 Interessantes Beispiel, aber ich sehe nicht, wie es etwas darüber aussagt, wie die Variablen benannt werden müssen. Nach den Beispielen in dieser anderen Frage könnten wir genauso leicht schreiben int dummyargc = 1; char *dummyargv[1] = {(char*)"Something"}; glutInit(&dummyargc, dummyargv);.
Steve Summit

Danke, @ Steve-Summit. Einige API-Dokumentationen sind irreführend, daher ist dieser Thread am hilfreichsten, um die argc argvNamenskonvention hervorzuheben , ebenso wie Ihre Antwort. Ich habe nur meinen Kommentar als Beispiel dafür angeführt, vorzugsweise unterschiedliche Namen zu verwenden. Hier ist der SO-Link
user3078414

5

Ja, Sie können sie nach Belieben umbenennen. Sie sind einfach Funktionsparameternamen, nichts weiter.


3

Ich habe das Gefühl, dass jeder die technischen C ++ - Regeln gut und gut behandelt hat: Die Antwort lautet ja. Lassen Sie uns die Tradition und die Tatsache beiseite legen, dass diese eine bestimmte Funktion speziell und ikonisch ist und gültige Punkte enthält, die sich auf dieser Grundlage nicht ändern dürfen.

Oft habe ich das Gefühl, dass die Philosophie der Entscheidungen selten diskutiert wird, und wollte daher eine Perspektive auf diese Angelegenheit bieten, da ich es für wichtig halte, warum dies von Anfang an verlangt wurde.

Diese Frage beinhaltet für mich die Wahl, Englisch im Code im Allgemeinen auszudrücken. Sie scheinen von Kurzhandbeschreibungen gestört zu sein, insbesondere wenn die Kurzhand einen ähnlich aussehenden Text enthält. In Ihrem Beispiel bewirkt das Ändern von argn in n_of_args jedoch nur das Ändern eines Typs einer kurzen Hand in eine andere Form der Kurzschrift ohne wirklichen Mehrwert: Klarstellung oder andere sichtbare Eigenschaften.

Das Wort 'Nummer' wurde durch einen Buchstaben 'n' ersetzt.

Wenn Sie einen Kurzhandnamen über die Philosophie der Anti-Kurzhand ändern, erscheint so etwas möglicherweise angemessener:

main (int argumentCount, char ** argumentVector)

Ich denke immer an zwei Dinge: Dinge nach dem zu benennen, was sie sind und / oder nach ihrer impliziten Verwendung. Es als argumentVector zu bezeichnen, ist für mich überflüssig, da die Eigenschaft, ein Vektor zu sein, durch die doppelte Indirektion ** impliziert wird. Eine bessere lange Hand für das Schreiben von Code ist daher: ** Argumente.

Einige würden sagen, dass die Variable argumentCount als int deklariert ist und ein Count nicht negativ sein kann, aber Sie können ein negatives int haben {unsigned is better}.

Auch hier spielt es eine Rolle, was es ist und wie es verwendet wird. Wenn es eine Zählung ist, würde ich annehmen, dass es niemals negativ sein würde. Wie kann man denn eine Anzahl von -2 Äpfeln haben? Ich würde sagen, Sie schulden zwei Äpfel. Wenn es eine Zahl ist, würde ich erwarten, dass ein negativer Fall möglich ist. Aus diesem Grund ist Ihnen das zusätzliche Wort "von" wahrscheinlich wichtig. Dies und möglicherweise eine Nummer, auf die sich eine Sammlung bezieht, impliziert eher einen bestimmten Gegenstand als eine Eigenschaft der Sammlung selbst. Dh: rulesNumber = 5 impliziert ein bestimmtes Argument, jedoch nicht numberOfArguments.

main (int maxArgumentsIndex, char ** Argumente).

Dies beseitigt Mehrdeutigkeiten. Wenn Sie es als Index bezeichnen, werden negative Mehrdeutigkeiten in Groß- und Kleinschreibung beseitigt und es wird beschrieben, was es ist und wie es zusätzlich verwendet wird. Der englische Wortlaut impliziert auch, dass ein Maximum ein Absolutwert ist und sich seltsam anfühlt, wenn man Code schreibt, der diesen Wert ändert (es sollte const sein). 'Argumente' sind hier sinnvoll, da es Plural ist, beschreibt, was es ist und wie es bereits verwendet werden sollte. Selbst eine solche Interpretation kann gefährlich sein, da ein Index -1 von Count / NumberOf ist. 5 Argumente ergeben einen maxIndex von 4 !!

Jede andere Funktion und ich würde komplett nutzen:

void-Funktion (const unsigned int maxArgumentsIndex, const char ** Argumente)

Nicht alle Situationen verdienen lange Handbeschreibungen. In der Tat bietet eine kurze Hand manchmal eine bessere Lesbarkeit, insbesondere beim Schreiben von Mathematikklassen wie Vec3f, Matrix, Quaternion usw. Ich werde fast immer versuchen, eher die mathematische als die sprachliche Sprache zu finden . float x, y, z vrs. float xComponent und dergleichen.

Ich verstehe, dass all dies eine Stilwahl ist, aber sich der Wahl bewusst zu sein, wird auf lange Sicht wirklich helfen. Ich garantiere, dass erfahrene Programmierer sich Sorgen machen, wenn Arrays nicht im Plural geschrieben werden, aber andererseits ist main eine spezielle Prosa der Existenz;)


2

Gemäß C-Standards können Sie umbenennen. Es wird keine Auswirkungen haben. Wie ich verstanden habe, wurden in C-Sprache die Standardnamen für Schlüsselwörter / Typen / Token mit Zweck / Verwendung definiert, also sind es auf die gleiche Weise definierte Namen

argc --> argument count

argv --> argument vector

Das ist auch in Bezug auf die Verwendung sinnvoll, so dass Sie zu jedem Namen ändern können, den Sie erwarten Reserved names

In GCC beginnt die Programmausführung mit dem Funktionsnamen main , der nicht von seinen Parametern abhängt.

Wenn Sie ein eigenständiges Programm für Mikrocontroller schreiben, müssen Sie sich nicht um den Namen kümmern, mainsondern können Ihren eigenen definierenname Mikrocontroller kümmern, und den Assembly-Einstiegspunkt so ändern, dass er auf Ihre Funktion verweist. Dies hängt vom Controller-Compiler und der Verfügbarkeit des vordefinierten Controller-Quellcodes ab. Ich habe dies in Freescale Controller unter Code-Warrior gemacht.

Meine Anmerkung:

Es ist besser, den allgemeinen Standards / Codestilen zu folgen, um Code sichtbarer und lesbarer zu machen


0

Für den Compiler ist es sicher.

Das einzige Problem, das dies verursachen kann, ist Verwirrung. Personen, die Ihren Code lesen, erwarten, dass diese beiden Variablen ihre Standardnamen haben. Sie könnten sogar so etwas tun:

int main(int foo, char ** bar)
{
    int argc;
    float argv;

Aber ich glaube nicht, dass ich sagen muss, wie schlecht das wäre.


-1

Wenn Ihnen die Variablennamen nicht gefallen, können Sie sie durch das Makro #define ersetzen :

#define yourCounterName argc
#define yourVectorName  argv 

Sie gehen kein Risiko ein und produzieren eine "saubere Lösung".


Das sind keine Konstanten, nur Substitution.
David Dunham
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.