Лекции.Орг


Поиск:




Другие управляющие операторы

Лабораторная работа №6

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

Цель работы: Ознакомиться с управляющими структурами: Цикл с предусловием. Цикл со счетчиком. Цикл с постусловием. Другие управляющие операторы. Структурное программирование.

Теоретическая часть

Операторы цикла относятся к управляющим конструкциям всякого языка программирования. Управляющие операторы и конструкции языка задают порядок, в котором выполняются вычислительные операции программы.Существует три вида циклов: while, for и do.

Оператор while

Изучение операторов цикла начнем с оператора while. Цикл while имеет следующий формат (синтаксис) записи:

while (expression)program statement;

Производится расчет выражения expression, заключенного в круглые скобки. Если в результате расчета выражения expression получается истинный результат (TRUE или значение отлично от 0), то выполняется утверждение program statement, следующее непосредственно за закрывающей круглой скобкой. После выполнения этого утверждения вновь рассчитывается выражение expression. Если в результате расчета будет TRUE, то вновь будут выполнены утверждения program statement. Цикл повторяется до тех пор, пока в результате расчета выражения expression (в круглых скобках оператора while) не будет получено значение FALSE (ложный) или равное 0, которое является признаком окончания цикла, после чего выполнение программы продолжается с утверждения, следующего за утверждением program statement. Когда требуется выполнить группу утверждений, то она (группа) располагается в фигурных скобках:

while (expression){program statement;program2 statement2;program3 statement3;...}

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

Очевидно, что неверное задание выражения expression может привести к бесконечному циклу (к зацикливанию).

/* угадывание числа */#include <stdio.h>main(){ int i = 1; char res; printf("Задумайте целое число от 1 до 100. Компьютер попытается угадать его. \n"); printf ("Отвечайте y, если догадка правильна и"); printf("\n n, если программа ошибается \n"); printf("Итак, ваше число %d?\n",i); /*получение ответа */ while((res = getchar())!='y') if(res!='\n') /* пропуск символа новая строка */ printf("Ну тогда оно равно %d\n",++i); printf("Число угадано!\n");}
! Это довольно простая программа. Она написана правильно и решает поставленную задачу, но делает это крайне неэффективно. Данный пример показывает, что правильность написания - не единственный критерий, по которому необходимо оценивать программу. При этом очень важна ее эффективность!

В наших примерах до сих пор использовались условные выражения, но вообще говоря, это могут быть выражения произвольного типа. В качестве оператора можно использовать простой оператор с символом "точка с запятой" в конце или составной оператор, заключенный в фигурные скобки. Если выражение истинно (или в общем случае равно единице), то оператор, входящий в цикл while, выполняется один раз, а затем выражение проверяется снова. Эта последовательность действий, состоящая из проверки и выполнения оператора, периодически повторяется до тех пор, пока выражение не станет ложным (или в общем случае равным нулю). Каждый такой шаг называется итерация. Данная структура аналогична структуре оператора if. Основное отличие заключается в том, что в операторе if проверка условия и (возможное) выполнение оператора осуществляется только один раз, а в цикле while эти действия производятся, вообще говоря, неоднократно.

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

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

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

Итак:

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

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

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

 

Оператор for

Оператор цикла for имеет следующий формат записи:

for (init_expression; loop_condition; loop_expression)program statement;

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

Первый параметр init_expression используется для задания начального значения цикла (для задания начальных условий выполнения цикла)

Второй компонент loop_condition определяет условие или условия, в соответствии с которыми будет происходить выход из цикла. Повторение будет происходить до тех пор, пока это условие (или условия) выполняются. Если условие не выполняется, то цикл немедленно заканчивается.

Третий параметр loop_expression выполняется каждый раз, когда заканчивается обработка тела цикла, т.е. program statement (выражение loop_expression модифицирует условия, заданные выражением init_expression).

Чаще всего выражения init_expression и loop_expression являются операторами присваивания или вызовами функций, а второе выражение loop_condition – выражением отношения или логическим выражением.

