Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Доступ внутрь строк с помощью цикла for



Циклы

Цикл FOR

Часто, для выполнения программы требуется выполнение повторных действий.

Например сложение всех элементов массива один за другим поочередно.

Цикл for облегчает эту задачу.

#include < iostream>

int main()

{

using namespace std;

int i; // Создаем счетчик

 

//(Инициализация; проверка; обновление

for (i = 0; i < 5; i++){

   cout < < " C++ loops.\n";

}

cout < < " C++ knows when to stop.\n";

getchar();

return 0;

}

Ниже показан вывод программы:

C++ loops.

C++ loops.

C++ loops.

C++ loops.

C++ loops.

C++ knows when to stop.

 

for (i = 0; i < 5; i++)

   cout < < " C++ loops.\n";

или

for (i = 0; i < 5; i++){

   cout < < " C++ loops.\n";

   cout < < " C++ loops.\n";

}

Этот цикл начинается с присваивания целочисленной переменной i значения 0:

i = 0;

Это - часть инициализации цикла. Затем в части проверки цикла программа прове­ряет, меньше ли i числа 5:

i < 5;

Если это так, программа выполняет следующий оператор, который называется телом цикла:

cout < < " C++ knows loops.\n";

После этого программа активизирует часть обновления цикла, увеличивая i на 1:

i++

 

В части обновления цикла используется операция ++, которая называется операци­ей инкремента.

Она увеличивает значение своего операнда на 1. (Применение опера­ции инкремента не ограничено циклами for. Например, можно использовать i++; вместо i = i + 1; в качестве оператора программы.)

Инкрементирование i заверша­ет первый проход цикла.

 

Далее цикл начинает новый проход, сравнивая новое значение i с 5. Поскольку новое значение (1) также меньше 5, цикл печатает еще одну строку и завершается снова инкрементированием i.

Это подготавливает новый проход цикла — проверку, выполнение оператора и обновление значения i. Процесс продолжается до тех пор, пока не i не получит значение 5. После этого следующая проверка дает ложный ре­зультат, и программа переходит к оператору, следующему за циклом.

 

Части цикла for

Цикл for представляет собой средство пошагового выполнения повторяющихся действий. Устройство цикла. Обычно части цикла for выполняют следующие шаги.

1. Установка начального значения.

2. Выполнение проверки условия для продолжения цикла.

3. Выполнение действий цикла.

4. Обновление значения (значений), используемых в проверочном условии.

В структуре цикла C++ эти элементы расположены таким образом, чтобы их мож­но было охватить одним взглядом.

Инициализация, проверка и обновление составля­ют три части управляющего раздела, заключенного в круглые скобки. Каждая часть является выражением, отделяемым от других частей точкой с запятой. Оператор, следующий за управляющим разделом, называется телом цикла, и он выполняется до тех пор, пока проверочное условие остается истинным:

for(инициализация; проверочное выражение; обновляющее выражение) тело

 

Цикл выполняет инициализацию только однажды. Программы исполь­зуют это выражение для установки переменной в некоторое начальное значение, а потом применяют эту переменную в качестве счетчика цикла.

Проверочное выражение определяет, должно ли выполняться тело цикла. Это выражение представляет собой выражение сравнения - т.е. выражение, срав­нивающее два значения.

В примере сравниваются значения i и 5. Если про­верка проходит успешно (проверочное выражение истинно), программа выполняет тело цикла. На самом деле в C++ проверочные выражения не ограничиваются толь­ко сравнениями, дающими в результате true или false. Здесь можно использовать любое выражение, и C++ приведет его к типу bool.

Таким образом, выражение, воз­вращающее 0, преобразуется в булевское значение false, и цикл завершается. Если выражение оценивается как ненулевое, оно приводится к булевскому значению true, и цикл продолжается.

#include < iostream>

int main()

{

using namespace std;

cout < < " Enter the starting value: ";

int limit;

cin > > limit;

int i; //завершается, когда i равно О

for (i = limit; i; i--)

cout < < " i = " < < i < < " \n";

cout < < " Done now that i = " < < i < < " \n";

getchar();

return 0;

}

Цикл завершается, когда i достигает значения 0.

До появления типа bool срав­нивающие выражения вычислялись как 1 в случае истинности и 0 — в противопо­ложном случае.

Таким образом, значение выражения 3 < 5 было равно 1, а значение 5< 5 — равно 0.

Цикл for является циклом с входным условием. Это значит, что проверочное усло­вие выполняется перед каждым шагом цикла.

