(... *stl++ = *st2++; ... )
(... char ch = getNextChar(); ... )
Выражение вычисляется после выполнения инструкции на каждой итерации цикла. Обычно его используют для модификации переменной, инициализированной в инструкции-инициализации. Если самое первое вычисление условия дает false, выражение не выполняется ни разу. Правильные выражения выглядят таким образом:
( ... ...; ++-index )
( ... ...; ptr = ptr-next )
( ... ...; ++i, --j, ++cnt )
( ... ...; ) // пустое выражение
Для приведенного ниже цикла for
const int sz = 24;
int ia[ sz ];
vectorint ivec( sz );
for ( int ix = 0; ix sz; ++ix ) {
ivec[ ix ] = ix;
ia[ ix ]= ix;
}
порядок вычислений будет следующим:
* инструкция-инициализации выполняется один раз перед началом цикла. В данном примере объявляется переменная ix, которая инициализируется значением 0.
* Вычисляется условие. Если оно равно true, выполняется составная инструкция тела цикла. В нашем примере, пока ix меньше sz, значение ix присваивается элементам ivec[ix] и ia[ix]. Когда значением условия станет false, выполнение цикла прекратится. Если самое первое вычисление условия даст false, составная инструкция выполняться не будет.
* Вычисляется выражение. Как правило, его используют для модификации переменной, фигурирующей в инструкции-инициализации и проверяемой в условии. В нашем примере ix увеличивается на 1.
Эти три шага представляют собой полную итерацию цикла 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 )
// ...
Допущены ли ошибки в нижеследующих циклах for? Если да, то какие?
(a)
for ( int *ptr = ia, ix = 0;
ix size ptr != ia+size;
++ix, ++ptr )
// ...
(b)
for ( ; ; ) {
if ( some_condition )
break;
// ...
}
(c)
for ( int ix = 0; ix sz; ++ix )
// ...
if ( ix != sz )
// ...
(d)
int ix;
for ( ix sz; ++ix )
// ...
(e)
for ( int ix = 0; ix sz; ++ix, ++ sz )
// ...
Представьте, что вам поручено придумать общий стиль использования цикла for в вашем проекте. Объясните и проиллюстрируйте примерами правила использования каждой из трех частей цикла.
Дано объявление функции:
bool is_equa1( const vectorint vl,
const vectorint v2 );
Напишите тело функции, определяющей равенство двух векторов. Для векторов разной длины сравнивайте только то количество элементов, которое соответствует меньшему из двух. Например, векторы (0,1,1,2) и (0,1,1,2,3,5,8) считаются равными. Длину векторов можно узнать с помощью функций v1.size() и v2.size().
5.6. Инструкция while
Синтаксис инструкции while следующий:
while ( условие )
инструкция
Пока значением условия является true, инструкция выполняется в такой последовательности:
* Вычислить условие.
* Выполнить инструкцию, если условие истинно.
* Если самое первое вычисление условия дает false, инструкция не выполняется.
Условием может быть любое выражение:
bool quit = false;
// ...
while ( ! quit ) {
// ...