Нельзя использовать переменную в while, объявленную внутри цикла do/while

Почему мне не разрешено использовать переменную I, объявленную внутри do, и использовать ее внутри части while цикла do/while?

do
{
 index += index;
 int composite = index + 1;
 // more code here
} while (UnsetBitmask(bitmasks, composite)); // cannot resolve symbol composite

Впервые я увидел это, я думал, что это ошибка компилятора. Поэтому я перезапустил Visual Studio несколько раз, но все же он не распознает переменную в while.

Что не так с кодом, или это ошибка компилятора?

7 ответов

Ваша переменная используется вне do/while (в С# курсоры обычно определяют область), и поскольку она объявлена ​​внутри do-while, вы не можете использовать ее вне этой области.

Вы можете исправить это, просто объявив его вне цикла.

int composite = 0; // you are not required to set it to zero, as long 
 // as you do not use it before you initialize it
do
{
 index += index;
 composite = index + 1;
 // more code here
} while (UnsetBitmask(bitmasks, composite));

Примечание (1), общепринятой практикой является объявление и установка переменной за один раз, но это не является обязательным условием, если вы его установили, прежде чем использовать его.

Примечание (2): в С# фигурные скобки {....} определяют область переменных. Вы не можете использовать переменную за пределами ее области, она больше не "видима", на самом деле, когда она выходит за рамки, она готова к сбору мусора, а ее содержимое может быть undefined.

i konw это, но почему компилятор не может этого сделать

Вы спрашивали об этом в комментариях. Ответ менее тривиален, чем может показаться. Это сильно зависит от определения языка. Некоторые языки, такие как Perl или старше BASIC, позволяют объявлять переменные на любом уровне и в любой области. Другие языки позволяют определять области переменных и требовать, чтобы переменные были объявлены до их использования (С#, Java, С++, Python). Обычно, но не обязательно, это обычно для статически типизированных языков, поскольку компилятор должен заранее знать, какой тип данных вы хотите поместить в переменную, чтобы do type проверка.

Если компилятор будет принуждать объявление, но не область, это означает, что все переменные будут глобальными, что сложно в больших программах, как программист, вам нужно будет поддерживать, где вы использовали имена переменных и сохраняете уникальность. Это очень утомительно (думаю, COBOL).

С# добавило ключевое слово dynamic, которое позволяет использовать переменные с динамическим типом, но это все еще требует определения переменной до ее использования.

Компилятор может это сделать, но разработчики С# решили, что понятный язык лучше, и, по их мнению, объявленные переменные - это хорошая вещь, потому что это предотвращает ложные ошибки и невозможный код:

// can you see the problem?
va1l = 1;
val1 = 2;
vall = va1l + vall;

Заставляя вас объявлять переменные и обладать ими, предотвращает эти и связанные с ними типы ошибок.


Это не ошибка. Условие внутри цикла while находится вне блока, в котором определена переменная.

int composite;
do
{
 index += index;
 composite = index + 1;
 // more code here
} while (UnsetBitmask(bitmasks, composite));


Per Спецификация переменная условия для do .. while должна быть объявлена ​​вне цикла else на каждой итерации, переменная будет переинициализирована, что doesn Не имеет смысла.

int composite;
 do
 {
 index += index;
 composite = index + 1;
 // more code here
 } while (UnsetBitmask(bitmasks, composite));


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

Вы должны сделать что-то вроде этого....

int composite;
do
{
 index += index;
 composite = index + 1;
 // more code here
} while (UnsetBitmask(bitmasks, composite));


Хотя { ... } означает кодовый блок, все переменные в этом блоке ограничены этой специальной областью. Ваше условие находится вне этой области, поэтому он не может получить доступ к переменной там. Объявите его вне цикла, и он работает:

int composite = 0;
do
{
 index += index;
 composite += index + 1;
 // more code here
} while (UnsetBitmask(bitmasks, composite));


Более общее правило: вы не можете использовать переменную вне ее области, что в С# it {...}, например.

{
 int x = 123;
 ...
 }
 x = 456; // <- compile time error

do {} while в вашем коде просто означает, что область принадлежит циклу.


int composite;
do
{
 index += index;
 composite = index + 1;
 // more code here
} while (UnsetBitmask(bitmasks, composite));

licensed under cc by-sa 3.0 with attribution.