Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Использование goto. 1 страница




Алгоритмы и псевдокод.

Вложенные циклы.

Сравнение циклов.

Философ Зенон и цикл for.

Гибкость конструкции for.

Цикл for.

Цикл do-while.

Программа подсчета слов.

Завершение цикла while.

11.1.1.3. Программа, «рисующая» символами.

11.1.3.1. Операция «запятая» в цикле for.

11.2. Оператор break.

11.3. Оператор continue.

11.4. Совместное использование операторов break и continue.

11.5. Оператор goto.

11.6. Оператор exit().

11.7. Оператор atexit().

 

7. Циклы и другие управляющие средства.

Здесь рассматриваются принципы работы управляющих структур и даются рекомендации, каким образом лучше всего применять каждую из них. Мы обсудим операторы break, continue, goto и операцию «запятая»: все они могут использоваться для управления ходом выполнения программы. Кроме того, мы расскажем вам еще немного о массивах, которые часто используются вместе с циклами.

 

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

В языке С имеется стандартный набор операторов цикла: for, while и do-while (называемый в некоторый других языках высокого уровня циклом repeat-until). Вас может, однако, удивить то, каким способом программа выходит из цикла. В С можно изменить порядок выполнения цикла четырьмя способами. Естественно, все циклы заканчиваются при выполнении заданного проверочного условия. Однако, в С цикл может также закончиться по некоторому заданному условию ошибки при помощи операторов break или exit. Кроме этого, в циклах может быть собственная управляющая логика, изменяемая при помощи оператора break или оператора continue.

 

11.1.1. Цикл while.

Так же как и цикл for, в С цикл while является циклом с предусловием. Это означает, что в программе проверка_условия осуществляется до выполнения оператора или операторов, входящих в тело цикла. Благодаря этому, циклы с предусловием могут либо не выполняться вообще, либо выполняться множество раз. В С синтаксис цикла while следующий:

 

while(проверка_условия)

оператор;

 

В циклах while с несколькими операторами необходимы фигурные скобки:

 

while(проверка_условия) {

оператор1;

оператор2;

оператор3;

операторn;

}

 

В следующей программе на С цикл while используется для определения того, сколько раз переменную ivalue сдвигать вправо. Программа печатает двоичное представление целого числа со знаком.

 

/*07WHILE.C

Программа на С, в которой используется цикл while с предусловием

и флагом*/

 

#include "stdafx.h"

#include <iostream>

#include <conio.h>

#include <stdio.h>

//#include <iostream.h>

using namespace std;

#define WORD 16

#define ONE_BYTE 8

main()

{

int ivalue = 256, ibit_position=1;

unsigned int umask = 1;

/* Следуицее значение... */

printf("The following value %d,\n",ivalue);

/* в двоичном виде выглядит так: */

printf("in binary form looks like: ");

while(ibit_position <= WORD) {

if ((ivalue >> (WORD - ibit_position)) & umask)

/*сдвинуть каждый */

printf ("1"); /*разряд в 0-ю */

else /* позицию и */

printf("0"); /* сравнить с umask k*/

if(ibit_position == ONE_BYTE)

printf (" ");

ibit_position++;

}

printf ("\n\nPress any key to finish\n"); /* Конец работы */

_getch();

return(0);

}

 

В начале программы определяются две константы, WORD и ONE_BYTE, которые можно легко изменить для различных архитектур. Константа WORD используется как флаг, определяющий окончание цикла while. В цикле while переменная ivalue сдвигается, сравнивается с umask, и печатается следующий старший разряд числа. Такой алгоритм позволяет использовать простой оператор printf() для вывода результата.

 

11.1.1.1. Завершение цикла while.

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

 

index = 1;

while(index < 5)

printf("Доброе утро!\n");

Данный фрагмент программы печатает это радостное сообщение бесконечное число раз, поскольку в цикле отсутствуют конструкции, изменяющие величину переменной index, которой было присвоено значение 1.

 

index = 1;

while(-- index < 5)

printf(" Как колеблются старые атомы!\n");

 

И этот фрагмент программы работает ненамного лучше. Значение переменной index в нем изменяется, но в «неправильном» направлении! Единственным утешением здесь служит тот факт, что выполнение данного куска программы в конце концов завершится. Это произойдет, когда величина переменной index станет меньше наименьшего отрицательного числа, допустимого в системе.

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

 

index = 3;

while(index++ < 5)

printf(" Желаю хорошо провести день\n");

 

Измените первую строку на

 

index = 3;

 

и вы получите работающую программу.

 

11.1.1.2. Программа подсчета слов.

