2016-11-10 5 views
0

Ich hatte eine Frage zum Umfang in C++. Mein Kumpel gab mir einen Praxistest, um mich auf eine anstehende technische Prüfung vorzubereiten, und ich war mir nicht sicher, wie ich eine Frage beantworten sollte.Mechanik des Variablenbereichs in C++

ich den Code-Snippet gegeben

int nValue1 = 12, nTotal =0; 
nTotal += nValue1; 
{ 
    int nValue1 = 14; 
    nTotal += nValue1; 
} 
nTotal += nValue1; 

Ich brauche eine Auffrischung auf der Mechanik des Umfangs, weil ich nicht sicher bin, welche der folgenden Antworten am besten ist.

A) Wenn der Code den Bereich verlässt, der Compiler seinen Wert zurück erinnert wiederherzustellen bis 12.

B), wenn der Code, den Bereich verlässt, wird die ursprüngliche nValue1 wieder verwendet.

Ich denke, die Antwort ist B, ist das richtig?

+2

Dieser Code ist falsch, weil 'nValue1' verwendet wird, bevor es erklärt wird. – Brian

+0

Ähm ... Die Frage ergibt für mich keinen Sinn. Von welchem ​​"ursprünglichen" nValue "spricht es? Ich würde verstehen, wenn die innere Variable auch 'nValue' genannt wird. Aber es ist nicht. – AnT

+0

Es ist offensichtlich ein Tippfehler, die äußere Deklaration soll auch "nValue1" sein, basierend auf der Frage. –

Antwort

4

Die Antwort ist weder.

Es gibt keinen "ursprünglichen Wert", und es gibt nichts zu erinnern.

Sie sind zwei separate, unabhängige Variablen. Im inneren Bereich bezieht sich das Symbol nValue1 auf eine Variable. Außerhalb des inneren Bereichs bezieht sich das Symbol nValue1 auf eine andere Variable.

Auch innerhalb des inneren Bereichs kann der äußere Bereich nValue1 (durch einen Zeiger oder einen ähnlichen Mechanismus) geändert werden. Wenn der innere Bereich existiert, wird nValue1 nicht "erinnert", um den gleichen Wert wie vor dem Bereich zu haben, sondern unabhängig davon, welcher Wert indirekt aktualisiert wurde, während der innere Bereich in Kraft war.

+0

Nun, die einzige andere mögliche Antwort ist c) Da wir nValue1 innerhalb einiger Klammern ändern, weiß der Compiler, dass er seinen Wert auf den Stapel verschiebt, wenn er die öffnende Klammer trifft. Beim Auftreffen auf die schließende Klammer zieht der Compiler den Wert vom Stapel zurück. –

+0

@ZachEllis: Entschuldigung, dass du einen schlechten Test hast. "Stack" ist ein unbequemer Begriff. Es gibt einen konzeptuellen Datenstapel, und alle lokalen nicht-statischen Variablen sind darauf, es gibt einen konzeptionellen Funktionsaufruf-Stack, und wahrscheinlich gibt es einen physischen Stack auf Ihrer CPU. Alle Variablen in Ihrem Beispiel befinden sich auf dem konzeptionellen Stack. Keiner von ihnen wird wahrscheinlich auf dem physischen Stapel sein, weil jede CPU mehr als 2 Register hat. – MSalters

0

Genau wie ein Zusatz zu Sam Varshavchiks richtige Antwort, wegen Ihres Kommentars darauf. Also, wenn Sie meinen, Sie verschonen eine Variable in Ihrem Fall, weil Sie den Namen wiederverwenden, ist es nicht der Fall. Ich werde versuchen, für Sie zu veranschaulichen, wie entsprechenden Code aber ohne den Namen einer Variable in einem inneren Umfang der Wiederverwendung (die auch als „Schattenbildung“ bekannt ist) aussehen würde:

int nValue1 = 12, nTotal =0; 
nTotal += nValue1; 
{ 
    int nValue2 = 14; 
    nTotal += nValue2; 
} 
nTotal += nValue1; 

wenn man es in einem ein

int main() { 
// place the relevant code snipped here 
} 

und bei dem erzeugten Assembler-Code anschauen, werden Sie die gleiche Leistung für beide Fälle siehe:

push rbp 
    mov  rbp, rsp 
    mov  DWORD PTR [rbp-4], 12 
    mov  DWORD PTR [rbp-8], 0 
    mov  eax, DWORD PTR [rbp-4] 
    add  DWORD PTR [rbp-8], eax 
    mov  DWORD PTR [rbp-12], 14 
    mov  eax, DWORD PTR [rbp-12] 
    add  DWORD PTR [rbp-8], eax 
    mov  eax, DWORD PTR [rbp-4] 
    add  DWORD PTR [rbp-8], eax 
    mov  eax, 0 
    pop  rbp 
    ret 

Sie können dies überprüfen, mit dem Compiler Explorer:

Ihr Code mit nValue1: Your code + assembler

Mein gleichwertig mit nValue2: My code + assembler

Verwandte Themen