Любую из трех частей можно опустить, но точки с запятыми должны остаться на своих местах. Если опустить init_expression или loop_expression, то соответствующие операции не будут выполняться. Если же опустить проверку условия loop_condition, то по умолчанию считается, что условие продолжения цикла всегда истинно, и тогда цикл станет бесконечным (произойдет зацикливание)?, т.е. если опущено loop_condition, то по умолчанию вместо него подставляется значение TRUE.

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

for (init_expression; loop_condition; loop_expression){program1 statement1;program2 statement2;program3 statement3;...}

В представленном случае тело цикла находится в фигурных скобках.

Конструкция цикла, реализованная оператором for, может быть выполнена также и оператором while следующим образом:

init_expression;while (loop_condition){program statement;loop_expression;}

Исключением является применение операции continue.

Циклfor(;loop_condition;) program statement;

с опущенными init_expression, loop_expression эквивалентен циклу

while(loop_condition) program statement;

Цикл

for(;;)program statement;

со всеми опущенными выражениями эквивалентен циклу

while(TRUE) program statement;

т.е. эквивалентен бесконечному циклу. Такой цикл может быть прерван только явным выходом из него с помощью операторов break, goto, return, содержащихся в теле цикла program statement.

Операторы отношения перечислены в табл. 6.1.

Таблица 6.1.
Операторы отношения языка программирования С
№ п/п Оператор Значение
1) == Равно
2) != Не равно
3) < Меньше
4) <= Меньше или равно
5) > Больше
6) >= больше или равно

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

Несмотря на внешнее сходство с итеративными циклами for языков Паскаль и Ада или итеративными циклами do языков Фортран или ПЛ/1, цикл for языка Си не является их семантической копией. Цикл for языка Си обладает большей общностью, чем циклы for и do других языков. В отличии от этих циклов, в общем случае число итераций в цикле for языка Си не может быть определено до выполнения этого цикла.

Цикл for и его альтернатива цикл while семантически почти эквивалентны, но, как указывается в работе (Ritchie, D.M. 1980. The Programming Language - Reference Manual/. AT&T Bell Laboratories, Murray Hill, N.J. 07974), не идентичны. Например, рассмотрим случай, когда оператор program statement является оператором continue или составным оператором, содержащим оператор continue. Действие оператора continue состоит в переходе к концу цикла, что имеет различные последствия для цикла for и его эквивалента в форме цикла while. В случае с циклом for выражение loop_expression выполняется до вычисления значения выражения loop_condition, в то время как в эквивалентном цикле while выражение loop_expression пропускается.

Гибкость конструкции for - следствие способа использования выражений в спецификации цикла. Существует много возможностей применения цикла for, некоторые из которых мы приведем ниже.

  1. Можно применять операцию увеличения для счета в порядке возрастания:
Нахождение произведения чисел от 1 до 10 или 10!float pr=1;for(n=1; n<11; n++)pr*=n;printf("10!=%f0.0",pr);
  1. Можно применять операцию уменьшения для счета в порядке убывания вместо счета в порядке возрастания:
for(n=10; n>0; n--)printf("%d секунд!\n",n);printf("Пуск! \n");
  1. При желании можно вести счет двойками, десятками и т.д.:
for (n=2; n<60;n+=13);printf("%d\n",n);
  1. Можно вести подсчет с помощью символов, а не только чисел:
for(ch = 'a';ch<='z';ch++)printf("Величина кода ASCII для %с равна %d.\n",ch,ch);

При выполнении этого оператора будут выведены на печать все буквы от а до z вместе с их кодами ASCII. Этот оператор работает, поскольку символы в памяти машины размещаются в виде чисел, и потому в данном фрагменте ведется счет с использованием целых чисел.

  1. Можно проверить выполнение некоторого произвольного условия, отличного от условия, налагаемого на число итераций. Рассмотрим пример в программе печатающей таблицу кубов целых чисел:
/* таблица кубов */main(){ int num; for(num=1; num<=6; num++) printf("%5d %5d\n", num,num*num*num);}

А теперь заменим спецификацию

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

