C ++ для переменной области

Я новичок в c ++ и наткнулся на это:

    for (int i=0 ; i<500 ; i++) {
        //to do
    }

    int i;
    std::cin >> i;

UPDATE: Using visual studio 2010 (and the compiler it uses) the i outside the for loop has the value 500 AFTER the call to cin >> i; I am looking at the values using the Visual Studio debugger << (this is the problem - благодаря Greg)

Теперь я ожидал

а) int i; вне цикла for и int i = 0; быть разными переменными, то есть цикл for i выйти из области действия после закрытия фигурных скобок

б) как только я понял, что это не выходит за рамки, я задавался вопросом, почему он не переписывался в цинне.

Я думаю, что б) является преднамеренным (хотя мне трудно найти страницу в книге Бьярна Страуструпа на c ++), но я уверен, что в той же книге указано, что переменные имеют область охвата фигур, в которые они заключены.

В большинстве других языков, которые я знаю при объявлении переменных в конструкции for, они считаются находящимися в фигурных скобках цикла for, но в c ++ это, похоже, не так.

Является ли это так и является специфическим для цикла for или есть какие-либо другие случаи, когда это происходит (я не могу думать ни о каком другом, но эй, я новичок)

благодаря

1
добавлено отредактировано
Просмотры: 1
Что заставляет вас думать, что это не выходит за рамки? i в цикле for действителен только в цикле for.
добавлено автор chris, источник
@GregHewgill, Правильно, я думал, что у меня была слабая память о чем-то, что это сделало. Вы подтвердили это.
добавлено автор chris, источник
Если вы не используете старый компилятор Microsoft, который не реализовал спецификацию должным образом.
добавлено автор Greg Hewgill, источник
Я добавил ответ, в котором суммируются наблюдения и выводы.
добавлено автор Greg Hewgill, источник
Как вы оцениваете значение i ? Вы используете отладчик, или вы действительно печатаете значение с помощью std :: cout << i или что-то еще? Если вы используете отладчик, помните, что не всегда можете доверять тому, что говорит вам отладчик, особенно если у вас есть две разные переменные в одной и той же функции с тем же именем.
добавлено автор Greg Hewgill, источник
Трудно сказать, действительно ли проблема в том, что вы описываете (поскольку мы не можем видеть всю программу). Что произойдет, если вы измените переменную в цикле для на j вместо i , например?
добавлено автор Greg Hewgill, источник
См. /Zc: forScope , для которых версии по умолчанию включены.
добавлено автор CB Bailey, источник
@GregHewgill Это полная программа, и я подумал, что это вариант компилятора ... очень плохо, если он настроен по умолчанию таким образом в визуальной студии ... проверка сейчас
добавлено автор Paul Sullivan, источник
@GregHewgill - место на. Я попробовал std :: cout << i и получил предупреждение компилятора об использовании неинициализированной переменной, я был напечатан как -8000000 что-то (значение неинициализированной памяти?), А после cin >> i оно напечатало правильное введенное значение. Если я не могу доверять отладчику, кому я могу доверять? Или это только одно из этих оговорок? (также, если вы сделаете ответ, я отметю как правильно и спасибо)
добавлено автор Paul Sullivan, источник
Я использую компилятор Visual Studio 2010 и переменную i после cin >> i == 500 независимо от того, что я набираю на консоли
добавлено автор Paul Sullivan, источник

4 ответы

В некоторых ситуациях, особенно в этом случае, когда у вас есть две разные переменные в одной и той же функции с тем же именем, вы не всегда можете доверять отладчику, чтобы предоставить вам правильную информацию. Если вы запрашиваете значение i , отладчик может не знать точно, с какому i вы ссылаетесь. Из того, что вы описали, это похоже на то, что компилятор выделил два разных места памяти для каждого другого экземпляра i .

I often use the principle When in doubt, print more out. If you use std::cout << i, then you should see the actual value of i that is in scope at the point where you print the output.

3
добавлено
Спасибо Greg - я alwayys ожидаю, что отладчик покажет мне правильную переменную, но может понять, почему в этой ситуации это не будет. Отмечено как ответ и спасибо за вашу помощь
добавлено автор Paul Sullivan, источник

Hm, много ответов и даже один выбран как «решение».

