2016-03-29 19 views
0

Ich habe unten Code geschrieben (Nur für Verständnis Zweck nur). Außerhalb der Hauptleitung, int b; bedeutet vorläufige Definition. Inside main int b = 16 ist eine lokale Variable. Innerhalb der Funktionsvariablen b hat interne Verknüpfung (Dateibereich). Die Ausgabe ist 16 und 0. Ich habe gelesen, dass Speicher nur für vorläufig definierte Variablen reserviert wird, wenn sie initialisiert werden. Also hier ist meine Frage innerhalb der Funktion, printf druckt den Wert von b und wird der Speicher zugewiesen, wenn printf aufgerufen wird? Falls dies der Fall ist, kann ich sagen, dass der Speicher einer vorläufig definierten Variablen zugewiesen wird, wenn auf sie zum ersten Mal zugegriffen wird (ob initialisiert oder auf sie zugegriffen wird)? Oder liege ich falsch?Vorläufige Definition und Speicherzuweisung

int b; 
int b; 
void f1(int a1); 
int main() 
{ 
    int b=16; 
    printf("b=%d\n",b); 
    f1(5); 
    return 0; 
} 

void f1(int a1) 
{ 
    printf("b = %d\n",b); 
} 

Edited: mehr Klarheit hinzu: Ich bin mir bewusst, dass Variable innerhalb der Funktion von dem in Haupt unterscheidet. Beachten Sie auch, dass die lokale Variable im Stapel liegt. Meine Frage hier ist in Bezug auf vorläufige Definition. int b wurde zweimal deklariert und in C akzeptiert, da es sich um eine vorläufige Definition handelt. Wenn es sich um eine tatsächliche Definition handelt, sind Mehrfachdefinitionen nicht zulässig und werden daher nicht akzeptiert. Es gibt einige Fragen zur vorläufigen Definition (About Tentative definition). Nach einer von ihnen "C hat eine spezielle" vorläufige Definition "Regel, die mehrere Definitionen für die gleiche Variable erlaubt, solange sie alle übereinstimmen und höchstens eine Initialisierer hat. Der C-Compiler, hinter den Kulissen, kombiniert alle der vorläufigen Definitionen in einer einzigen Definition. " So umformulieren Sie meine Frage:

Wird Speicher zugeordnet, wenn Variable nur vorläufig definiert ist, aber nicht verwendet? (Angenommen, der Compiler optimiert den Code nicht). Es sieht so aus, als ob am Ende der Übersetzungseinheit der Speicher entsprechend der oben verlinkten Frage zugewiesen wird. Oder ob Speicher nur zugewiesen wird, wenn es zum ersten Mal verwendet wird (in diesem Fall in printf-Anweisung)?

+0

Ist 'int b; int b; 'erlaubt? : O – Downvoter

+0

* "Eine vorläufige Definition wird zu einer vollständigen Definition, wenn das Ende der Übersetzungseinheit erreicht ist und keine Definition mit einem Initialisierer für den Bezeichner" * aufgetreten ist.Die letzte vorläufige Definition wird also zu einer tatsächlichen mit globaler Reichweite und Null wird initialisiert. –

+0

@cad: Da sie identisch sind: ja. Nicht sicher, ob das stimmt, wenn man z.B. 'typedef int es; es b; ', musste im Standard nachschlagen, aber ich würde das sowieso wie Hölle vermeiden. – Olaf

Antwort

0

Dies sind zwei verschiedene Variablen.

Für den globalen wird der Speicher zugewiesen, wenn das Programm zum ersten Mal in den Speicher geladen wird. Es ist im globalen Speicher des Programms zugeordnet und kann von jedem Punkt im Programm aus leicht erreicht werden.

Für die main() ist lokal int b=16; auf dem Stapel zugeordnet, in der main() Funktionsrahmen. Es kann nur direkt von dieser Funktion zugegriffen werden. Alles andere erfordert entweder, dass main() die Variable Adresse oder einige komplexe Zeigerarithmetik auf dem Stapel übergeben.

Den lokalen bversteckt die globalen b, weil sie die gleichen Namen haben, so können Sie das global man von dieser Funktion verwenden (in einigen Sprachen erlauben dies, C nicht), aber das ist es. Sie sind unterschiedliche Variablen, und die Binärdatei Ihres Programms (d. H. Die tatsächlich ausgeführten Anweisungen) würde sich nicht ändern, wenn Sie den Namen ändern.

0

Diese Antwort erklärt, warum Null initialisiert ist.

Does gcc automatically initialize static variables to zero?

Die int b; in Haupt auf dem Stapel befindet und auf 16. In Ihrer Funktion f1 die einzige b Symbol, das in Rahmen ist, ist die eine in Dateigültigkeitsbereich deklariert und es Null ist initialisiert, weil das ist, was der Standard sagt es sollte sein.