Какова область цикла while
и for
?
Например, если я объявил объект в цикле, каково его поведение и почему?
Какова область цикла while
и for
?
Например, если я объявил объект в цикле, каково его поведение и почему?
В следующих примерах все переменные уничтожаются и воссоздаются для каждой итерации цикла, кроме i
, которая сохраняется между итерациями цикла и доступна для условных и окончательных выражений в цикле for. Ни одна из переменных не доступна за пределами циклов. Уничтожение переменных внутри тела цикла for происходит до того, как i
будет увеличено.
while(int a = foo()) {
int b = a+1;
}
for(int i=0;
i<10; // conditional expression has access to i
++i) // final expression has access to i
{
int j = 2*i;
}
Что касается причины; петли на самом деле принимают один оператор для своего тела, просто случается, что существует оператор, называемый составным выражением, созданным фигурными фигурными скобками. Объем переменных, созданных в любом составном выражении, ограничен самой составной инструкцией. Так что это действительно не специальное правило для циклов.
Операторы циклов и выбора имеют свои собственные правила для переменных, созданных как часть цикла или оператора выбора. Они просто разработаны в соответствии с тем, что, по мнению дизайнера, было наиболее полезным.
Все объявленные в цикле области привязаны к этому циклу и не могут быть доступны за пределами фигурных скобок. На самом деле вам даже не нужен цикл для создания новой области. Вы можете сделать что-то вроде:
{
int x = 1;
}
//x cannot be accessed here.
int d;
// can use d before the loop
for(int a = 0; a < 5; ++a) // can use a or d in the ()
{
int b;
// can use d, a, b in the {}
}
int c;
// can use d, c after the loop
a
и b
видны только в области цикла for. Область включает в себя то, что в цикле ()
и {}
Я подумал, что стоит упомянуть:
Некоторые компиляторы могут иметь параметр, который влияет на объем переменных, созданных в инициализаторе цикла for. Например, Microsoft Visual Studio имеет опцию /Zc: forScope (Формирование соответствия для области Loop Scope). По умолчанию используется стандартное поведение С++. Однако это можно изменить так, чтобы переменная цикла for сохранялась в активном состоянии вне области цикла for. Если вы используете VS, может быть полезно знать, что этот параметр существует, поэтому вы можете убедиться, что он настроен на желаемое поведение. Не уверен, есть ли другие компиляторы, у которых есть этот параметр.
Некоторые компиляторы могут исключить код, который, по его мнению, не нужен, из-за настроек оптимизации и " Dead Store. Например, если переменная, которая изменяется внутри цикла, не читается вне цикла, сам цикл может быть отброшен компилятором.
Например, рассмотрим следующий цикл:
int cnt = 0;
int trys = MAX_INT;
while (trys-- > 0)
{
cnt += trys;
}
возможно, что некоторые компиляторы могут отбросить [содержимое] цикла, потому что переменная Cnt не используется после цикла.
Просто хотел добавить, что переменные, объявленные в цикле for или while, также находятся в пределах цикла. Например:
for (int index = 0; index < SOME_MAX; ++index)
{
...
}
// index is out of scope here.
for( int i = 0; i < 10; ++i )
{
string f = "foo";
cout << f << "\n";
}
// i and f are both "gone" now
В приведенном выше примерном коде как i
, так и f
находятся в пределах {
{и }
}. Когда закрывающая скобка выполняется, обе переменные выпадают из области видимости.
Причина этого заключается в том, что стандарт говорит так; как работает язык С++.
Что касается мотивации, подумайте, что это может быть использовано в ваших интересах:
for( ...)
{
std::auto_ptr<SomeExpensiveObject> obj(new SomeExpensiveObject);
}
В приведенном выше коде мы используем интеллектуальный указатель RAII для "собственного" дорогостоящего объекта, который мы создали в цикле. Сфера семантики цикла for
определяет, что после каждого выполнения цикла объект, который был создан во время этой итерации, будет уничтожен.
int a;
for(int b=0; b<10; ++b) {
int c;
}
как если бы это было:
int a;
{
int b=0;
begin:
if (b<= 10)
{
{
int c;
}
++b;
goto begin;
}
}
Цель состоит в том, чтобы переменные выходили из области видимости в четко определенных точках последовательности.
Проверьте этот код
#include < stdio.h >
int i = 10;
int main() {
for(int i=0; i<3; i++) {
fprintf(stdout," for i = %d & upper i = %d\n",i,::i);
}
while (i>3) {
int i = 30;
fprintf(stdout," while i = %d & upper i = %d\n",i,::i);
i++;
fprintf(stdout," while i = %d & upper i = %d\n",i,::i);
}
fprintf(stdout,"i = %d \n",i);
}
В приведенном выше коде глобальная переменная я отличается от той, которая управляет циклом for.
Он напечатает
for i = 0 & upper i = 10
for i = 1 & upper i = 10
for i = 2 & upper i = 10
когда цикл while - переменная i, определенная внутри, имеет локальную область, где, поскольку переменная под (i > 3) следует глобальной переменной и не относится к локальной области.
Dipan.
В C/С++ область действия переменной, объявленной в цикле for или while (или любой другой заключенный в скобки блок, если на то пошло), находится от открытой скобки до закрывающей скобки.
while (some_condition == true)
{
int myVar = 3;
}
cout << myVar << endl; // This will cause a compilation error
Переменная находится в рамках цикла. То есть вам нужно быть в цикле для доступа к нему. Это так же, как если бы вы объявили переменную внутри функции, доступ к ней имеют только объекты в функции.