Цикл никогда не выполняет тело, если проверочное условие возвращает false.

Например, при  запуске программы 2 в качестве начального значения ввели 0. Поскольку проверочное условие не удовлетворено при первой же проверке, тело цикла не вы­полнится ни разу:

 

Enter the starting countdown value: 0

Done now that i = 0

Позиция “проверка перед циклом” может помочь предохранить программу от проблем.

Обновляющее выражение вычисляется в конце цикла, после того, как выполнено тело цикла. Обычно оно используется для увеличения или уменьшения значения пе­ременной, управляющей количеством шагов цикла. Однако оно может быть любым допустимым выражением C++, как и все остальные управляющие выражения. Это обеспечивает циклу for гораздо более широкие возможности, чем простой отсчет от 0 до 5, как делалось в первом примере.

Тело цикла for состоит из одного оператора, но вскоре вы увидите, как расширить это правило.

На рисунке показана блок-схема цикла for.

 

 

В C++ принят стиль помещения пробелов между for и последующими скобками, а также пропуск пробела между именем функции и следующими за ним скобками:

Другие управляющие операторы, такие как if и while, трактуются аналогично for. Это служит для визуального подчеркивания разницы между управляющим оператором и вызо­вом функции.

К тому же принято писать тело функции с отступом, чтобы выделить его визуально.

Выражения и операторы

Управляющий раздел for включает три выражения.

Любое значение или любая допустимая комбинация выражений и операций составляет вы­ражение.

Например, 10 — это выражение со значением 10, а

28 * 20 — выражение со значением 560. В C++ любое выражение имеет свое значе­ние. Часто оно вполне очевидно. Например, следующее выражение формируется из двух значений и операции сложения, и оно равно 49:

22 + 27

Иногда значение не столь очевидно. Например, показанный ниже код — это тоже выражение, потому что формируется из двух значений и операции присваивания:

X = 20

В C++ значение выражения присваивания определяется как значение его левой части, поэтому данное выражение имеет значение 20. Тот факт, что выражения при­сваивания имеют значения, означает, что допускаются операторы вроде такого:

maids = (cooks = 4) + 3;

Выражение cooks = 4 имеет значение 4, поэтому maids присваивается значение 7. Однако то, что C++ допускает подобное поведение, не значит, что вы должны зло­употреблять им. То же самое правило, которое разрешает такие специфические операторы, также означает, что разрешен следующий удобный оператор:

х = у = z = 0;

Это быстрый способ установки одного и того же значения нескольким перемен­ным. Согласно приоритету, присваивание ассоциируется справа налево, поэтому первый 0 присваивается z, затем z = 0 присваивается у и т.д.

И, наконец, выражения отношений, такие как х < у, вычисляются как значения true и false типа bool.

#include < iostream>

int main()

{

using namespace std;

int x;

 

cout < < " The x = 100 has the value ";

cout < < (x = 100) < < endl;

cout < < " Now x = " < < x < < endl;

cout < < " The x < 3 has the value ";

cout < < (x < 3) < < endl;

cout < < " The x > 3 has the value ";

cout < < (x > 3) < < endl;

cout.setf(ios_base:: boolalpha); //новое средство C++

cout < < " The x < 3 has the value ";

cout < < (x < 3) < < endl;

cout < < " The x > 3 has the value ";

cout < < (x > 3) < < endl;

getchar();

return 0;

}

 

От выражения до оператора программы один шаг; для этого достаточно добавить точку с запятой. То есть следующий код будет выражением:

age = 100

В то же время показанный ниже код является оператором:

age = 100;

Точнее, это оператор выражения . Любое выражение может стать оператором, если к нему добавить точку с запятой, но результат может не иметь смысла с точки зрения программы. Например, если rodents — переменная, то следующий код представляет собой допустимый оператор C++:

rodents + 6;

// допустимое, однако бессмысленное выражение

Компилятор разрешает такой оператор, но он не делает ничего полезного. Прог­рамма просто вычисляет сумму, ничего с ней не делает и переходит к следующему опе­ратору.

Не выражения и операторы

Некоторые концепции, такие как структуры или цикл for, являются ключевыми для понимания C++.

Но существуют также относительно менее значимые аспекты синтаксиса, которые иногда могут сбивать с толку, когда уже кажется, что язык впол­не понятен. Несколько из них мы сейчас рассмотрим.

