Добрый вечер. Пришел с вопросом. Читал тут книгу, в одном фрагменте было написано, что если я укажу тип данных у переменной в условии функции, то значение переменной будет иметь большую область видимости, чем если бы я указал переменную без типа. То есть без типа переменная будет действовать, пока активен цикл, но с типом данных она будет действовать и на еще одни скобки.
Решил проверить. Написал с 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
. Естественно, что при работе цикла она изменяется.
А вообще по вопросу очевидно, что вы эту тему понимаете неверно, так что почитайте повнимательнее учебник на тему областей видимости переменных.
Виртуальный выделенный сервер (VDS) становится отличным выбором
Пробовала разные варианты создания на выходе файла DLL, который содержит несколько строк, поскольку изучаю C# - C++ непонятен совсем