Теперь у нас есть возможности для написания программы подсчета числа слов в тексте. (Она может также подсчитывать символы и строки.)

#include <stdio.h>

#define YES 1

#define NO 0

main()

{

int ch; /* введенный символ */

long nc = 0L; /* число символов */

int nl = 0; /* число строк */

int nw = 0; /* число слов */

int word = NO; /* = = YES, если содержимое ch — часть слова */

while((ch = getchar())!= EOF)

{

nc++; /* подсчет символов */

if (ch = = ' \n')

nl ++; /* подсчет строк */

if (ch!= ' ' && ch!= '\n' && ch!= ' \t' && word = = NO)

{

word = YES; /* начало нового слова */

nw++; /* подсчет слов */

}

if ((ch = = ' ' || ch = = ' \n' || ch = = ' \t') && word == YES)

word = NO; /* достигнут конец слова */

}

printf(" символов = %ld, слов = %d, строк = %d\n", nc, nw, nl);

}

 

Поскольку существуют три различных «пустых символа», мы должны использовать логические операции для проверки всех трех возможностей. Рассмотрим, например, следующую строку:

 

if(ch!= ' '&& ch!= '\n' && ch!= ' \t' && word == NO)

 

В ней говорится: «если содержимое ch — не пробел, и не новая строка, и не табуляция, и не первый символ слова». (Первые три условия эквивалентны проверке, не является ли содержимое ch пустым символом.) Выполнение всех четырех условий служит признаком начала нового слова, и значение переменной nw увеличивается. Если мы в середине слова, то первые три условия оказываются выполненными, но значением переменной word окажется признак YES, и значение переменной nw не увеличивается. Когда в процессе ввода встретится очередной «пустой» символ, переменной word будет вновь присвоен признак NO.

 

11.1.1.3. Программа, «рисующая» символами.

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

/* художник-график */

/* рисует сплошные фигуры */

#include <stdio.h>

#define MAXLENGTH 80

main()

{

int ch; /* печатаемый символ */

int start, stop; /* начальная и конечная позиции */

int count;

/* счетчик позиций */

while((ch = getchar())!= EOF) /* ввод символа */

{

if (ch!= '\n') /* пропуск символа «новая строка» */

{

scanf(" %d %d", &start, &stop); /* ввод граничных значений */

if (start > stop || start < 1 || stop > MAXLENGTH)

printf(" Введены неправильные граничные значения. \n");

else

{

count = 0;

while(++count < start)

putchar(' '); /* печать пробелов вплоть до

начальной позиции */

while (count++ < = stop)

putchar(ch); /"печать символа до конечной позиции */

putchar('\n'); /* закончить печать строки и

начать новую */

} /* конец части else */

} /* конец проверки содержимого ch */

} /* конец цикла while */

} /* конец программы */

Программа вывела на экран символ В в позициях с 10 по 20, а символ Y — с 12 по 18. К сожалению, при диалоговой работе с программой на экране наши команды перемежаются выводимыми строками. Гораздо более удобным способом использования программы является создание файла, содержащего подходящий набор данных, а затем применение операции переключения для ввода (из него) параметров в программу. Предположим, например, что в файле с именем fig содержатся следующие данные:

 

-30 50

| 30 50

| 30 50

| 30 50

| 30 50

| 30 50

= 20 60

: 31 49

: 30 49

: 29 49

: 27 49

: 25 49

: 30 49

: 30 49

/ 30 49

: 35 48

: 15 48

 

После ввода команды sketcher < fig вы увидите результат работы программы.

Замечание: на устройствах печати и экранах дисплеев отношение высоты символа к его ширине может быть различным; в результате эти фигуры при печати выглядят более сжатыми по вертикали, чем изображенные на экране.

Анализ программы. Это короткая программа, но она оказалась сложнее тех примеров, которые мы обсуждали до сих пор. Рассмотрим некоторые ее элементы.

Длина строки. Мы ввели в программу ограничение на длину печатаемой строки (она не может быть больше 80 позиций), поскольку 80 символов — это стандартный формат (по ширине) экрана дисплеев различных типов, а также число символов при нормальной ширине листа бумаги на устройстве для печати. Вы можете, однако, переопределить величину константы MAXLENGTH, если при работе с программой захотите воспользоваться устройством, имеющим другую ширину строки.

Структура программы. В нашей программе имеются три цикла while, один оператор if и один оператор if-else. Посмотрим, чтобы каждый из них делает: while((ch = getchar())!= EOF)

