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 ) {
// ...
quit = do_something();
}
string word;
while ( cin word ){ ... }
или объявление с инициализацией:
while ( symbol *ptr = search( name )) {
// что-то сделать
}
В последнем случае ptr видим только в блоке, соответствующем инструкции while, как это было и для инструкций for и switch.
Вот пример цикла while, обходящего множество элементов, адресуемых двумя указателями:
int sumit( int *parray_begin, int *parray_end )
{
int sum = 0;
if ( ! parray_begin || ! parray_end )
return sum;
while ( parray_begin != parray_end )
// прибавить к sum
// и увеличить указатель
sum += *parray_begin++;
return sum;
}
int ia[6] = { 0, 1, 2, 3, 4, 5 };
int main()
{
int sum = sumit( ia[0], ia[ 6 ] );
// ...
}
Для того чтобы функция sumit() выполнялась правильно, оба указателя должны адресовать элементы одного и того же массива (parray_end может указывать на элемент, следующий за последним). В противном случае sumit() будет возвращать бессмысленную величину. Увы, С++ не гарантирует, что два указателя адресуют один и тот же массив. Как мы увидим в главе 12, стандартные универсальные алгоритмы реализованы подобным же образом, они принимают параметрами указатели на первый и последний элементы массива.
Какие ошибки допущены в следующих циклах while:
(a)
string bufString, word;
while ( cin bufString word )
// ...
(b)
while ( vectorint::iterator iter != ivec.end() )
// ...
(c)
while ( ptr = 0 )
ptr = find_a_value();
(d)
while ( bool status = find( word )) {
word = get_next_word();
if ( word.empty() )
break;
// ...
}
if ( ! status )
cout "Слов не найдено\n";
while обычно применяется для циклов, выполняющихся, пока некоторое условие истинно, например, читать следующее значение, пока не будет достигнут конец файла. for обычно рассматривается как пошаговый цикл: индекс пробегает по определенному диапазону значений. Напишите по одному типичному примеру for и while, а затем измените их, используя цикл другого типа. Если бы вам нужно было выбрать для постоянной работы только один из этих типов, какой бы вы выбрали? Почему?