Хотя утверждение о том, что добавление точки с запятой к любому выражению превращает его в оператор, справедливо, обратное не верно. То есть исключение точки с запятой из оператора не обязательно преобразует его в выражение. Из всех разновидностей операторов, которые мы рассмотрели до сих пор, операто­ры возврата, операторы объявления и операторы for не укладываются в правило оператор = выражение + точка с запятой. Например, вот оператор:

int load;

Однако фрагмент int load не является выражением и не имеет значения. Это делает следующий код некорректным:

 

eggs = int toad * 1000; //не верно, это — не выражение

cin > > int toad; // нельзя комбинировать объявление с cin

 

Подобным же образом нельзя присваивать цикл for переменной. В следующем примере цикл for — это не выражение, поэтому он не имеет значения, и присваи­вать его не разрешено:

int fx = for (i = 0; i< 4; i++)

cout > > i; // невозможно

 

Отклонения от правил

Язык C++ добавляет к циклам С возможность, которая требует некоторой поправ­ки к синтаксису цикла for. Исходный синтаксис выглядел следующим образом:

for ( выражение; выражение; выражение) оператор

В частности, управляющий раздел конструкции for состоял из трех выражений, разделенных точками с запятой, как это указывалось ранее в настоящей главе. Однако циклы C++ позволяют поступать так, как показано ниже:

for (int i = 0; i < 5; i ++)

To есть в области инициализации цикла for можно объявить переменную. Часто поступать подобным образом очень удобно, но это не вписывается в исходный син­таксис, поскольку объявление не является выражением. Это единственное незаконное поведение, которое подгонялось под правила за счет определения нового вида выра­жений — выражения оператора объявления, которое представляло собой объявление без точки с запятой и могло встречаться только в операторе for.

С объявлением переменной внутри for связан один практический аспект, о котором вы должны знать. Такая переменная существует только внутри оператора for. То есть после того, как программа покидает цикл, пе­ременная исчезает:

for (int i = 0; i < 5; i++)

cout < < " C + + knows loop.\n";

cout < < i < < endl; //переменная i больше не определена

 

 

 Код в лис­тинге далее использует цикл для вычисления и сохранения первых 16 факториалов. Факториалы, которые являются удобным примером автоматизации обработки, вы­числяются следующим образом.

Ноль факториал, записываемый как 0!, определен как равный 1.

Далее, 1! равен 1*0!, т.е. 1.

2! равно 2*1!, или 2.

3! равно 3*2!, или 6, и т.д.

То есть факториал каждого целого числа равен произведению этого числа на факториал предыдущего числа. В программе один цикл используется для вычисления значений последовательных факториалов, с сохранением их в массиве. Второй цикл служит для отображения результатов. Также программа демонстрирует применение внешних объявлений для значений.

#include < iostream>

const int ArSize = 16;      

int main()

{

using namespace std;

long long factorials[ArSize];

factorials[1] = factorials[0] = 1LL;

for (int i = 2; i < ArSize; i++)

   factorials[i] = i * factorials[i-1];

for (int i = 0; i < ArSize; i++)

   cout < < i < < "! = " < < factorials[i] < < endl;

getchar();

return 0;

}

Цикл иллюстрирует возможность применения счетчика цикла в его теле как переменной.

Программа из листинга демонстрирует, как цикл for работает рука об руку с массивами, предоставляя удобное средство доступа к каждому члену массива по оче­реди. К тому же используется const для создания символического представления (ArSize) для размера массива.

После этого ArSize применяется вез­де, где вступает в игру размер массива — в определении массива, а также в выраже­нии, ограничивающем количество шагов циклов, обрабатывающих массив.

Если те­перь вы решите расширить программу для вычисления, скажем, 20 факториалов, для этого понадобится только установить ArSize в 20 и перекомпилировать программу. Благодаря использованию символической константы, вы избегаете необходимости изменять индивидуально каждое вхождение 16 на 20.

Ограничивающее выражение i < ArSize отражает тот факт, что индексы эле­ментов массива лежат в пределах от 0 до ArSize - 1, т.е. значение индекса должно останавливаться за один шаг до достижения ArSize. Вместо него можно было бы ис­пользовать проверочное условие i < = ArSize - 1.

 

Изменение шага цикла

До сих пор в примерах циклов счетчик цикла увеличивался или уменьшался на единицу на каждом шаге. Это можно изменить, модифицировав обновляющее выра­жение. Программа в листинге ниже, например, увеличивает счетчик цикла на величину введенного пользователем шага. Вместо применения i ++ в качестве обновляющего выражения она использует выражение

