Initialisieren von Variablen in C

Lesezeit: 7 Minuten

Benutzer-Avatar
Arthur Collé

Ich weiß, dass manchmal, wenn Sie eine nicht initialisieren interhalten Sie eine Zufallszahl, wenn Sie die Ganzzahl drucken.

Aber alles auf Null zu initialisieren scheint irgendwie albern zu sein.

Ich frage, weil ich mein C-Projekt kommentiere und ziemlich direkt auf die Einrückung bin und es vollständig kompiliert (90/90 danke Stackoverflow), aber ich möchte 10/10 auf die Stilpunkte bekommen.

Also die Frage: Wann ist es angebracht zu initialisieren und wann sollte man einfach eine Variable deklarieren:

int a = 0;

vs.

int a;

Es gibt mehrere Umstände, in denen Sie sollte nicht eine Variable initialisieren:

  1. Wenn es eine statische Speicherdauer hat (static Schlüsselwort oder globale Variable) und Sie möchten, dass der Anfangswert Null ist. Die meisten Compiler speichern tatsächlich Nullen in der Binärdatei, wenn Sie explizit initialisieren, was normalerweise nur eine Platzverschwendung ist (möglicherweise eine große Verschwendung für große Arrays).
  2. Wenn Sie die Adresse der Variablen sofort an eine andere Funktion übergeben, die ihren Wert füllt. Hier ist die Initialisierung nur Zeitverschwendung und kann für Leser des Codes verwirrend sein, die sich fragen, warum Sie etwas in einer Variablen speichern, die überschrieben werden soll.
  3. Wenn ein aussagekräftiger Wert für die Variable nicht bestimmt werden kann, bis der nachfolgende Code die Ausführung abgeschlossen hat. In diesem Fall ist es aktiv schädlich, die Variable mit einem Dummy-Wert wie null/NULL zu initialisieren, wie hier verhindert, dass der Compiler Sie warnt wenn Sie einige Codepfade haben, denen niemals ein sinnvoller Wert zugewiesen wird. Compiler sind gut darin, Sie vor dem Zugriff auf nicht initialisierte Variablen zu warnen, können Sie jedoch nicht vor Variablen warnen, die immer noch Dummy-Werte enthalten.