на

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

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

  1. Можно сделать так, чтобы значение некоторой величины возрастало в геометрической, а не в арифметической прогрессии, т.е. вместо прибавления фиксированного значения на каждом шаге цикла выполнялось бы умножение:
for(x=100.0; x<150.0; x*=1.1)printf("Ваш долг теперь %3.2f.\n",x);

В этом фрагменте программы значение переменной x умножается на 1.1 на каждом шаге цикла, что увеличивает ее на 10%. Результат выглядит следующим образом:

Ваш долг теперь 100.00.Ваш долг теперь 110.00.Ваш долг теперь 121.00.Ваш долг теперь 133.10.Ваш долг теперь 146.41.
  1. В качестве третьего выражения можно использовать любое правильно составленное выражение. Какое бы выражение мы ни указали, его значение будет меняться при каждой итерации:
for (x=y=1; y<=75; y=5*x++)printf("%10d %10d\n",x,y);

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

! Хотя этот пример и правильный, он не может служить иллюстрацией хорошего стиля программирования. Программа выглядела бы гораздо понятнее, если бы мы не смешали процесс изменения переменной цикла с алгебраическими вычислениями.
  1. Можно даже опустить одно или более выражений, но при этом нельзя опустить символы "точка с запятой". Тело цикла
for(;;) {...}

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

  1. Первое выражение не обязательно должно инициализировать переменную. Вместо этого, например, там мог бы стоять оператор printf(). Необходимо помнить только, что первое выражение вычисляется только один раз перед тем, как остальные части цикла начнут выполняться.
for(printf("Запоминайте числа! \n"); num!= 6;)scanf("%d",&num);printf("Это как раз то, что я хочу!\n");

В этом фрагменте первое сообщение оказывается выведенным на печать один раз, а затем осуществляется прием вводимых чисел до тех пор, пока не поступит число 6.

  1. Параметры, входящие в выражения, находящиеся в спецификации цикла, можно изменить при выполнении операций в теле цикла. Предположим, например, что у вас есть цикл со спецификацией следующего вида:
for(n=1; n<1000; n+t)

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

Подведем итоги. В операторе for используются три выражения, управляющие работой цикла. Они разделены символом "точка с запятой". Инициализирующее выражение вычисляется только один раз до начала выполнения какого-нибудь из операторов цикла. Если проверяемое выражение оказывается истинным, или не равным нулю, тело цикла выполняется один раз. Затем вычисляется величина корректируемого выражения, и значение проверяемого выражения определяется вновь. Оператор for - это цикл с предусловием. Решение о том, выполнить ли в очередной раз тело цикла или нет, принимается до начала его прохождения. Поэтому может случиться так, что тело цикла не будет выполнено ни разу. Оператор, образующий тело цикла, может быть как простым, так и составным.

Операция "запятая" увеличивает гибкость использования цикла for, позволяя включить в его спецификацию несколько инициализирующих или корректирующих выражений.

Оператор do–while

Рассмотренные операторы цикла while и for производят проверку условия выполнения цикла до начала выполнения тела цикла. Поэтому тело цикла может ни разу не выполниться, если с самого начала результатом расчета условия выполнения цикла будет значение FALSE (ложь). В случае необходимости производить проверку условия выполнения цикла после тела цикла (т.е. когда выполняется хотя бы одно предписанное действие в теле цикла) прибегают к циклу do–while.

Оператор цикла do–while имеет следующий формат записи:

doprogram statement;while (loop_condition);

Выполнение цикла do–while происходит следующим образом: сначала выполняется утверждение program statement, затем производится проверка условия выполнения цикла loop_condition с помощью оператора while. Если результатом проверки будет значение TRUE (истина), то выполнение цикла продолжится, и утверждение program statement всякий раз будет выполняться вновь. Повторение цикла будет продолжаться до тех пор, пока в результате проверки условия выполнения цикла loop_condition будет получаться значение TRUE. Когда в результате проверки условия будет вычислено значение FALSE (ложь), то выполнение цикла прекратится и произойдет переход к утверждению (следующему фрагменту программы), непосредственно следующему за циклом.

