Страницы

Поиск по вопросам

суббота, 28 декабря 2019 г.

Случаи указания типа данных в условии цикла

#cpp #циклы #область_видимости


Добрый вечер. Пришел с вопросом. Читал тут книгу, в одном фрагменте было написано,
 что если я укажу тип данных у переменной в условии функции, то значение переменной
будет иметь большую область видимости, чем если бы я указал переменную без типа. То
есть без типа переменная будет действовать, пока активен цикл, но с типом данных она
будет действовать и на еще одни скобки.

Решил проверить. Написал с int'ом-все сработало. Убрал int-и программа стала использовать
значение переменной в цикле во всей программе и по какому-то принципу компилятор его
даже изменил, по какому-я не понимаю.

Вопрос: Я некорректно понял инфу из учебника? Да, то как все должно быть на самом деле?

#include 
using namespace std;

int main() {
 int done=5;
 int howmany=3;

   for( done=1; done


Ответы

Ответ 1



Рассмотрим следующую программу #include int main() { int done = 5; int howmany = 3; for ( done = 1; done < howmany; done++ ) { std::cout << done << std::endl; } std::cout << done << std::endl; return 0; } Ее вывод на консоль 1 2 3 В этой программе в блоке кода функции main объявлена переменная done. Сначала эта переменная инициализируется значением 5 int done = 5; а затем в предложении for ей присваивается значение 1 for ( done = 1; done < howmany; done++ ) ^^^^^^^^ После выхода из цикла эта переменная будет иметь значение 3. Теперь рассмотрим следующую программу #include int main() { int done = 5; int howmany = 3; for ( int done = 1; done < howmany; done++ ) { std::cout << done << std::endl; } std::cout << done << std::endl; return 0; } Ее вывод на консоль 1 2 5 В этой программе в предложении for объявляется переменная с именем done, совпадающем с именем переменной, объявленной в блоке кода main. for ( int done = 1; done < howmany; done++ ) ^^^^^^^^^^^^ Эта переменная в предложении for скрывает одноименную переменную с таким же именем, объявленную во внешнем блоке кода. Ее область определения - это тело цикла for. После выхода из цикла данная переменная прекращает свое существование. Из стандарта C++ (6.5.3 The for statement) 3 If the for-init-statement is a declaration, the scope of the name(s) declared extends to the end of the for statement. Поэтому последняя строка вывода программы 5 уже выводит на консоль значение переменной done, которая была объявлена до цикла в блоке кода функции main В общем случае имя, объявленное во внутренней области объявления скрывает такое же имя, объявленное во внешней области объявления Из стандарта C++ (3.3.10 Name hiding) 1 A name can be hidden by an explicit declaration of that same name in a nested declarative region or derived class (10.2). Обратите внимание, что есть важное отличие в определении предложения for между C++ и C. В C++ во второй части предложения for, где записывается условие, также может быть объявление. Рассмотрите следующую демонстрационную программу #include int main() { int done = 5; int howmany = 3; for ( ; int howmany = done; done-- ) { std::cout << done << std::endl; } std::cout << '\n' << howmany << std::endl; return 0; } Ее вывод на консоль 5 4 3 2 1 3 При каждой итерации данного цикла for for ( ; int howmany = done; done-- ) ^^^^^^^^^^^^^^^^^^ объявляется переменная howmany, которая скрывает переменную с таким же именем, объявленную в функции main. Значение, присвоенное этой переменной, преобразуется к булевскому типу. Если оно равно 0, то условие будет ложным и произойдет выход из цикла. После цикла выводится уже значение переменной howmany, объявленной в main. Ну, и напоследок пример, когда в предложении for сразу в двух его частях объявляются переменные, которые скрывают одноименные переменные с теми же именами, объявленные в main. После выхода из цикла эти переменные прекращают свое существование, и становятся видимыми переменные, объявленные в main. #include int main() { int done = 10; int howmany = 20; for ( int done = 5; int howmany = done; done-- ) { std::cout << done << std::endl; } std::cout << '\n' << done << std::endl; std::cout << howmany << std::endl; return 0; } Вывод этой программы на консоль 5 4 3 2 1 10 20 Предложение for в этой программе логически может быть представлено как { int done = 5; Label_repeat: { int howmany = done; if ( howmany != 0 ) { std::cout << done << std::endl; done--; goto Label_repeat; } else { goto Label_exit; } } } Label_exit: //...

Ответ 2



Как я понимаю, вы просто указали в цикле for for(int done .... При этом произошло следующее: вы объявили новую переменную done, которая имеет областью видимости только цикл for, а после выхода из него это переменная done благополучно умирает, и имя done относится вновь к той переменной, которая объявлена в начале функции main. Поскольку в цикле вы меняли переменную, которая просто "тезка" локальной переменной done из функции main, последняя оставалась неизменной. Но как только вы убираете слово int из заголовка цикла for, объявление исчезает, и переменная, используемая в цикле for - та же, что объявлена в main. Естественно, что при работе цикла она изменяется. А вообще по вопросу очевидно, что вы эту тему понимаете неверно, так что почитайте повнимательнее учебник на тему областей видимости переменных.

Комментариев нет:

Отправить комментарий