Добрый вечер. Пришел с вопросом. Читал тут книгу, в одном фрагменте было написано, что если я укажу тип данных у переменной в условии функции, то значение переменной будет иметь большую область видимости, чем если бы я указал переменную без типа. То есть без типа переменная будет действовать, пока активен цикл, но с типом данных она будет действовать и на еще одни скобки.
Решил проверить. Написал с int'ом-все сработало. Убрал int-и программа стала использовать значение переменной в цикле во всей программе и по какому-то принципу компилятор его даже изменил, по какому-я не понимаю.
Вопрос: Я некорректно понял инфу из учебника? Да, то как все должно быть на самом деле?
#include <iostream>
using namespace std;
int main() {
int done=5;
int howmany=3;
for( done=1; done<howmany; done++)
{
cout<<"7"<<endl;
}
cout<<done;
return 0;
}
Вывод:
7
7
3
Рассмотрим следующую программу
#include <iostream>
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 <iostream>
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 <iostream>
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 <iostream>
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:
//...
Как я понимаю, вы просто указали в цикле for
for(int done ....
При этом произошло следующее: вы объявили новую переменную done
, которая имеет областью видимости только цикл for
, а после выхода из него это переменная done
благополучно умирает, и имя done
относится вновь к той переменной, которая объявлена в начале функции main
. Поскольку в цикле вы меняли переменную, которая просто "тезка" локальной переменной done
из функции main
, последняя оставалась неизменной.
Но как только вы убираете слово int
из заголовка цикла for
, объявление исчезает, и переменная, используемая в цикле for
- та же, что объявлена в main
. Естественно, что при работе цикла она изменяется.
А вообще по вопросу очевидно, что вы эту тему понимаете неверно, так что почитайте повнимательнее учебник на тему областей видимости переменных.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Пробовала разные варианты создания на выходе файла DLL, который содержит несколько строк, поскольку изучаю C# - C++ непонятен совсем