! Таким образом, цикл do–while гарантированно выполнится хотя бы один раз.

 

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

do {program1 statement1;program2 statement2;program3 statement3;... } while (loop_condition);

Оператор цикла while называется оператором цикла с предусловием, оператор цикла for называется оператором цикла с параметром, оператор цикла do–while называется оператором цикла c постусловием.

! Цикл do while - это конструкция с условием на выходе.

Пример:

do scanf("%d", &number);while(number!=50);

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

Особенности работы с языком Си. Циклом какого вида лучше всего воспользоваться? Во-первых, решите, нужен ли вам цикл с предусловием или же с постусловием. Чаще вам нужен будет цикл с предусловием. По оценкам Кернигана и Ритчи, в среднем циклы с постусловием составляют только 5% общего числа используемых циклов. Существует несколько причин, по которым программисты предпочитают пользоваться циклами с предусловием. В их числе один общий принцип, согласно которому лучше посмотреть, куда вы прыгаете, до прыжка, а не после. Вторым моментом является то, что программу легче читать, если проверяемое условие находится в начале цикла. И наконец, во многих случаях важно, чтобы тело цикла игнорировалось полностью, если условие вначале не выполняется.

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

Пример:

/* Простое число - это такое число, которое делится нацело только на 1 и само на себя. Первыми простыми числами будут 2, 3, 5, 7 и 11. *//*простые числа*/ main(){ int number, divisor, limit; int count=0; printf("Укажите, пожалуйста, верхний предел для поиска простых чисел. \n"); printf("Bерхний предел должен быть 2 или больше.\n"); scanf("%d",&limit); while (limit<2) { /* вторая попытка, если ошибка при вводе */ printf("Bы были невнимательны! Попробуйте еще раз\n"); scanf("%d",&limit); } printf("Ceйчac напечатаем простые числа!\n"); for (number=2;number<=limit; number++) /*внешний цикл*/ { for(divisor=2; number%divisor!=0; divisor++); if(divisor==number) { printf("%5d",number); if(++count%10==0) printf("\n");/* новая строка начинается через каждые 10 простых чисел */ } } printf("Pa6oта завершена!\n");}

Во внешнем цикле каждое число, начиная с 2 и кончая величиной limit, последовательно берется для проверки. Указанная проверка осуществляется во внутреннем цикле. В count хранится счетчик получаемых простых чисел. При печати каждое одиннадцатое простое число печатается с новой строки.

Другие управляющие операторы

Операторы, определяющие циклические вычисления, которые мы рассмотрели, и условные операторы if, if-else и switch, являются важнейшими средствами управления выполнением программы на языке Си. Они должны использоваться для реализации общей структуры программы. Три оператора, рассматриваемые ниже, обычно рассматриваются реже, поскольку слишком частое их использование ухудшает читаемость программы, увеличивает вероятность ошибок и затрудняет ее модификацию. Никлаус Вирт дал определение структурного программирования, как программирования без goto.

Оператор break

Оператор break используется для выхода из оператора while, do, for, switch, непосредственно его содержащего. Управление передается на оператор, следующий за оператором, из которого осуществлен выход. Оператор break имеет форму

break;

Пример:

while((ch=getchar())!= EOF) /* читается символ ch=getchar(). Если он не совпадает с EOF, выполняется тело оператора while */{ if(ch=='\n') break; putchar(ch);}

Работа цикла полностью прекращается, как только при вводе встречается символ "новая строка".

Оператор continue

Оператор continue служит для пропуска оставшейся части выполняемой итерации цикла, непосредственно его содержащего. Если условиям

и цикла допускается новая итерация, то она выполняется, в противном случае цикл завершается. Оператор continue имеет следующую форму:

continue;

Пример:

while((ch=getchar())!= EOF) /* читается символ ch=getchar(). Если он не совпадает с EOF, выполняется тело оператора while */{ if(ch=='\n') continue; putchar(ch);}

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

Оператор goto