Функция getchar() читает первый встретившийся символ независимо от того, является ли он алфавитным символом, пробелом, символом «новая строка» или еще чем-нибудь. Функция scanf() делает то же самое, если чтение производится в формате %с (символ). Но, когда scanf() осуществляет ввод данных в формате %d (целые), пробелы и символы «новая строка» пропускаются. Поэтому символы «новая строка» или любые пробелы между символом, считываемым функцией getchar(), и следующим целым числом, считываемым функцией scanf(), игнорируются. Функция scanf() читает цифры до тех пор, пока не встретит нецифровой символ — пробел, символ «новая строка» или букву. Следовательно, между первым и вторым целыми числами необходимо помещать пробел или символ «новая строка», чтобы функция scanf() могла распознать, где кончается одно и начинается другое.

Этим объясняется, почему между символом и следующим целым числом может стоять пробел или символ «новая строка», и почему между двумя целыми числами обязательно должен быть разделитель такого вида. Но почему между целым числом, стоящим в конце набора данных, и следующим символом не может стоять пробел? Потому что в следующий раз на очередном шаге выполнения цикла while функция getchar() осуществляет ввод символа из той позиции, где «остановилась» функция scanf(). Поэтому она прочтет любой следующий символ, стоящий после целого числа,— пробел, символ «новая строка» и т. п.

Если бы мы следовали требованиям функции getchar(), структуру данных необходимо было бы организовать так:

 

W10 50a20 60у10 30

 

где между последним целым числом, стоящим в конце группы, и следующим символом разделитель отсутствует. Но такая структура выглядит неуклюже, поскольку число 50 при этом выглядит так, как будто оно помещено в одну группу с а, а не с w. Поэтому введен оператор

 

if(ch!= '\n')

 

чтобы иметь возможность обнаружить, когда значение ch равно символу «новая строка». Вместо этого можно использовать данные, вводимые в виде

 

w10 50

а20 60

у10 30

 

где между числом 50 и а помещен символ «новая строка». Программа читает этот символ, игнорирует его и затем переходит к чтению следующего символа.

Контроль ошибок. Существует широко распространенная проблема, связанная с вводом в машину данных, которые должны использоваться определенным образом. Один из методов ее решения состоит в «контроле ошибок». Это означает, что, перед тем как приступить к обработке данных, программа должна проверить их правильность. В нашей программе мы сделали первую попытку осуществить такой контроль ошибок с помощью операторов:

 

if(start > stop || start < 1 || stop > MAXLENGTH)

printf(" Введены неправильные граничные значения.\n");

 

Они входят в структуру if-else, которая определяет, что основная часть программы будет выполняться только в том случае, если ни один из трех if-тестов не окажется истинным.

С какой целью мы принимаем все эти меры предосторожности? Во-первых, совершенно неправильно размещать начальную позицию после конечной, поскольку обычно на терминал данные выводятся слева направо, а не наоборот. Поэтому с помощью выражения start > stop проверяется наличие такой потенциальной ошибки. Во-вторых, при выводе на экран первый столбец имеет номер 1; мы не можем выводить данные левее левого края. Выражение start < 1 служит средством обнаружения такой ошибки. И наконец, с помощью выражения stop > MAXLENGTH проверяется, не попытаемся ли мы вывести на печать данные правее правого края. Существуют ли еще какие-нибудь ошибочные значения, которые мы можем присвоить переменным start и stop? Можно было бы, конечно, попробовать присвоить переменной start значение большее, чем MAXLENGTH. Может ли этот вариант успешно пройти наш тест? Нет, хотя наличие подобной ошибки мы и не проверяем непосредственно. Предположим, что величина Start больше константы MAXLENGTH. Тогда либо значение stop тоже превышает величину MAXLENGTH, что обязательно приведет к обнаружению ошибки, либо stop окажется меньшей или равной MAXLENGTH. Но тогда ее значение должно быть меньше величины Start, что приведет к обнаружению этой ошибки первым тестом. Другая вероятная ошибка может состоять в том, что значение stop окажется меньше 1. Мы оставляем читателям в качестве самостоятельного упражнения проверку того, что данная ошибка также не останется незамеченной.

В нашей программе контроль ошибок выглядит весьма простым. Если вы проектируете программу для серьезных целей, вы обязаны обратить на этот вопрос больше внимания, чем мы. Например, выводимые сообщения об ошибках могли бы указывать, какие величины неверны и почему; кроме того, вы могли бы привнести в сообщения что-то от себя и придать им большую эмоциональную окраску. Приведем несколько примеров:

 

Указанное вами значение stop — 897654 превышает ширину экрана.

Вот эта да! У вас START больше, чем STOP. Попробуйте, пожалуйста, еще раз.

ВЕЛИЧИНА START ДОЛЖНА БЫТЬ БОЛЬШЕ 0, ИНДЮК.

 