i = i + by, где by — выбранный пользовате­лем шаг цикла.

 

#include < iostream>

int main()

{

using namespace std;    

cout < < " Enter an integer: ";

int by;

cin > > by;

cout < < " Counting by " < < by < < " s: \n";

for (int i = 0; i < 100; i = i + by)

   cout < < i < < endl;

   

getchar();

getchar();

return 0;

}

 

Главное, на что здесь нужно обратить внимание: в качестве обновляющего выражения можно использовать любое допустимое выражение. Например, если вы захотите на каждом шаге цикла возводить в квадрат и прибавлять 10, можете воспользоваться выражением

i = i * i + 10

Другой момент, который следует отметить: часто лучше проверять на предмет не­равенства, чем равенства. Например, проверка i = = 100 в этом примере не подой­дет, поскольку i перепрыгивает через значение 100.

Выражения отношений

Компьютеры — это нечто большее, чем неутомимые обработчики чисел. Они так­же умеют сравнивать значения, и эта их способность лежит в основе автоматическо­го принятия решений. В C++ эту возможность реализуют операции отношений. В C++ доступны шесть операций отношений для сравнения чисел.

Поскольку символы пред­ставлены своими ASCII-кодами, эти операции можно также применять и для срав­нения символов. Они не работают со строками в стиле С, но работают с объектами класса string.

Каждое сравнивающее выражение возвращает булевское (типа bool) значение true, если сравнение истинно, и false — в противном случае, поэтому дан­ные операции хорошо подходят для применения в проверочных условиях циклов. (Старые реализации оценивали истинные выражения как 1 и ложные — как 0.)

Этими шестью операциями отношений исчерпываются все возможности, преду­смотренные в C++ для сравнения чисел.

 

 

 

 


 


Цикл while

Цикл while - это цикл for, у которого удалены инициализирующая и обновляю­щая части; в нем имеется только проверочное условие и тело:

while (проверочное_условие)

тело

 

Сначала программа вычисляет выражение проверочное_условие в скобках. Если выражение дает в результате true, программа выполняет оператор (или операторы), содержащийся в теле цикла. Как и в случае с циклом for, тело состоит из единст­венного оператора либо блока, определенного фигурными скобками. После того, как завершено выполнение тела, программа возвращается к проверочному условию и за­ново вычисляет его. Если условие возвращает ненулевое значение, программа снова выполняет тело.

Этот цикл проверки и выполнения продолжается до тех пор, пока проверочное условие не вернет false.

Если вы хотите в ко­нечном итоге прервать цикл, то в теле цикла должно происходить нечто такое, что повлияет на выражение проверочного условия. Например, цикл может увеличивать значение переменной, используемой в проверочном условии, либо читать новое зна­чение, вводимое с клавиатуры. Подобно for, цикл while является циклом с входным условием. То есть, если проверочное условие оценивается как false в самом начале, то программа ни разу не выполнит тело цикла.

 

 

В листинге представлен пример работы цикла while. Цикл проходит по всем символам строки и отображает их ASCII-коды. По достижении нулевого символа цикл завершается. Эта техника прохода по символам строки до нулевого ограничителя является стандартным методом обработки строк в C++. Поскольку строка содержит маркер конца, программа часто не нуждается в явной информации о длине строки.

 

 

#include < iostream>

const int ArSize = 20;

int main()

{

using namespace std;

char name[ArSize];

 

cout < < " Your first name, please: ";

cin > > name;

cout < < " Here is your name, verticalized and ASCIIized: \n";

int i = 0; // start at beginning of string

while (name[i]! = '\0')

{

   cout < < name[i] < < ": " < < int(name[i]);

 cout < < endl;

   i++; // don't forget this step

}

 

getchar();

getchar();

return 0;

}

Оператор (ы)

}

может быть переписан так:

инициализирующее -выражение;

while ( проверочное-выражение)

{

Оператор (ы)

обновляющее -выражение;

}

Аналогично, представленный ниже цикл while:

Тело

можно переписать так:

for (; проверочное-выражение; ) тело

 

Цикл for требует трех выражений (или, формально, одного оператора и следую­щих за ним двух выражений), но они могут быть пустыми выражениями (или опера­торами).

Обязательны только два знака точки с запятой. Кстати, пропуск провероч­ного выражения в цикле for трактуется как true, поэтому следующий цикл будет продолжаться бесконечно:

for (; ; ) тело

Поскольку циклы for и while почти эквивалентны, какой именно использовать — в основном, вопрос стиля. Есть три отличия.