Оператор goto предназначен для безусловной передачи управления к оператору с указанной меткой. Он имеет следующую форму:

goto метка;

Керниган и Ритчи считают оператор goto "чрезвычайно плохим" средством и предлагают применять его как можно реже или не применять совсем. Приведем пример записи оператора:

goto part1;

Чтобы этот оператор выполнялся правильно, необходимо наличие другого оператора, имеющего метку part1. В этом случае запись оператора начинается с метки, за которой следует двоеточие:

part1: printf("точка перехода\n");
! Избегайте использовать goto! С тех пор как Дейкстра опубликовал свой знаменитый труд "Вредность оператора GOTO", специалисты бились над методами структурного программирования. Отметим, что нужно очень осторожно использовать операторы: goto, break, continue, return.

Если без операторов goto, break, continue, return никак не обойтись, то при использовании goto переходите вперед по коду, а не назад.

Оператор break лучше не использовать для преждевременного выхода из цикла, его полезно использовать внутри оператора switch.

Оператор continue нежелательно использовать для модификации логики циклов.

! Почему нежелательно использовать функции со многими операторами return. Один из принципов структурного программирования состоит в том, что программа должна иметь одну точку входа и одну точку выхода. Функции со многими операторами return более сложны для чтения, чем те, которые имеют лишь один оператор return в конце тела функции.

Практическая часть

Рассмотрим примеры программ с операторами циклов while, for и do–while.

Пример 1. Напишите программу вывода на экран пользователя целых положительных чисел с помощью оператора while. Начальное и последнее число должно задаваться пользователем с клавиатуры.

Программный код решения примера:

#include <stdio.h>#include <conio.h> int main(void) {int i, j = 0, n;printf("\n\t Enter the primary natural number: ");scanf_s("%d", &i);printf("\t Enter the last natural number: ");scanf_s("%d", &n); printf("\n\t The numbers are:");while (i <= n) {printf("\n\t %3d", i);++i;++j; }printf("\n\t Total numbers: %d\n", j); printf("\n Press any key: "); _getch(); return 0; }

Рис. 6.1. Результат выполнения программы с вводом целых чисе

Возможный результат выполнения программы показан на рис. 6.1.

В программе использована функция scanf_s(), принятая в MS Visual Studio. В программе применено инкрементирование переменных, принятое в языке С, а именно ++i или ++j означает, что переменные увеличиваются на единицу. При этом знаки "++" могут располагаться перед именем переменной или после. Отличие в том, что ++i – это значение переменной после увеличения, а i++ – сначала переменная имеет заданное значение, а потом происходит ее увеличение. Для переменных цикла обе формы равнозначны.

Условием цикла является то, что пока переменная i меньше или равна переменной n (предполагается, что n больше начального значения i), то будут выполняться действия (печать и увеличение переменной j), заложенные в теле цикла. Расчет выражения, заключенного в круглые скобки оператора, предназначен для проверки нестрогого неравенства переменной i по отношению к переменной n. Если это неравенство выполняется, то в теле цикла происходят печать и увеличение (инкрементирование) переменных i, j.

Пример 2. Напишите программу посимвольного ввода предложения "Hello, world" и подсчитать число символов в нем (включая запятую и пробел).

Программный код решения примера:

#include <stdio.h>#include <conio.h> int main(void){ int c, i = 0; printf("\n Enter symbol-by-symbol the offer \"Hello, world\",\n press twice Ctrl+Z and press Enter:\n");printf("\t"); while ((c = getchar())!= EOF){printf("\t");c = getchar();++i;} printf("\n\t The number of characters: %d\n", i); printf("\n Press any key: "); _getch(); return 0;}

В программе ввод символьных данных должен завершиться комбинацией клавиш Ctrl+Z, что будет соответствовать окончанию ввода (файла), т.е. EOF. Оператор цикла while будет выполняться до тех пор, пока не встретится так называемый конец файла EOF. В предложении \"Hello, world\" два обратных слэша включены для вывода на консоль двойных кавычек.