Abgesehen von diesen Problemen würde ich sagen, dass es im Allgemeinen eine gute Praxis ist, Ihre nicht statischen Variablen nach Möglichkeit zu initialisieren.

  • +1 Ich stimme Ihrer Antwort zu und bin von den meisten anderen Antworten völlig überrascht. (Was bringen sie ihnen heutzutage in den Schulen bei?) Aber ich habe eine kleine Spitzfindigkeit bezüglich Ihrer “riesigen Verschwendung”: in den alten Tagen Initialisierung der .bss war nur etwa drei Zeilen Assembler-Code (und die Frage ist getaggt C).

    – Joseph Quinsey

    3. November 2011 um 4:06 Uhr


  • Die “große Verschwendung” besteht darin, dass das All-Null-Objekt in Daten und nicht in bss gespeichert wird. Die meisten (alle?) Compiler tun dies, wenn Sie ausdrücklich initialize, weshalb ich empfohlen habe, nach Möglichkeit immer die implizite Nullinitialisierung zu verwenden.

    – R.. GitHub HÖR AUF, EIS ZU HELFEN

    3. November 2011 um 12:33 Uhr

  • Ich dachte Mitte der 80er Jahre an crt0 für ROM-basierte Systeme zurück. Aber jetzt verwendet das Betriebssystem anscheinend Zero-Fill-on-Demand; Sieh dir das an. Ein Schnelltest echo 'char foo[0x88888]; int main(void) {return 0;}' | gcc -x c - && readelf -a a.out | grep bss gibt ... .bss NOBITS ... 0888a8 ....

    – Joseph Quinsey

    3. November 2011 um 21:19 Uhr

  • +1 für eine nachdenkliche, gut begründete Antwort. Dies gibt gute Einblicke in die Gründe dafür, dass Variablen nicht initialisiert werden. Ich bin jedoch aus dem anderen Lager. Mir wurde immer gesagt, dass alle Variablen initialisiert werden müssen, um die gelegentliche Verwendung von Zufallswerten (und als Folge davon nicht reproduzierbare Fehler) zu vermeiden. Und ich wollte ein Gegenbeispiel für das dritte geben Fall: Leider arbeite ich in letzter Zeit viel mit Code, dessen Autoren sich nicht um Warnungen gekümmert haben. Also ich habe Hunderte davon. Infolgedessen kann ich mich nicht auf Compiler-Warnungen verlassen. In diesem Fall bevorzuge ich ein deterministisches Verhalten gegenüber einer weiteren Warnung

    – Dmitrij Semikin

    2. Juni 2015 um 21:25 Uhr

  • Ich glaube, dass Code-Sauberkeit und Lesbarkeit oft unterschätzt werden. Das Einsparen eines Wortes beim Schreiben auf Kosten einer höheren Fehleranfälligkeit bei der Codewartung (was ist, wenn jemand diese Variable später verwendet? Wird er / sie Compiler-Warnungen aktiviert haben? Was, wenn die Funktion, die den Wert aktualisieren soll, sie nicht berührt, zB wegen eines Fehlers?) sieht für mich etwas verrückt aus. Ich hoffe, dass diese Art der Optimierung nur in leistungskritischen Bereichen wie Software-Decodern und nirgendwo sonst durchgeführt wird. (Übrigens, viele Compiler werden diesen Schreibvorgang sogar überspringen, wenn sich ein anderer im Codepfad befindet.)

    – Narcolessico

    16. Januar 2020 um 13:03 Uhr

Eine noch nicht erwähnte Regel lautet: Wenn die Variable innerhalb einer Funktion deklariert wird, wird sie nicht initialisiert, und wenn sie im statischen oder globalen Bereich deklariert wird, wird sie auf 0 gesetzt:

int a; // is set to 0

void foo() {
  int b;  // set to whatever happens to be in memory there
}

Allerdings – aus Gründen der Lesbarkeit würde ich normalerweise alles zum Zeitpunkt der Deklaration initialisieren.

Wenn Sie daran interessiert sind, diese Art von Dingen im Detail zu lernen, würde ich empfehlen diese Präsentation und dieses Buch

Mir fallen spontan ein paar Gründe ein:

  1. Wenn Sie es später in Ihrem Code initialisieren werden.

    int x;
    
    if(condition)
    {
        func();
        x = 2;
    }
    else
    {
       x = 3;
    }
    anotherFunc(x); // x will have been set a value no matter what
    
  2. Wenn Sie etwas Speicher benötigen, um einen Wert zu speichern, der durch eine Funktion oder einen anderen Codeabschnitt festgelegt wurde:

    int x;  // Would be pointless to give x a value here
    scanf("%d", &x);
    

  • Dieser Code generiert eine Warnung in g++, da x ohne Initialisierung verwendet wird.

    – Anio

    2. November 2011 um 2:05 Uhr


Benutzer-Avatar
Anio

Wenn sich die Variable im Geltungsbereich einer Funktion befindet und kein Mitglied einer Klasse I stets initialisieren, da Sie sonst Warnungen erhalten. Auch wenn diese Variable später verwendet wird, weise ich sie lieber bei der Deklaration zu.

Member-Variablen sollten Sie im Konstruktor Ihrer Klasse initialisieren.

Für Zeiger, stets Initialisieren Sie sie auf einen Standardwert, insbesondere NULL, selbst wenn sie später verwendet werden sollen, sind sie gefährlich, wenn sie nicht initialisiert werden.

Außerdem wird empfohlen, Ihren Code mit der höchsten Warnstufe zu erstellen, die Ihr Compiler unterstützt. Dies hilft, schlechte Praktiken und potenzielle Fehler zu identifizieren.