Одно из них, как уже упоминалось, за­ключается в том, что пропущенное условие проверки в цикле for интерпретируется как true.

Второе отличие связано с возможностью использования оператора инициа­лизации в цикле for для объявления переменной, которая будет локальной в цикле; в цикле while это сделать не получится.

Наконец, существует небольшое отличие, ко­гда тело цикла содержит оператор continue. Обычно про­граммисты применяют циклы for для циклов со счетчиками, потому что формат for позволяет держать всю необходимую информацию — начальное значение, конечное значение и метод обновления счетчика — в одном месте. Цикл while используется, когда заранее не известно, сколько раз будет выполняться цикл.

При проектировании цикла необходимо руководствоваться следующими указаниями:

· Идентифицировать условие завершения цикла.

· Инициализировать это условие перед первой проверкой.

· Обновлять условие на каждом шаге цикла, прежде чем оно будет проверено вновь.

 

Цикл do while

К этому моменту вы ознакомились с двумя циклами — for и while. Третьим цик­лом в C++ является do while. Он отличается от двух других тем, что осуществляет проверку на выходе. Это значит, что такой цикл вида “кто его знает” сначала выпол­нит свое тело и только потом оценит проверочное условие, чтобы узнать, нужно ли продолжать дальше. Если условие оценивается как false, цикл завершается; в про­тивном случае выполняется новый шаг с последующей проверкой условия. Такой цикл всегда выполняется, как минимум, один раз, потому что поток управления программы проходит через его тело до того, как достигает проверочного условия. Синтаксис цикла do while показан ниже:

 

do

тело

while (проверочное-выражение);

 

Часть тело может быть единственным оператором либо блоком операторов, заключенным в фигурные скобки. На рисунке показан поток управления в цикле do while.

Обычно цикл с проверкой на входе — лучший выбор, нежели цикл с проверкой на выходе, т.к. проверка выполняется до его запуска.

 

Задачи.

№5

Напишите программу, в которой пользователь будет вводить числа с клавиатуры, пока не введет заранее заданное в условии «Любимое число» из некого заданного диапазона(от 1 до 20).

№6

Напишите программу, которая приглашает пользователя вводить числа. После каждого введенного значения программа должна выдавать накопленную сумму введенных значений. Программа должна завершаться при вводе 0.

Циклы

Цикл FOR

Часто, для выполнения программы требуется выполнение повторных действий.

Например сложение всех элементов массива один за другим поочередно.

Цикл for облегчает эту задачу.

#include < iostream>

int main()

{

using namespace std;

int i; // Создаем счетчик

 

//(Инициализация; проверка; обновление

for (i = 0; i < 5; i++){

   cout < < " C++ loops.\n";

}

cout < < " C++ knows when to stop.\n";

getchar();

return 0;

}

Ниже показан вывод программы:

C++ loops.

C++ loops.

C++ loops.

C++ loops.

C++ loops.

C++ knows when to stop.

 

for (i = 0; i < 5; i++)

   cout < < " C++ loops.\n";

или

for (i = 0; i < 5; i++){

   cout < < " C++ loops.\n";

   cout < < " C++ loops.\n";

}

Этот цикл начинается с присваивания целочисленной переменной i значения 0:

i = 0;

Это - часть инициализации цикла. Затем в части проверки цикла программа прове­ряет, меньше ли i числа 5:

i < 5;

Если это так, программа выполняет следующий оператор, который называется телом цикла:

cout < < " C++ knows loops.\n";

После этого программа активизирует часть обновления цикла, увеличивая i на 1:

i++

 

В части обновления цикла используется операция ++, которая называется операци­ей инкремента.

Она увеличивает значение своего операнда на 1. (Применение опера­ции инкремента не ограничено циклами for. Например, можно использовать i++; вместо i = i + 1; в качестве оператора программы.)

Инкрементирование i заверша­ет первый проход цикла.

 

Далее цикл начинает новый проход, сравнивая новое значение i с 5. Поскольку новое значение (1) также меньше 5, цикл печатает еще одну строку и завершается снова инкрементированием i.

Это подготавливает новый проход цикла — проверку, выполнение оператора и обновление значения i. Процесс продолжается до тех пор, пока не i не получит значение 5. После этого следующая проверка дает ложный ре­зультат, и программа переходит к оператору, следующему за циклом.

 

Части цикла for