Функции printf("\t") осуществляют табуляцию вводимых символов. Подсчет числа вводимых символов выполняется с помощью переменной цикла (счетчика) i, которая инкрементируется в теле цикла.

Заголовочный файл #include <conio.h> служит для поддержания консольного ввода-вывода для функции _getch(). Без него при компиляции программы могут выводиться предупреждения, хотя программа с предупреждениями работает.

Результат выполнения программы показан на рис. 6.2.

Рис. 6.2. Выполнение программы посимвольного ввода данных

Примечание. Прототип функции getchar() имеет следующий вид:

#include <stdio.h>int getchar(void);

Пример 3. Напишите программу табличного вывода строчных букв латинского алфавита и их десятичных кодов с помощью оператора цикла for.

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

Программный код решения примера:

#include <stdio.h>#include <conio.h>int main(void){ int j = 1; char a = 'a'; printf("\n Table code characters:\n");for (; a <= 'z'; ++a) printf("\n %4d) %2c: code%4d", j++, a, a); printf("\n\n Press any key: "); _getch(); return 0;}

Результат выполнения программы показан на рис. 6.3.

Рис. 6.3. Таблица десятичных кодов букв латинского алфавита

Форматированный вывод данных предусматривает выравнивание по правому краю, для чего предусматриваются числовые спецификаторы типа %4d и %2c для целых чисел и символов в функции printf().

Пример 4. Напишите программу расчета значений функции распределения потока Эрланга 4-го порядка с параметром = 2.3 на отрезке времени от 0 до 5 (условных единиц) с шагом 0.2:

Программный код решения примера:

#include <stdio.h>#include <conio.h>#include <math.h> int main(void){ int j, f, k = 4; double F, Lt, s, t = 0.0, Tend = 5.0; float L = 2.3F; printf("\n Erlang function of order %d, Lambda = %1.2f:\n\n", k, L); for (; t <= Tend; t += 0.2) { s = 0.0; f = 1; Lt = 1.0; for (j = 1; j <= k; ++j) { f *= j; Lt *= (L*t); s += (Lt/f)*exp(-L*t); } F = 1 - exp(-L*t) - s; printf("\t %lg\n", F); } printf("\n\n Press any key: "); _getch(); return 0;}

В программе использованы вложенные циклы for. Применены специфические условия изменения переменных (но характерных для языка С):

t += 0.2; /* t = t + 0.2; */f *= j; /* f = f * j; */t *= (L*t); /* Lt = Lt * (L*t); */

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

В программе также предусмотрено накопление суммы для каждого шага времени t. Для расчета экспоненты в заголовок программы включена библиотека математических функций #include <math.h>.

Результат выполнения программы показан на рис. 6.4

Рис. 6.4. Расчет функции распределения Эрланга 4-го порядка

Пример 5. Вычислите с точностью до "машинного нуля" значение суммы числового ряда:

Программный код решения примера:

#include <stdio.h>#include <conio.h> int main(void) { double denom; double sum1 = 0.0, sum2 = 0.0; int k = 1; denom = k * (k + 1) * (k + 2); // знаменатель ряда do { sum1 = sum2; sum2 += 1.0 / denom; denom = denom / k * (k + 3); ++k; } while (sum1 < sum2); printf("\n\t The amount of numerical series: %lg\n", sum2); printf("\n Press any key: "); _getch(); return 0;}

В приведенной программе сумма вычисляется как значение переменной sum2. Ее предыдущее значение сохраняется в переменной sum1. Так как приближенное значение с добавлением неотрицательных слагаемых не уменьшается, условием продолжения цикла служит отношение sum1 < sum2 (поскольку растет знаменатель denom). Когда при добавлении очередного слагаемого значение суммы остается неизменным (за счет конечной разрядной сетки для представления вещественных чисел), нарушается условие sum1 < sum2 и цикл прекращается. Таким образом, конечность разрядной сетки представления вещественных чисел в компьютере определяет собой "машинный нуль".

Инициализация знаменателя сделана до начала цикла. Форматный вывод результата выполнен с помощью спецификатора символа "l".

