Variablenwiederverwendung in C

8

Der Code, den ich mir ansehe, ist dies:

%Vor%

Meine Frage dreht sich um die Verwendung von numWords . Verwendet das Laufzeitsystem diese Variable erneut oder weist es bei jedem Durchlauf durch die int -Schleife ein neues for zu? Wenn Sie sich fragen, warum ich das frage, bin ich ein Java-Programmierer, der in HPC einsteigen will und deshalb versuche, C zu lernen. Normalerweise weiß ich, dass Sie Code wie vermeiden wollen das ist also wirklich explorativ.

Ich bin mir bewusst, dass die Antwort wahrscheinlich auf den Compiler angewiesen ist ... Ich suche nach einer tieferen Erklärung als das. Nehmen Sie den Compiler Ihrer Wahl an.

    
avgvstvs 08.10.2011, 20:27
quelle

6 Antworten

2

Dies wird in C als "Block", "automatisch" oder "lokal" bezeichnet. Es ist eine Form von lexikalisches Scoping , dh ein Name bezieht sich auf seine lokale Umgebung. In C ist es von oben nach unten, was bedeutet, dass es passiert, wenn die Datei geparst und kompiliert und nur sichtbar ist, nachdem sie im Programm definiert wurde.  Wenn die Variable den Gültigkeitsbereich verlässt, ist der lexikalische Name nicht mehr gültig (sichtbar) und der Speicher kann wiederverwendet werden.

Die Variable wird in einem lokalen Gültigkeitsbereich oder in einem Block definiert, der durch geschweifte Klammern { /* block */ } definiert wird. Dies definiert eine ganze Gruppe von C- und C99-Idiomen wie:

%Vor%

Es gibt Feinheiten wie:

%Vor%

und:

%Vor%

Es gibt Idiosynkrasien:

  1. In K & amp; R C, ANSI C89 und Visual Studio müssen alle Variablen am Anfang der Funktion oder der zusammengesetzten Anweisung (d. h. vor der ersten Anweisung)
  2. deklariert werden
  3. In gcc können Variablen an beliebiger Stelle in der Funktion oder der zusammengesetzten Anweisung deklariert werden und sind erst ab diesem Zeitpunkt sichtbar.
  4. In C99 und C ++ können Schleifenvariablen in der Anweisung für deklariert werden und sind bis zum Ende des Schleifenkörpers sichtbar.
  5. In einem Schleifenblock wird die Zuweisung EINMAL durchgeführt und die RH-Zuweisung (falls vorhanden) jedes Mal ausgeführt.

In dem von Ihnen geposteten Beispiel haben Sie sich nach int numWords = 0; erkundigt und ob jedes Mal ein neues int durch die Schleife zugewiesen wird. Nein, es ist nur ein int in einem Schleifenblock zugewiesen, aber die rechte Seite von = wird jedes Mal ausgeführt. Dies kann nachgewiesen werden:

%Vor%

Kompilieren Sie das mit jedem gcc (clang, eclipse, usw.) kompatiblen Compiler mit deaktivierten Optimierungen ( -O0 ) oder on. Die Adresse von t2 ist immer dieselbe.

Vergleichen Sie jetzt mit einer rekursiven Funktion:

%Vor%

Die Adresse von n wird jedes Mal anders sein, weil bei jedem rekursiven Aufruf ein neues automatisches n zugeordnet wird.

Vergleiche mit einer iterativen Version von factorial, die zur Verwendung einer Schleifenblockzuweisung erzwungen wird:

%Vor%

Abschließend haben Sie nach int numWords = 0; in der for-Schleife gefragt. Die Variable wird in diesem Beispiel wiederverwendet.

Wie der Code geschrieben wird, verlässt sich der Programmierer auf die RH von int numWords = 0; nach der ersten Ausführung und setzt die Variable auf 0 zurück, um sie in der folgenden while-Schleife zu verwenden.

    
the wolf 08.10.2011, 23:18
quelle
5

Ihre Vorstellung davon, wie dies in Java funktioniert, könnte falsch verstanden werden - Java "zerteilt" auch nicht jedes Mal eine neue int durch eine solche Schleife. Primitive Typvariablen wie int werden im Java-Heapspeicher nicht zugewiesen und der Compiler verwendet denselben lokalen Speicher für jede Schleifeniteration.

Auf der anderen Seite, wenn Sie new irgendetwas in Java jedes Mal durch eine Schleife aufrufen, dann ja, ein neues Objekt wird jedes Mal zugewiesen. In diesem Fall tun Sie das nicht. C wird auch nichts vom Heap zuweisen, es sei denn, Sie rufen malloc oder ähnlich (oder in C ++, new ) auf.

    
Greg Hewgill 08.10.2011 20:35
quelle
4

Bitte beachten Sie den Unterschied zwischen automatic und dynamic Speicherzuweisung. In Java existiert nur letzteres.

Dies ist eine automatische Zuweisung:

%Vor%

Dies ist eine dynamische Zuweisung:

%Vor%

Die dynamische Zuweisung in C erfolgt nur explizit (wenn Sie malloc oder seine Derivate aufrufen).

In Ihrem Code wird nur der Wert für Ihre Variable festgelegt, keine neue wird zugewiesen.

    
Constantinius 08.10.2011 20:31
quelle
3

Aus Performance-Sicht wird es nicht wichtig sein. (Variablen werden Registern oder Speicherorten zugeordnet, so dass sie wiederverwendet werden müssen.)

Vom logischen Standpunkt aus gesehen, ja, es wird wiederverwendet, weil Sie es außerhalb der Schleife deklariert haben.

Aus logischer Sicht:

  • numWords wird nicht in der äußeren Schleife wiederverwendet, da sie darin deklariert ist.
  • numWords wird in der inneren Schleife wiederverwendet, da sie nicht innerhalb von
  • deklariert ist.
Mysticial 08.10.2011 20:29
quelle
0

Der Gültigkeitsbereich der Variable numWords befindet sich innerhalb der for-Schleife. Genauso wie Java kann man die Variable nur innerhalb der Schleife benutzen, also müsste theoretisch ihr Speicher beim Beenden freigegeben werden - da sie in deinem Fall ebenfalls auf dem Stack ist.

Jeder gute Compiler würde jedoch denselben Speicher verwenden und die Variable einfach bei jeder Iteration auf 0 setzen.

Wenn Sie class anstelle von int verwenden, wird der Destruktor immer dann aufgerufen, wenn die for Schleifen vorhanden sind.

Bedenke das auch:

%Vor%

Die beiden hier erstellten Objekte befinden sich wahrscheinlich im selben Speicher.

    
Luchian Grigore 08.10.2011 20:37
quelle
-3

Es wird jedes Mal durch die Schleife zugewiesen (der Compiler kann diese Zuweisung optimieren)

%Vor%

Keine Garantie, dass alle 100 Zeilen die gleiche Adresse haben (obwohl sie dies wahrscheinlich tun).

Bearbeiten: Der C99-Standard , in 6.2.4 / 5 heißt es: "[the object] lifetime extends from entry into the block with which it is associated until execution of that block ends in any way." und in 6.8.5 / 5 heißt es, dass der Körper einer for -Anweisung tatsächlich ein Block ist ... also gilt der Absatz 6.2.4 / 5 .

    
pmg 08.10.2011 21:19
quelle

Tags und Links