2016-11-10 6 views
0

У меня возник вопрос о области видимости в C++. Мой приятель дал мне практический тест, чтобы помочь подготовиться к предстоящему техническому экзамену, и я не был уверен, как ответить на один вопрос.механика переменной области видимости в C++

Я дал фрагмент кода

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

мне нужно освежить в механике рамки, потому что я не уверен, какой из следующих ответов лучше.

А) Когда код выходит из области видимости, компилятор запоминает, чтобы восстановить его значение обратно до 12.

B) Когда код выходит из области видимости, оригинальный nValue1 снова используется.

Я думаю, что ответ B, это правильно?

+2

Этот код является неправильным, потому что 'nValue1' используется, прежде чем он объявлен. – Brian

+0

Хм ... Вопрос не имеет для меня никакого смысла. О каком «оригинальном' nValue' это говорить? Я бы понял, если внутренняя переменная также называется «nValue». Но это не так. – AnT

+0

Это, очевидно, опечатка, внешняя декларация должна быть 'nValue1', также, на основе вопроса. –

ответ

4

Ответ не является ни тем, ни другим.

Нет «первоначального значения», и не о чем помнить.

Это две отдельные независимые переменные. Во внутренней области символ nValue1 относится к одной переменной. За пределами внутренней области символ nValue1 относится к другой переменной.

Даже внутри внутренней области внешний вид nValue1 может быть изменен (через указатель или какой-либо эквивалентный механизм). Когда существует внутренняя область видимости, nValue1 не «помнит», чтобы иметь то же значение, что и перед областью действия, но независимо от того, какое значение обновлялось косвенно, в то время как внутренняя область действия действовала.

+0

Ну, единственный возможный вариант ответа - c) поскольку мы меняем nValue1 внутри некоторых фигурных скобок, он знает, что он подталкивает свое значение в стек при попадании в открытую скобу. При попадании на закрывающую скобу компилятор отбрасывает значение обратно со стека. –

+0

@ZachEllis: Извините, что вы получили плохой тест. «Стек» - неудобный термин. Существует стек концептуальных данных, и на нем есть все локальные нестатические переменные, есть стек концептуальных функций, и, вероятно, на вашем процессоре есть физический стек. Все переменные в вашем примере находятся в концептуальном стеке. Ни один из них, вероятно, не будет находиться в физическом стеке, потому что любой процессор имеет более 2 регистров. – MSalters

0

Точно так же как дополнение к Sam Varshavchiks правильный ответ, из-за вашего комментария по нему. Итак, если вы имеете в виду, вы пощадите переменную в своем случае, потому что вы повторно используете имя, это не так. Я попытаюсь проиллюстрировать вам, как эквивалентный код, но без повторного имя переменной во внутреннем объеме (который также известен как «тенизации») будет выглядеть следующим образом:

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

если вы поместите его в

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

и посмотреть на сгенерированный ассемблерный код, вы увидите тот же результат для обоих случаев:

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 

вы можете проверить это с помощью компилятора проводнике:

Ваш код с помощью nValue1: Your code + assembler

Мой эквивалент с помощью nValue2: My code + assembler

Смежные вопросы