Результат выполнения программы показан на рис. 6.5.

Рис. 6.5. Результат подсчета суммы бесконечного ряда

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

Задача заключается в том, чтобы, например, число 123 переписать как 321.

Программный код решения примера:

#include <stdio.h>#include <conio.h> int main(void) { long int x, r=0; printf("\n Enter an integer: "); scanf_s("%ld", &x); printf("\n Reverse-digit number %ld:\n\n\t", x); do { r =r*10+ x % 10; x /= 10; } while (x!= 0); printf(" %ld", r); printf("\n\n Press any key: "); _getch(); return 0;}

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

Результат выполнения программы показан на рис. 6.6.

Рис. 6.6. Результат программы по реверсу числа

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

Программный код решения примера:

#include <stdio.h>#include <conio.h> int main (void) { int p = 0; char ch = 'A'; char i, j, k, ch2, kk, chA; chA = ch; printf("\n Enter a capital letter between \"A\" and \"S\": ");scanf_s("%c", &ch2, sizeof(char)); for(chA -= 1; chA >= ch2; chA--) { printf("\n Error! Press any key: "); _getch(); return -1; } for (kk = 'S'+1; kk <= ch2; kk++) {printf("\n Error! Press any key: "); _getch(); return -1;} k = ch2;for (kk = ch; kk <= k; kk++) { printf("\n "); for (ch2 = ch; ch2 <= k-p; ch2++) printf(" "); for (j = ch; j <= kk; j++) printf(" %c", j); for (i = kk; i > ch; i--) printf(" %c", i-1); p++; } printf("\n\n Press any key: "); _getch(); return 0;}

Пример выполнения программы показан на рис. 6.7.

Рис. 6.7. Пример горки букв

Контрольные вопросы

  1. Как организуются составные операторы циклов в языке С?
  2. Как организуются вложенные циклы в языке С?
  3. В каких случаях может произойти зацикливание при использовании оператора цикла с предусловием?
  4. В каких случаях может произойти зацикливание при использовании оператора цикла с постусловием?
  5. Сколько условий требуется для работы оператора цикла с параметром?
  6. Чем отличаются префиксное и постфиксное инкрементирование и декрементирование?
  7. Какое различие в операторах цикла между префиксным и постфиксным инкрементированием?
  8. Сколько операторов отношения в языке С? Перечислите их.
  9. Как реализуется взаимозаменяемость операторов цикла while и for?

Задание.

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

Вариант 1.

Задание 1.

Используя цикл for написать программу, позволяющую:

Задание 2.

, не используя оператор if и функцию возведения в степень.

Задание 3.

Задание 4.

Задание 5.

Вариант 2.

Задание 1.

Используя цикл for написать программу, позволяющую:

Задание 2.

Задание 3.

Задание 4.

Задание 5.

Вариант 3.

Задание 1.

Используя цикл for написать программу, позволяющую:

Задание 2.

Задание 3.

Задание 4.

Задание 5.

Вариант 4.

Задание 1.

Используя цикл for написать программу, позволяющую:

Задание 2.

Задание 3.

Задание 4.

Задание 5.

Вариант 5.

Задание 1.

Используя цикл for написать программу, позволяющую:

Задание 2.

Задание 3.

Задание 4.

Задание 5.

Вариант 6.

Задание 1.

Используя цикл for написать программу, позволяющую:

Задание 2.

Задание 3.

Задание 4.

Задание 5.

Вариант 7.

Задание 1.

Используя цикл for написать программу, позволяющую:

Задание 2.

Задание 3.

Задание 4.

Задание 5.

Вариант 8.

Задание 1.

Используя цикл for написать программу, позволяющую:

Задание 2.

Задание 3.

Задание 4.

Задание 5.

Вариант 9.

Задание 1.

Используя цикл for написать программу, позволяющую:

Задание 2.

Задание 3.

Задание 4.

Последовательность Фибоначчи образуется так: первый и второй члены последовательности равны 1.ю а каждый следующий равен сумме двух предыдущих (1, 1, 2, 3, 5, 8, 13, …). Найти первое число Фибоначчи, большее m (m>1).

