Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
C++ для начинающих (Стенли Липпман) 3-е хххх.pdf
Скачиваний:
85
Добавлен:
30.05.2015
Размер:
5.92 Mб
Скачать

С++ для начинающих

205

}

5.5. Инструкция цикла for

Как мы видели, выполнение программы часто состоит в повторении последовательности инструкций до тех пор, пока некоторое условие остается истинным. Например, мы читаем и обрабатываем записи файла, пока не дойдем до его конца, перебираем элементы массива, пока индекс не станет равным размерности массива минус 1, и т.д. В С++ предусмотрено три инструкции для организации циклов, в частности for и while, которые начинаются проверкой условия. Такая проверка означает, что цикл может закончиться без выполнения связанной с ним простой или составной инструкции. Третий тип цикла, do while, гарантирует, что тело будет выполнено как минимум один раз: условие цикла проверяется по его завершении. (В этом разделе мы детально рассмотрим цикл for; в разделе 5.6 разберем while, а в разделе 5.7 – do while.)

Цикл for обычно используется для обработки структур данных, имеющих

#include <vector> int main() {

int ia[ 10 ];

for ( int ix = 0; ix < 10; ++-ix ) ia[ ix ] = ix;

vector<int> ivec( ia, ia+10 ); vector<int>::iterator iter = ivec.begin() ;

for ( ; iter != ivec.end(); ++iter ) *iter *= 2;

return 0;

фиксированную длину, таких, как массив или вектор:

}

for (инструкция-инициализации; условие; выражение )

Синтаксис цикла for следующий:

инструкция

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

// index и iter определены в другом месте

for ( index =0; ...

for ( ; /* пустая инструкция */ ...

for ( iter = ivec.begin(); ...

for ( int 1o = 0,hi = max; ...

инструкции-инициализации:

С++ для начинающих

206

for ( char *ptr = getStr(); ...

условие служит для управления циклом. Пока условие при вычислении дает true, инструкция продолжает выполняться. Выполняемая в цикле инструкция может быть как простой, так и составной. Если же самое первое вычисление условия дает false,

(... index < arraySize; ... ) (... iter != ivec.end(); ... ) (... *stl++ = *st2++; ... )

инструкция не выполняется ни разу. Правильные условия можно записать так:

(... char ch = getNextChar(); ... )

Выражение вычисляется после выполнения инструкции на каждой итерации цикла. Обычно его используют для модификации переменной, инициализированной в инструкции-инициализации. Если самое первое вычисление условия дает false,

( ...

...; ++-index )

( ...

...; ptr = ptr->next )

( ...

...; ++i, --j, ++cnt )

выражение не выполняется ни разу. Правильные выражения выглядят таким образом:

( ... ...; ) // пустое выражение

const int sz = 24;

 

int ia[ sz ];

 

vector<int> ivec( sz );

 

for ( int ix = 0; ix < sz; ++ix )

{

ivec[ ix ] = ix;

 

ia[ ix ]= ix;

 

Для приведенного ниже цикла for

}

порядок вычислений будет следующим:

1.инструкция-инициализации выполняется один раз перед началом цикла. В данном примере объявляется переменная ix, которая инициализируется значением 0.

2.Вычисляется условие. Если оно равно true, выполняется составная инструкция тела цикла. В нашем примере, пока ix меньше sz, значение ix присваивается элементам ivec[ix] и ia[ix]. Когда значением условия станет false, выполнение цикла прекратится. Если самое первое вычисление условия даст false, составная инструкция выполняться не будет.

3.Вычисляется выражение. Как правило, его используют для модификации переменной, фигурирующей в инструкции-инициализации и проверяемой в условии. В нашем примере ix увеличивается на 1.

С++ для начинающих

207

Эти три шага представляют собой полную итерацию цикла for. Теперь шаги 2 и 3 будут повторяться до тех пор, пока условие не станет равным false, т.е. ix окажется равным или большим sz.

В инструкции-инициализации можно определить несколько объектов, однако все они

for ( int ival = 0, *pi = &ia, &ri = val; ival < size;

++iva1, ++pi, ++ri )

должны быть одного типа, так как инструкция объявления допускается только одна:

// ...

Объявление объекта в условии гораздо труднее правильно использовать: такое объявление должно хотя бы раз дать значение false, иначе выполнение цикла никогда

#include <iostream>

int main()

{

for ( int ix = 0;

bool done = ix == 10; ++ix )

cout << "ix: " << ix << endl;

не прекратится. Вот пример, хотя и несколько надуманный:

}

Видимость всех объектов, определенных внутри круглых скобок инструкции for, ограничена телом цикла. Например, проверка iter после цикла вызовет ошибку

int main()

{

string word;

vector< string > text; // ...

for ( vector< string >::iterator iter = text.begin(), iter_end = text.end();

iter != text.end(); ++iter )

{

if ( *iter == word ) break;

// ...

}

// ошибка: iter и iter_end невидимы if ( iter != iter_end )

компиляции8:

8 До принятия стандарта языка С++ видимость объектов, определенных внутри круглых скобок for, простиралась на весь блок или функцию, содержащую данную инструкцию. Например, употребление двух циклов for внутри одного блока

Примечание [O.A.2]: Нумера ция сносок сбита, как и вся остальная. Необходима проверка.

С++ для начинающих

208

// ...

Упражнение 5.8

(a)

for ( int *ptr = &ia, ix = 0;

ix < size && ptr != ia+size; ++ix, ++ptr )

// ...

Допущены ли ошибки в нижеследующих циклах for? Если да, то какие?

(b)

for ( ; ; ) {

if ( some_condition ) break;

// ...

}

{

//верно для стандарта С++

//в предыдущих версиях C++ - ошибка: ival определена дважды for (int ival = 0; ival < size; ++iva1 ) // ...

for (int ival = size-1; ival > 0; ival ) // ...

}

в ранних версиях языка вызывало ошибку: ival определена дважды. В стандарте С++ данный текст синтаксически правилен, так как каждый экземпляр ival является локальным для своего блока.