Но в любом случае проблема с Visual C ++ 10.0 (компилятор, поставляемый с Visual Studio 2010) заключается в том, что по умолчанию он он может быть настроен на предстандартное поведение, где область действия переменной, объявленной в < code> для цикла расширил блок, в который был помещен цикл.

Вы хотите эту опцию:

/Zc:forScope,wchar_t

который позволяет использовать стандартный код C ++ для -scope, а также встроенный wchar_t тип, и вы хотите:

/GR

который позволяет RTTI (т. е. dynamic_cast и typeid )).

Чтобы получить стандартную версию, вы также можете использовать этот вариант компоновщика:

/entry:mainCRTStartup

для включения стандартного C ++ main для программ подсистемы GUI и, конечно же, вы хотите включить обработку исключений, но, как я помню, для проекта Visual C ++, который включен по умолчанию (хотя и не для компилятора командной строки) ,

Кроме того, конечно, вы хотите включить как можно больше предупреждений с помощью /W4 , хотя это не имеет ничего общего со стандартным соответствием.

Но, в любом случае, суммирование, причина, по которой вы получаете странные для областей, скорее всего, связана с тем, что проект компилятора и/или Visual Studio defaulting был установлен на старые предстандартные правила , а опция для этого - /Zc: forScope .

1
добавлено
Несмотря на то, что я не решал проблему, которую я имел (это был в основном отладчик, показывающий мне жуткие значения, и я действительно проверял параметр/Zc: forScope правильно установленный (по умолчанию)), это на самом деле отлично подходит для того, чтобы помочь новичкам (мне) понять и правильно настроить так + 1 и спасибо
добавлено автор Paul Sullivan, источник

Предполагая соответствие (и компилятор, не соответствующий этому вопросу, скорее всего, дал ошибку компиляции), ваши два i отличаются. Но ничто не мешает компилятору использовать одинаковое расположение памяти для обоих, так как их живое время также отличается, и, следовательно, второй i , начиная с окончательного значения первого, поскольку он не инициализирован, равен следует ожидать в этом случае.

The fact that cin >> i doesn't allow you to enter a new value is unrelated with that. And you don't give enough information to do more than guessing a reason (my guess would be the stream is in an error state).

0
добавлено
Ваша программа не завершена, она не компилируется. Откуда вы знаете, что i - 500 после ввода? Если это с помощью отладчика, то с остальной частью описания моя первая ставка будет на компиляторе, не используя ту же ячейку памяти и отладчик, которые путаются по поводу того, что вы хотите.
добавлено автор AProgrammer, источник
@PaulSullivan, я ответил на слишком много вопросов, где проблема заключалась в том, что OP, хотя очевидно, до такой степени, что его не спрашивают, даже не заявляя.
добавлено автор AProgrammer, источник
Я перепробовал, и программа, которую вы видите, «полностью» - она ​​не пишет поверх i, но если я изменю переменную outisde, для for j вызов cin >> j работает как ожидалось.
добавлено автор Paul Sullivan, источник
В программе отсутствует основная функция - предполагается, что она не будет полной программой без нее. поместите мой код в 'main', включите std пространство имен и он скомпилируется.
добавлено автор Paul Sullivan, источник
Справедливая точка AProgrammer - ответ был отправлен и извиняется, если я натолкнулся на неправильный путь - я предполагаю, что люди поймут, что это фрагмент кода и подразумевается, что он находится в основном и т. Д. Я думаю, я переоценил другие OP. Спасибо за вашу помощь :)
добавлено автор Paul Sullivan, источник

Я предполагаю, что это происходит, потому что 2nd i не является инициализированным, а компилятор использует тот же блок памяти для второго i. Они все еще отличаются двумя переменными. И да, первый я зачерпнул до петли. Поэтому он не определен, вы не можете рассчитывать, что второй i будет 500.

for (int i=0 ; i<500 ; i++) {
    //to do
}

int i=0; // initialize i
std::cin >> i;
0
добавлено
Оказывает свою работу как ожидалось - только отладчик показывает, что у меня такое же значение, но cout << i подтверждает uninitialisation и правильное значение после cin >> i. Спасибо, в любом случае :)
добавлено автор Paul Sullivan, источник