Benutzer-Avatar
Adam Zalcman

Statische und globale Variablen werden für Sie auf Null initialisiert, sodass Sie die Initialisierung überspringen können. Automatische Variablen (z. B. nicht statische Variablen, die im Funktionskörper definiert sind) können Müll enthalten und sollten wahrscheinlich immer initialisiert werden.

Wenn Sie bei der Initialisierung einen bestimmten Wert ungleich Null benötigen, sollten Sie immer explizit initialisieren.

Benutzer-Avatar
Jared Ng

Es ist immer eine gute Praxis, Ihre Variablen zu initialisieren, aber manchmal ist es nicht so streng notwendig. Folgendes berücksichtigen:

int a;
for (a = 0; a < 10; a++) { } // a is initialized later

oder

void myfunc(int& num) {
  num = 10;
}

int a;
myfunc(&a); // myfunc sets, but does not read, the value in a

oder

char a;
cin >> a; // perhaps the most common example in code of where
          // initialization isn't strictly necessary

Dies sind nur einige Beispiele, bei denen es nicht unbedingt notwendig ist, eine Variable zu initialisieren, da sie später gesetzt wird (aber zwischen Deklaration und Initialisierung nicht zugegriffen wird).

Im Allgemeinen schadet es jedoch nicht, Ihre Variablen immer bei der Deklaration zu initialisieren (und dies ist wahrscheinlich die beste Vorgehensweise).

Benutzer-Avatar
septisch

Im Allgemeinen besteht keine Notwendigkeit, eine Variable zu initialisieren, mit zwei bemerkenswerten Ausnahmen:

  1. Sie deklarieren einen Zeiger (und weisen ihn nicht sofort zu) – Sie sollten diese als guten Stil und defensive Programmierung immer auf NULL setzen.
  2. Wenn Sie bei der Deklaration der Variablen bereits wissen, welcher Wert ihr zugewiesen wird. Weitere Zuweisungen verbrauchen mehr CPU-Zyklen.

Darüber hinaus geht es darum, die Variablen in den richtigen Zustand zu bringen, in dem Sie sie für die auszuführende Operation haben möchten. Wenn Sie sie nicht lesen, bevor eine Operation ihren Wert ändert (und es der Operation egal ist, in welchem ​​Zustand sie sich befindet), müssen sie nicht initialisiert werden.

Ich persönlich initialisiere sie sowieso immer gerne; Wenn Sie vergessen haben, ihm einen Wert zuzuweisen, und es versehentlich an eine Funktion übergeben wird (wie eine verbleibende Pufferlänge), wird 0 normalerweise sauber behandelt – 32532556 wäre es nicht.

  • Sie raten ihm also, dass es nur unter zwei Bedingungen notwendig ist, sagen dann aber, dass Sie es immer tun, und geben ein Beispiel, warum er es tun sollte?

    – Lou

    2. November 2011 um 2:28 Uhr

  • danke septisch, ich mochte “Darüber hinaus geht es darum, die Variablen in den richtigen Zustand zu bringen, in dem Sie sie für die Operation haben möchten, die Sie ausführen werden.” sehr aufschlussreich

    – Arthur Colle

    2. November 2011 um 2:39 Uhr

  • Ich habe nie gesagt, dass es nur notwendig ist, nur dass in 90% der Situationen niemand den Unterschied bemerken würde. In dem Beispiel wäre die Anwendung immer noch kaputt – nur ohne Initialisierung werden Sie eher abstürzen als falsche Ergebnisse liefern. Guter Stil schreibt vor, dass Sie sie initialisieren sollten (nichts schreibt vor, dass Sie sollten), und deshalb habe ich meine Meinung abgegeben.

    – septisch

    2. November 2011 um 2:44 Uhr


1344930cookie-checkInitialisieren von Variablen in C

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

Privacy policy