Цикл for представляет собой средство пошагового выполнения повторяющихся действий. Устройство цикла. Обычно части цикла for выполняют следующие шаги.

1. Установка начального значения.

2. Выполнение проверки условия для продолжения цикла.

3. Выполнение действий цикла.

4. Обновление значения (значений), используемых в проверочном условии.

В структуре цикла C++ эти элементы расположены таким образом, чтобы их мож­но было охватить одним взглядом.

Инициализация, проверка и обновление составля­ют три части управляющего раздела, заключенного в круглые скобки. Каждая часть является выражением, отделяемым от других частей точкой с запятой. Оператор, следующий за управляющим разделом, называется телом цикла, и он выполняется до тех пор, пока проверочное условие остается истинным:

for(инициализация; проверочное выражение; обновляющее выражение) тело

 

Цикл выполняет инициализацию только однажды. Программы исполь­зуют это выражение для установки переменной в некоторое начальное значение, а потом применяют эту переменную в качестве счетчика цикла.

Проверочное выражение определяет, должно ли выполняться тело цикла. Это выражение представляет собой выражение сравнения - т.е. выражение, срав­нивающее два значения.

В примере сравниваются значения i и 5. Если про­верка проходит успешно (проверочное выражение истинно), программа выполняет тело цикла. На самом деле в C++ проверочные выражения не ограничиваются толь­ко сравнениями, дающими в результате true или false. Здесь можно использовать любое выражение, и C++ приведет его к типу bool.

Таким образом, выражение, воз­вращающее 0, преобразуется в булевское значение false, и цикл завершается. Если выражение оценивается как ненулевое, оно приводится к булевскому значению true, и цикл продолжается.

#include < iostream>

int main()

{

using namespace std;

cout < < " Enter the starting value: ";

int limit;

cin > > limit;

int i; //завершается, когда i равно О

for (i = limit; i; i--)

cout < < " i = " < < i < < " \n";

cout < < " Done now that i = " < < i < < " \n";

getchar();

return 0;

}

Цикл завершается, когда i достигает значения 0.

До появления типа bool срав­нивающие выражения вычислялись как 1 в случае истинности и 0 — в противопо­ложном случае.

Таким образом, значение выражения 3 < 5 было равно 1, а значение 5< 5 — равно 0.

Цикл for является циклом с входным условием. Это значит, что проверочное усло­вие выполняется перед каждым шагом цикла.

Цикл никогда не выполняет тело, если проверочное условие возвращает false.

Например, при  запуске программы 2 в качестве начального значения ввели 0. Поскольку проверочное условие не удовлетворено при первой же проверке, тело цикла не вы­полнится ни разу:

 

Enter the starting countdown value: 0

Done now that i = 0

Позиция “проверка перед циклом” может помочь предохранить программу от проблем.

Обновляющее выражение вычисляется в конце цикла, после того, как выполнено тело цикла. Обычно оно используется для увеличения или уменьшения значения пе­ременной, управляющей количеством шагов цикла. Однако оно может быть любым допустимым выражением C++, как и все остальные управляющие выражения. Это обеспечивает циклу for гораздо более широкие возможности, чем простой отсчет от 0 до 5, как делалось в первом примере.

Тело цикла for состоит из одного оператора, но вскоре вы увидите, как расширить это правило.

На рисунке показана блок-схема цикла for.

 

 

В C++ принят стиль помещения пробелов между for и последующими скобками, а также пропуск пробела между именем функции и следующими за ним скобками:

Другие управляющие операторы, такие как if и while, трактуются аналогично for. Это служит для визуального подчеркивания разницы между управляющим оператором и вызо­вом функции.

К тому же принято писать тело функции с отступом, чтобы выделить его визуально.

Выражения и операторы

Управляющий раздел for включает три выражения.

Любое значение или любая допустимая комбинация выражений и операций составляет вы­ражение.

Например, 10 — это выражение со значением 10, а

28 * 20 — выражение со значением 560. В C++ любое выражение имеет свое значе­ние. Часто оно вполне очевидно. Например, следующее выражение формируется из двух значений и операции сложения, и оно равно 49:

22 + 27

Иногда значение не столь очевидно. Например, показанный ниже код — это тоже выражение, потому что формируется из двух значений и операции присваивания:

X = 20

В C++ значение выражения присваивания определяется как значение его левой части, поэтому данное выражение имеет значение 20. Тот факт, что выражения при­сваивания имеют значения, означает, что допускаются операторы вроде такого:

maids = (cooks = 4) + 3;

