Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ТП лекции Раздел 4.doc
Скачиваний:
16
Добавлен:
28.09.2019
Размер:
2.56 Mб
Скачать

Операторы циклов

Три оператора цикла могут быть описаны следующей схемой:

while (условие) {тело цикла}

do {тело цикла} while (условие);

for ( ; ; ) {тело цикла}

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

while(0) {тело цикла} //Тело цикла не выполнится ни разу

while (1) {тело цикла} //Бесконечный цикл

do {тело цикла} while(0); // Тело выполнится 1 раз

Тело цикла do {...} while (): обязательно выполнится хотя бы один раз, так как решение о продолжении цикла принимается после каждого прохода (выпол­нения оператора(ов) тела цикла).

Если известно заранее, сколько раз надо повторять цикл, то удобно приме­нять цикл for. Цикл for является очень мощным, гибким и часто используемым опера­тором языка С++. Прежде всего, обратите внимание на наличие трех групп в заголовке цикла for( ; ; ). Они разделены точкой с занятой. В первой группе заголовка могут быть пере­числены через запятую операторы, которые следует выполнить до входа в цикл, то есть один раз. Во второй части указывается условие продолжения цикла. В третьей группе перечисляются операторы, выполняемые в конце цикла (много раз). После заголовка следует тело цикла. Но выполняется оно до операторов третьей груп­пы. Здесь справедливо вышеупомянутое правило: если в теле более одного опе­ратора, то оно должно быть заключено в блок, ограниченный фигурными скоб­ками. Тело цикла может быть игнорировано (не выполнено ни разу), если условие нарушено при первом же входе в цикл. Условие продолжения проверяется до выполнения операторов тела цикла. Следует не пожалеть времени и хорошо за­помнить последовательность выполнения операторов при реализации цикла:

  1. Операторы первой части заголовка (выполняются один раз до входа в цикл).

  2. Вторая часть (проверка условия и выход из цикла в случае его нарушения).

  3. Операторы тела цикла.

  4. Операторы третьей части заголовка.

  5. Переход к пункту 2.

Высокий потенциал оператора for определяется тем, что в первой и третьей группах может быть несколько операторов и они могут быть достаточно сложными, а во второй части может быть логическое выражение любой сложности.

Тема 4.4. Разработка векторных структур данных в Visual C++.

4.4.1. Статические одномерные массивы.

При объявлении указателя задается тип переменных, на которые он может ука­зывать. Это кажется лишним, так как указатель любого типа в Win32 — 4 байта, содержащие адрес какого-либо объекта в памяти. Но все дело в том, что с указа­телями связана адресная арифметика, правила которой различны для разных типов указателей. Так, если к указателю на тип int прибавить единицу, то его значение изменится на 4 байта или sizeof(int). Это же действие в Win16 приве­дет к увеличению указателя на 2 байта. Забегая вперед, скажем, что при увели­чении указателя на массив объектов какого-либо класса (например, класса Man) указатель сдвинется в памяти ровно на один объект этого класса, независимо от того, сколько памяти он занимает.

Имя массива в языке С фактически является указателем на первый его эле­мент, который соответствует нулевому значению индекса (или индексов в слу­чае многомерных массивов). Если объявлен массив float a[16];, то справедливо равенство а==&а[0]. Переменные типа «указатель» могут быть использованы и часто используются для доступа к элементам массива. Рассмотрим пример, в ко­тором совместно используются массив переменных вещественного типа и указа­тель на переменные этого же типа. Имеют смысл следующие присвоения:

float a[16],*p; // Объявление массива и указателя for (int i=0; i<16; i++)

a[i]=float(i*i); //Заполнение массива p = &а[6]; //p указывает на а[6] *р = 3.14f; // Равносильно а[6] = 3.14; p++; // Теперь р указывает на а[7]. Произошел сдвиг на 4 байта а[1] = *(р+3); // Равносильно а[1] = а[10]; В а[1] попадает 100 а[2] = ++*р; //Равносильно а[2] = ++а[7]; В а[2] попадает 50 а[3] = *++р; //Равносильно а[3] = а[8]; В а[3] попадает 64

Адресная арифметика, например р+3 или ++р, осуществляется в единицах объяв­ленного базового типа данных float. Если в конкретной вычислительной систе­ме число типа float занимает 4 байта, то результатом операции р+3 будет адрес, отстоящий от р на 12 байтов. Значение ++*р вычисляется так: сначала выбирает­ся (*р) — содержимое по адресу р, то есть а[7], так как в данный момент указа­тель содержит &а[7]. Затем выполняется приращение (increment) a[7], то есть увеличение а[7] на единицу. При вычислении *++р, наоборот, сначала произво­дится изменение указателя (++р), потом выборка содержимого по адресу, на ко­торый он указывает.