Какова область действия переменной счетчика в цикле for? - PullRequest
9 голосов
/ 06 августа 2010

Я получаю следующую ошибку в Visual Studio 2008:

Error 1 A local variable named 'i' cannot be declared in this scope because it would give a different meaning to 'i', which is already used in a 'child' scope to denote something else

Это мой код:

for (int i = 0; i < 3; i++)
{
  string str = "";
}

int i = 0; // scope error
string str = ""; // no scope error

Я понимаю, что str перестает существовать после завершения цикла, но я также думал, что область действия i также ограничивается циклом for.

То есть i имеет ту же область видимости, что и переменная, объявленная только вне цикла for?

Edit:

Просто чтобы прояснить ситуацию, я использую C #. Я обсуждаю удаление тега "C". Однако, поскольку правильный ответ объясняет разницу между ними, я думаю, что имеет смысл оставить оба тега.

У меня была ошибка в коде выше:

for (int i = 0; i < 3; i++)
{
  string str = "";
}

int i = 0; // scope error
string str = ""; // also scope error,
                 // because it's equivalent to declaring
                 // string str =""; before the for loop (see below)

Ответы [ 4 ]

20 голосов
/ 06 августа 2010

Я думаю, что вы все путаете C ++ и C #.

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

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

Итак, в C ++ это было незаконно. Теперь это законно.

for (int i; ; )
{
}
for (int i; ; )
{
}

И то же самое разрешено в C #. Существует три области действия, внешняя, в которой «i» не определена, и две дочерние области, каждая из которых объявляет свое собственное «i».

Но то, что вы делаете, это:

int i;
for (int i; ; )
{
}

Здесь есть две области видимости. Внешний, который объявляет «я», и внутренний, который также объявляет «я». Это допустимо в C ++ - внешнее 'i' скрыто - но это недопустимо в C #, независимо от того, является ли внутренняя область действия циклом for, циклом while или чем-то еще.

Попробуйте это:

int i;
while (true)
{
    int i;
}

Это та же проблема. C # не допускает использование переменных с одинаковыми именами во вложенных областях.

3 голосов
/ 06 августа 2010

Инкрементатор не существует после цикла for.

for (int i = 0; i < 10; i++) { }
int b = i; // this complains i doesn't exist
int i = 0; // this complains i would change a child scope version because the for's {} is a child scope of current scope

Причина, по которой вы не можете переопределить i после цикла for, заключается в том, что в IL он фактически объявляет его перед циклом for, потому чтообъявления появляются в верхней части области видимости.

2 голосов
/ 06 августа 2010

Просто некоторая справочная информация: последовательность не входит в это.Есть только идея областей видимости - область действия метода, а затем область действия for.Как таковое, «когда цикл заканчивается» не является точным.

Вы публикуете, следовательно, то же самое, что и это:«вписаться» в мою ментальную модель лучше ..

2 голосов
/ 06 августа 2010

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

...