
- •Максимов м.Н.
- •3. Скалярные типы и выражения 51
- •5. Адреса, указатели, массивы, память 95
- •6. Функции, указатели, ссылки 132
- •7 Структуры, объединения и классы 170
- •Введение
- •Модуль 1
- •1.2. Этапы подготовки исполняемой программы
- •1.3. Системы счисления
- •Представление чисел от 0 до 16 в разных системах счисления
- •2.1. Общие сведения о программах, лексемах и алфавите
- •2.2. Идентификаторы и служебные слова
- •2.3. Типы данных
- •2.4. Константы
- •Типы, выбираемые компилятором по умолчанию для целых констант
- •Данные вещественного типа
- •2.5. Операции
- •2.6. Разделители
- •3. Скалярные типы и выражения
- •3.1. Определение и описание переменных
- •3.2. Явное и неявное преобразование типа
- •Проектные задания
- •Тесты рубежного контроля
- •Квалиметрическая оценка
- •Список литературы
- •Модуль 2
- •4.1. Последовательно выполняемые операторы
- •4.2. Операторы выбора
- •If( выражение) оператор_1 else оператор_2
- •If( выражение) оператор_1
- •4.3. Операторы цикла
- •4.4. Операторы передачи управления
- •If (условие) break;
- •4.5. Примеры численного моделирования цепей первого порядка
- •5. Адреса, указатели, массивы, память
- •5.1. Указатели и адреса объектов
- •5.2. Адресная арифметика, типы указателей и операции над ними
- •5.3. Свойства указателя типа void*
- •5.4. Свойства объекта cout
- •5.5. Массивы и указатели
- •5.6. Многомерные массивы, массивы указателей, динамические массивы
- •Проектные задания к модулю
- •Тесты рубежного контроля
- •6.2. Функции с переменным количеством параметров
- •6.3. Рекурсивные функции
- •6.4. Подставляемые (инлайн-) функции
- •6.5. Функции и массивы
- •6.6. Указатели на функции
- •Void f3(float) (...) // Определение функции
- •Int* f4(char *){...} // Определение функции
- •Проектные задания
- •Тесты рубежного контроля
- •Квалиметрическая оценка
- •Модуль 4
- •7 Структуры, объединения и классы
- •7.1 Структура как тип и совокупность данных
- •7.3 Объединения разнотипных данных
- •7.4 Деревья
- •7.5 Битовые поля структур и объединений
- •7.6 Компонентные функции структурированных объектов
- •7.7 Расширение действия (перегрузка) стандартных операций
- •7.8 Доступ к компонентам структурированного объекта
- •7.9 Классы и шаблоны
- •Проектные задания
- •Тесты рубежного контроля
- •Квалиметрическая оценка
- •Список литературы
- •Приложение 1
- •Приложение 2 Стандартная библиотека функций языка Си
4.3. Операторы цикла
Операторы цикла задают многократное исполнение операторов тела цикла. Определены три разных оператора цикла:
цикл с предусловием и его блок-схема:
while(выражение_ условие) тело цикла
Рис. 4.5. Блок-схема цикла с предусловием
Цикл с постусловием и его блок-схема:
do
тело цикла
while (выражение_ условие);
Рис. 4.6. Блок-схема цикла с постусловием
Итерационный цикл и его блок-схема:
for(инициализация_цикла; выражение_условия; список выражений)
тело цикла
Рис. 4.7. Блок-схема итерационного цикла
Тело цикла это либо отдельный (в том числе пустой) оператор, который всегда завершается точкой с запятой, либо составной оператор, либо блок. Выражение условия – это скалярное или логическое выражение, определяющее условие продолжения итераций. Если значение выражения условия равно нулю, то итерации (многократное выполнения одних и тех же операторов, в данном случае выполнение операторов тела цикла) прекращаются, если не равно нулю итерации продолжаются.
Прекращение выполнения цикла возможно в следующих случаях:
нулевое значение проверяемого выражения;
выполнение в теле цикла оператора передачи управления (break; goto; return) за пределы цикла.
Последнюю из указанных возможностей проиллюстрируем позже, рассматривая особенности операторов передачи управления.
Оператор while называется оператором цикла с предусловием. При входе в цикл вычисляется выражение_условие. Если его значение отлично от нуля, то выполняется тело цикла. Затем снова проверяется выражение-условие и если его значение снова отлично от нуля, то опять выполняется тело цикла и т.д. до тех пор, пока значение выражения_условия не станет равным нулю. Если значение выражения_условия при проверке оказалось равным нулю, то управление передаётся на оператор, стоящий сразу за телом цикла. Приведём примеры программ с циклом предусловия:
//Программа 4.2
#include "stdafx.h"
#include <iostream>
//Подсчёт количества символов в строке
void main( ){
std::cout<<"\n Input string = ";
char buf[100];
std::cin>>buf;
long len =0;
while (buf[len])len++; /*Тело цикла – один оператор (len++) */
std::cout<<"\n The number of symbol are = "<<len;
getchar();
}
Как известно, строка в Си++ заканчивается нулевым символом. Поэтому, перебрав посимвольно всю строку и найдя нулевой символ, можно подсчитать количество символов в строке, что и делается с помощью цикла в примере.
Часто в качестве выражения условия в цикле может вступать логическое выражение. Например, следующая последовательность операторов вычисляет сумму квадратов первых N натуральных чисел (членов натурального ряда):
int i =0;
long s = 0;
long N = 6;
while(i < N) s+=++i*i;// Тело цикла - один оператор s+=++i*i;
cout<<s;
Цикл завершится тогда, когда логическое выражение i < N станет ложным.
Может ли цикл выполнятся бесконечно? Да, может. Во всяком случае до тех пор, пока программист искусственно с помощью горячих клавиш (Ctrl+Break) или выключения питания компьютера не прервёт его выполнение. Самым простым примером бесконечного цикла может служить такая запись:
while (1) ; // Бесконечный цикл с пустым оператором в качестве тела.
Поэтому значение выражения_условия не должно быть константой и должно меняться во время выполнения итераций.
Оператор
do тело цикла while (выражение _условие);
называется оператором цикла с постусловием. При входе в цикл с постусловием выполняется тело цикла. Затем вычисляется выражение_условие и если его значение не равно нулю, то вновь выполняется тело цикла. Если выражение_условие равно нулю, то управление передаётся следующему оператору за циклом в тексте программы. Таким образом, тело цикла с постусловием в любом случае выполняется хотя бы один раз.
Бесконечный цикл можно записать так:
do ; while(1);
Поэтому к выражению условия требования те же, что и для цикла while c предусловием – оно должно изменяться при итерациях либо за счёт операторов тела цикла, либо при вычислениях.
Оператор итерационного цикла for имеет формат:
for( инициализация_цикла; выражение_условие; список_выражений)
тело_цикла
где тело_цикла может быть блоком, отдельным оператором, составным оператором или пустым оператором; инициализация_цикла – последовательность определений (описаний) и выражений, разделяемых запятыми (чаще всего здесь устанавливаются начальные значения счётчиков и параметров цикла); выражение_условие – такое же, как и в циклах while и do: если оно равно нулю, то выполнение цикла прекращается; список_выражений – список выражений, записанных через запятую и выполняемых на каждой итерации.
Цикл for работает следующим образом: при входе в цикл происходит инициализация_цикла и проверка значения выражения_условия. Если оно истинно (не равно 0), выполняется тело_цикла, если нет управление передаётся оператору, стоящему сразу за телом цикла в программе. После выполнения тела цикла выполняется список_выражений, далее опять проверяется выражение_условие и по его значению определяется, делать новую итерацию или нет.
Цикл for можно записать, опустив и/или инициализацию_цикла, выражение_условие, список_выражений, в виде:
for ( ; ;); // бесконечный цикл с пустым оператором в качестве тела.
for ( ;1;); // бесконечный цикл с пустым оператором в качестве тела.
В этом случае точки с запятой должны оставаться. Значение выражения_условия считается равным единице.
Приведём примеры использования цикла for для решения задачи суммирования квадратов первых N членов натурального ряда:
for( int i =1, s = 0; i <= N; i++) s+= i*i ;
for ( int i = 0, s = 0; i <=N ; s +=++i*i);
for ( int i = 0, s = 0; i <=N ; s +=++i*i) s +=++i*i;
for ( int i = 0, s = 0; i <=N ; ) {
int j; j = ++ i; s +=j*j;
}
В проекте языка Си++ нет специальных соглашений относительно области действия имён, определенных в инициализирующей части оператора цикла. В конкретных реализациях компилятора принято, что область действия таких имён – от места размещения цикла for до конца блока, в котором этот цикл используется.
Разрешено и широко используется вложение любых циклов в любые циклы. Например, вывод на экран элементов квадратной матрицы может быть реализован с помощью вложенных циклов:
//Программа 4.3
#include "stdafx.h"
#include <iostream> //1
void main (){ //2
int A[3][3]; //3
for(int i = 0; i < 3; i++){/*4 Начало тела первого цикла*/
std::cout<<"\n"; //5
for(int k = 0; k < 3; k++) //6
std::cout<<"\t"<<(A[i][k]=i+k);/*7 Тело вложенного цикла */
} //8 Конец тела первого цикла
getchar();
} //9
В инициализации циклов определены переменные i и k. Область существования переменной i с 4 по 9 строку программы. Область существования переменной k – с 6 по 8 строку программы.