Выражение cooks = 4 имеет значение 4, поэтому maids присваивается значение 7. Однако то, что C++ допускает подобное поведение, не значит, что вы должны зло­употреблять им. То же самое правило, которое разрешает такие специфические операторы, также означает, что разрешен следующий удобный оператор:

х = у = z = 0;

Это быстрый способ установки одного и того же значения нескольким перемен­ным. Согласно приоритету, присваивание ассоциируется справа налево, поэтому первый 0 присваивается z, затем z = 0 присваивается у и т.д.

И, наконец, выражения отношений, такие как х < у, вычисляются как значения true и false типа bool.

#include < iostream>

int main()

{

using namespace std;

int x;

 

cout < < " The x = 100 has the value ";

cout < < (x = 100) < < endl;

cout < < " Now x = " < < x < < endl;

cout < < " The x < 3 has the value ";

cout < < (x < 3) < < endl;

cout < < " The x > 3 has the value ";

cout < < (x > 3) < < endl;

cout.setf(ios_base:: boolalpha); //новое средство C++

cout < < " The x < 3 has the value ";

cout < < (x < 3) < < endl;

cout < < " The x > 3 has the value ";

cout < < (x > 3) < < endl;

getchar();

return 0;

}

 

От выражения до оператора программы один шаг; для этого достаточно добавить точку с запятой. То есть следующий код будет выражением:

age = 100

В то же время показанный ниже код является оператором:

age = 100;

Точнее, это оператор выражения . Любое выражение может стать оператором, если к нему добавить точку с запятой, но результат может не иметь смысла с точки зрения программы. Например, если rodents — переменная, то следующий код представляет собой допустимый оператор C++:

rodents + 6;

// допустимое, однако бессмысленное выражение

Компилятор разрешает такой оператор, но он не делает ничего полезного. Прог­рамма просто вычисляет сумму, ничего с ней не делает и переходит к следующему опе­ратору.

Не выражения и операторы

Некоторые концепции, такие как структуры или цикл for, являются ключевыми для понимания C++.

Но существуют также относительно менее значимые аспекты синтаксиса, которые иногда могут сбивать с толку, когда уже кажется, что язык впол­не понятен. Несколько из них мы сейчас рассмотрим.

Хотя утверждение о том, что добавление точки с запятой к любому выражению превращает его в оператор, справедливо, обратное не верно. То есть исключение точки с запятой из оператора не обязательно преобразует его в выражение. Из всех разновидностей операторов, которые мы рассмотрели до сих пор, операто­ры возврата, операторы объявления и операторы for не укладываются в правило оператор = выражение + точка с запятой. Например, вот оператор:

int load;

Однако фрагмент int load не является выражением и не имеет значения. Это делает следующий код некорректным:

 

eggs = int toad * 1000; //не верно, это — не выражение

cin > > int toad; // нельзя комбинировать объявление с cin

 

Подобным же образом нельзя присваивать цикл for переменной. В следующем примере цикл for — это не выражение, поэтому он не имеет значения, и присваи­вать его не разрешено:

int fx = for (i = 0; i< 4; i++)

cout > > i; // невозможно

 

Отклонения от правил

Язык C++ добавляет к циклам С возможность, которая требует некоторой поправ­ки к синтаксису цикла for. Исходный синтаксис выглядел следующим образом:

for ( выражение; выражение; выражение) оператор

В частности, управляющий раздел конструкции for состоял из трех выражений, разделенных точками с запятой, как это указывалось ранее в настоящей главе. Однако циклы C++ позволяют поступать так, как показано ниже:

for (int i = 0; i < 5; i ++)

To есть в области инициализации цикла for можно объявить переменную. Часто поступать подобным образом очень удобно, но это не вписывается в исходный син­таксис, поскольку объявление не является выражением. Это единственное незаконное поведение, которое подгонялось под правила за счет определения нового вида выра­жений — выражения оператора объявления, которое представляло собой объявление без точки с запятой и могло встречаться только в операторе for.

С объявлением переменной внутри for связан один практический аспект, о котором вы должны знать. Такая переменная существует только внутри оператора for. То есть после того, как программа покидает цикл, пе­ременная исчезает:

for (int i = 0; i < 5; i++)

cout < < " C + + knows loop.\n";

cout < < i < < endl; //переменная i больше не определена

 

 

 Код в лис­тинге далее использует цикл для вычисления и сохранения первых 16 факториалов. Факториалы, которые являются удобным примером автоматизации обработки, вы­числяются следующим образом.