Привносимые личностные моменты относятся, конечно, и к вам самим.

 

11.1.2. Цикл do-while.

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

Синтаксис цикла do-while следующий:

do

действие;

while(проверка_условия);

 

При множестве действий в операторе do-while необходимы фигурные скобки:

 

do {

действие1;

действие2;

действиеЗ;

действиеn;

} while(проверка_условия);

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

 

do

{

выдвиньте предположение

получите ответ вида д, б, или м

} while (ответ не совпадает с д)

 

Вы должны избегать использования цикла do while, структура которого аналогична представленной ниже в записи на псевдокоде:

 

спросите пользователя, хочет ли он продолжать

do

некоторый умный вздор

while (oтвет будет да)

 

В данном случае, после того как пользователь ответит «нет», «некоторый умный вздор» будет выполнен, поскольку проверка осуществляется слишком поздно.

 

11.1.3. Цикл for.

В цикле for распространен для «математических повторений. Вот пример его записи:

 

for(count = 1; count <= NUMBER; count ++)

printf(" Будь моим Валентином!\n");

 

В круглых скобках содержатся три выражения, разделенные символом «точка с запятой». Первое из них служит для инициализации счетчика. Она осуществляется только один раз — когда цикл for начинает выполняться. Второе выражение — для проверки условия; она производится перед каждым возможным выполнением тела цикла. Когда выражение становится ложным (или в общем случае равным нулю), цикл завершается. Третье выражение вычисляется в конце каждого выполнения тела цикла. Ранее мы использовали его для увеличения значения счетчика count, но, вообще говоря, его использование этим не ограничивается. За заголовком цикла for следует простой или составной оператор.

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

 

/* таблица кубов */

main()

{

int num;

for(num = 1; num < = 6; num++)

printf(" %5d %5d \n", num, num*num*num);

}

Эта программа выводит на печать числа от 1 до 6 и их кубы:

1 1

2 8

3 27

4 64

5 125

6 216

 

Инициализация выполняется один раз перед началом работы цикла.

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

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

for(n = 1; n <= 10000; n++)

;

Этот цикл заставляет машину считать до 10000. Единственный символ «точка с запятой», расположенный во второй строке, информирует нас о том, что никаких других действий в этом цикле не производится. Такой уединенный символ «точка с запятой» можно представлять себе как «пустой» оператор, т. е. оператор, который не выполняет никаких действий.

 

Синтаксис цикла for следующий:

 

for(инициализация; проверка_условия; коррекция)

оператор;

 

При выполнении цикла for сначала осуществляется инициализация. Она выполняется в начале цикла и больше никогда не повторяется.

В следующем примере выполняется суммирование первых пяти целых чисел. Подразумевается, что переменные isum и ivalue предварительно описаны как целые:

 

isum = 0;

for(ivalue=1; ivalue <= 5: ivalue++)

isum += ivalue;

 

После инициализации переменной isum значением 0, выполняется цикл for. Во-первых, переменная ivalue устанавливается в 1 (это осуществляется только один раз); во-вторых, значение ivalue сравнивается с условием окончания цикла <=5. Поскольку результат сравнения — "истина", к переменной isum добавляется 1. Как только оператор выполнился, значение переменной управления циклом (ivalue) увеличивается на 1. Этот процесс повторяется еще четыре раза до тех пор, пока значение ivalue не увеличится до 6 и цикл не закончится.

 

11.1.3.1. Операция «запятая» в цикле for.

Операция «запятая» увеличивает гибкость использования цикла for, позволяя включать в его спецификацию несколько инициализирующих или корректирующих выражений. Например, ниже приводится программа, которая выводит на печать величины почтовых тарифов первого класса обслуживания. (Предположим, что почтовые тарифы: 20 центов за первую унцию и по 17 центов за каждую следующую.)

 

/* почтовые тарифы */

#define FIRST 20

#define NEXT 17

main()

{

int ounces, cost;

printf(" унции стоимость\n");

for(ounces = 1, cost = FIRST; ounces < - 16; ounces++, cost + = NEXT)

printf(" %3d %7d\n", ounces, cost);

}

 

Первые четыре строки результата работы программы будут выглядеть следующим образом:

 

Мы воспользовались операцией «запятая» в первом и третьих выражениях: в первом случае она позволяет инициализировать переменные ounces и cost; во втором — на каждой итерации увеличивать значение ounces на 1, a cost на 17 (величину константы NEXT). Все вычисления осуществляются в спецификации цикла for.