Задание 5.

Вариант 10.

Задание 1.

Используя цикл for написать программу, позволяющую:

Задание 2.

Задание 3.

Задание 4.

Верно ли, что сумма первых n членов последовательности Фиббоначи заканчивается цифрой 5.

Задание 5.

Вариант 11.

Задание 1.

Используя цикл for написать программу, позволяющую:

Задание 2.

Задание 3.

Задание 4.

Найти произведение первых k членов этой последовательности.

Задание 5.

Вариант 12.

Задание 1.

Используя цикл for написать программу, позволяющую:

Задание 2.

. Функцию возведения в степень не использовать.

Задание 3.

Задание 4.

Задание 5.

Вариант 13.

Задание 1.

Используя цикл for написать программу, позволяющую:

Задание 2.

Задание 3.

Задание 4.

Задание 5.

Вариант 14.

Задание 1.

Используя цикл for написать программу, позволяющую:

Задание 2.

Задание 3.

Задание 4.

Задание 5.

Вариант 15.

Задание 1.

Используя цикл for написать программу, позволяющую:

Задание 2.

, не используя оператор if и функцию возведения в степень.

Задание 3.

Задание 4.

Задание 5.

Вариант 16.

Задание 1.

Используя цикл for написать программу, позволяющую:

Задание 2.

Задание 3.

Задание 4.

Задание 5.

Вариант 17.

Задание 1.

Используя цикл for написать программу, позволяющую:

Задание 2.

Задание 3.

Задание 4.

Задание 5.

Вариант 18.

Задание 1.

Используя цикл for написать программу, позволяющую:

Задание 2.

Задание 3.

Задание 4.

Последовательность Фибоначчи образуется так: первый и второй члены последовательности равны 1.ю а каждый следующий равен сумме двух предыдущих (1, 1, 2, 3, 5, 8, 13, …).Вычислить S – сумму всех чисел Фибоначчи, которые не превосходят заданного числа n (n>1).

Задание 5.

Вариант 19.

Задание 1.

Используя цикл for написать программу, позволяющую:

Задание 2.

Задание 3.

Задание 4.

Задание 5.

Дано натуральное число. Найти произведение его последних n цифр. Величины для хранения всех n последних цифр не использовать.

Вариант 20.

Задание 1.

Используя цикл for написать программу, позволяющую:

Задание 2.

Задание 3.

Задание 4.

Задание 5.

Дано пятизначное число. Найти произведение его цифр. Переменные для хранения всех цифр числа не использовать.

Вариант 21.

Задание 1.

Используя цикл for написать программу, позволяющую:

Задание 2.

Задание 3.

Задание 4.

Задание 5.

Вариант 22.

Задание 1.

Используя цикл for написать программу, позволяющую:

Задание 2.

, не используя оператор if и функцию возведения в степень.

Задание 3.

Задание 4.

Задание 5.

Вариант 23.

Задание 1.

Используя цикл for написать программу, позволяющую:

Задание 2.

Задание 3.

Задание 4.

Задание 5.

Вариант 24.

Задание 1.

Задание 2.

Задание 3.

Задание 4.

Задание 5.

Вариант 25.

Задание 1.

Используя цикл for написать программу, позволяющую:

Задание 2.

, не используя оператор if и функцию возведения в степень.

Задание 3.

Задание 4.

Задание 5.



<== предыдущая лекция | следующая лекция ==>
Фильтрация аналоговых сигналов | Цели и задачи социального марафона
Поделиться с друзьями:


Дата добавления: 2016-10-23; Мы поможем в написании ваших работ!; просмотров: 478 | Нарушение авторских прав


Поиск на сайте:

Лучшие изречения:

Логика может привести Вас от пункта А к пункту Б, а воображение — куда угодно © Альберт Эйнштейн
==> читать все изречения...

802 - | 798 -


© 2015-2024 lektsii.org - Контакты - Последнее добавление

Ген: 0.01 с.