Ноль факториал, записываемый как 0!, определен как равный 1.

Далее, 1! равен 1*0!, т.е. 1.

2! равно 2*1!, или 2.

3! равно 3*2!, или 6, и т.д.

То есть факториал каждого целого числа равен произведению этого числа на факториал предыдущего числа. В программе один цикл используется для вычисления значений последовательных факториалов, с сохранением их в массиве. Второй цикл служит для отображения результатов. Также программа демонстрирует применение внешних объявлений для значений.

#include < iostream>

const int ArSize = 16;      

int main()

{

using namespace std;

long long factorials[ArSize];

factorials[1] = factorials[0] = 1LL;

for (int i = 2; i < ArSize; i++)

   factorials[i] = i * factorials[i-1];

for (int i = 0; i < ArSize; i++)

   cout < < i < < "! = " < < factorials[i] < < endl;

getchar();

return 0;

}

Цикл иллюстрирует возможность применения счетчика цикла в его теле как переменной.

Программа из листинга демонстрирует, как цикл for работает рука об руку с массивами, предоставляя удобное средство доступа к каждому члену массива по оче­реди. К тому же используется const для создания символического представления (ArSize) для размера массива.

После этого ArSize применяется вез­де, где вступает в игру размер массива — в определении массива, а также в выраже­нии, ограничивающем количество шагов циклов, обрабатывающих массив.

Если те­перь вы решите расширить программу для вычисления, скажем, 20 факториалов, для этого понадобится только установить ArSize в 20 и перекомпилировать программу. Благодаря использованию символической константы, вы избегаете необходимости изменять индивидуально каждое вхождение 16 на 20.

Ограничивающее выражение i < ArSize отражает тот факт, что индексы эле­ментов массива лежат в пределах от 0 до ArSize - 1, т.е. значение индекса должно останавливаться за один шаг до достижения ArSize. Вместо него можно было бы ис­пользовать проверочное условие i < = ArSize - 1.

 

Изменение шага цикла

До сих пор в примерах циклов счетчик цикла увеличивался или уменьшался на единицу на каждом шаге. Это можно изменить, модифицировав обновляющее выра­жение. Программа в листинге ниже, например, увеличивает счетчик цикла на величину введенного пользователем шага. Вместо применения i ++ в качестве обновляющего выражения она использует выражение

i = i + by, где by — выбранный пользовате­лем шаг цикла.

 

#include < iostream>

int main()

{

using namespace std;    

cout < < " Enter an integer: ";

int by;

cin > > by;

cout < < " Counting by " < < by < < " s: \n";

for (int i = 0; i < 100; i = i + by)

   cout < < i < < endl;

   

getchar();

getchar();

return 0;

}

 

Главное, на что здесь нужно обратить внимание: в качестве обновляющего выражения можно использовать любое допустимое выражение. Например, если вы захотите на каждом шаге цикла возводить в квадрат и прибавлять 10, можете воспользоваться выражением

i = i * i + 10

Другой момент, который следует отметить: часто лучше проверять на предмет не­равенства, чем равенства. Например, проверка i = = 100 в этом примере не подой­дет, поскольку i перепрыгивает через значение 100.

Доступ внутрь строк с помощью цикла for

Цикл for предоставляет прямой способ доступа к каждому символу в строке. Например, программа в листинге позволяет ввести строку и отобразить ее символ за символом в обратном порядке. В этом примере можно использовать либо объект класса string, либо массив char, потому что оба позволяют применять нотацию мас­сивов для доступа к индивидуальным символам строки. В листинге применяется объект класса string. Метод size () класса string возвращает количество символов в строке; цикл использует это значение в выражении инициализации для установки i в индекс последнего символа строки, исключая нулевой символ.

Для выполнения об­ратного отсчета в программе применяется операция декремента (— —), уменьшающая значение индекса массива на каждом шаге цикла. Также в листинге используется операция сравнения “больше или равно” (> =), чтобы проверить, достигли цикл пер­вого элемента.

#include < iostream>

#include < string>

int main()

{

using namespace std;

cout < < " Enter a word: ";

string word;

cin > > word;

// Отображение символов в обратном порядке

for (int i = word.size() - 1; i > = 0; i--)

   cout < < word[i];

cout < < " \nBye.\n";

 

getchar();

getchar();

return 0;

}

 

 


Поделиться:



Последнее изменение этой страницы: 2019-04-09; Просмотров: 143; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.288 с.)
Главная | Случайная страница | Обратная связь