Применение операции «запятая» не ограничено только циклами for, но именно в них она используется особенно часто. Операция обладает одним дополнительным свойством: при ее использовании гарантируется, что выражения, к которым она применяется (т. е. выражения, разделенные запятой), будут вычисляться слева направо.

 

11.1.3.2. Гибкость конструкции for.

Хотя цикл for на первый взгляд очень похож на цикл DO в Фортране, цикл FOR в Паскале и цикл FOR... NEXT в Бейсике, for в Си является гораздо более гибким средством, чем любой из упомянутых. Эта гибкость — следствие способа использования упомянутых выше трех выражений в спецификации цикла for. До сих пор первое выражение применялось для инициализации счетчика, второе — для задания его граничного значения, а третье — для увеличения его текущего значения на 1. Использованный таким образом, оператор for в языке Си совершенно аналогичен упомянутым выше соответствующим операторам в других языках. Но, кроме описанной, существует еще и много других возможностей его применения, девять из которых мы приводим ниже.

 

1. Можно применять операцию уменьшения для счета в порядке убывания вместо счета в порядке возрастания.

 

for(n = 10; n > 0; n--)

printf(" %d секунд!\n", n);

printf(" Пуск!\n");

 

2. При желании вы можете вести счет двойками, десятками и т. д.

 

for(n = 2; n < 60; n = n + 13)

printf(" %d\n", n);

 

3. Можно вести подсчет с помощью символов, а не только чисел:

 

for(ch = 'а'; ch <= 'z'; ch++)

printf(" Величина кода ASCII для %с равна %d.\n", ch, ch);

 

4. Можно проверить выполнение некоторого произвольного условия, отличного от условия, налагаемого на число итераций. В нашей программе таблица кубов вы могли бы заменить спецификацию

 

for(num = 1; num < = 6; num++)

 

на

 

for(num = 1; num*num*num <= 216; num ++)

 

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

 

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

 

for(debt = 100.0; debt < 150.0; debt = debt* 1.1)

printf(" Ваш долг теперь $%.2f.\n", debt);

 

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

 

for(x = 1; у <= 75; у = 5*х+++ 10);

printf("%10d %10d\n", x, у);

 

7. Можно даже опустить одно или более выражений (но при этом нельзя опустить символы «точка с запятой»). Необходимо только включить в тело цикла несколько операторов, которые в конце концов приведут к завершению его работы.

 

ans = 2;

for(n = 3; ans < = 25;)

ans = ans*n;

 

8. Первое выражение не обязательно должно инициализировать переменную. Вместо этого, например, там мог бы стоять оператор printf() некоторого специального вида. Необходимо помнить только, что первое выражение вычисляется только один раз перед тем, как остальные части цикла начнут выполняться.

 

for(printf(" Запоминайте введенные числа!\n"); num = = 6;)

scanf(" %d", &num);

printf("Эro как раз то, что я хочу!\n");

 

9. Параметры, входящие в выражения, находящиеся в спецификации цикла, можно изменить при выполнении операций в теле цикла. Предположим, например, что у вас есть цикл со спецификацией следующего вида:

 

for(n = 1; n < 1000; n += delta)

 

И если после нескольких итераций ваша программа решает, что величина параметра delta слишком мала или велика, оператор if внутри цикла может изменить значение параметра. В диалоговой программе пользователь может изменить этот параметр в процессе выполнения цикла.

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

 

11.1.3.3. Философ Зенон и цикл for.

Философ Зенон известен своими знаменитыми парадоксами (апориями). Посмотрим, как с помощью операции «запятая» можно разрешить старый парадокс. Греческий философ Зенон утверждал, что пущенная стрела никогда не достигнет цели. Сначала, говорил он, стрела пролетит половину расстояния до цели. После этого ей останется пролететь половину всего расстояния, но сначала она должна будет пролететь половину того, что ей осталось пролететь, и т. д. до бесконечности. Поскольку расстояние полета разбито на бесконечное число частей, для достижения цели стреле может потребоваться бесконечное время. Мы сомневаемся, однако, что Зенон вызвался бы стать мишенью для стрелы, полагаясь только на убедительность своего аргумента.

Применим количественный подход и предположим, что за одну секунду полета стрела пролетает первую половину расстояния. Тогда за последующую 1/2 секунды она пролетит половину того, что осталось от половины, за 1/4 — половину того, что осталось после этого, и т д. Полное время полета представляется в виде суммы бесконечного ряда 1 + 1/2 + 1/4 + 1/8 + 1/16 +.... Мы можем написать короткую программу для нахождения суммы первых нескольких членов.




Поделиться с друзьями:


Дата добавления: 2015-01-03; Просмотров: 586; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.185 сек.