|
||||||||
§6. Оператор безусловного перехода. Циклы. Блок-схемы. Оператор безусловного перехода. Иногда возникает необходимость перепрыгнуть из одного места программы в другое. Для этого в Pascal есть оператор безусловного перехода GoTo (идти в). В любом месте программы можно поставить метку и с помощью оператора GoTo заставить программу перепрыгнуть в это место. После метки в теле программы ставится двоеточие. Саму метку необходимо описать в разделе объявления меток после слова Label (метка). Пример: Program UslovniyPerehod; Label L,L1,L2; Begin GoTo L1; L:GoTo L2; L1:writeln('Перешли на метку L1'); GoTo L; L2:writeln('Перешли на метку L2'); end. ____________________________________ Перешли на метку L1 Перешли на метку L2 До настоящего времени все наши программы выполняли какую-либо работу и останавливались. Что бы снова выполнить эту же работу, необходимо было запустить программу заново. Сейчас с помощью оператора безусловного перехода мы можем написать простейший калькулятор, который не надо будет запускать каждый раз заново. Program ProstKalkulator; Label L; Var a,b:real; Begin L:Writeln('Введите два числа для сложения:'); read(a,b); Writeln(a,'+',b,'=',a+b); Write('Для повторения программы введите 1, '); Writeln('для выхода любую другую цифру.'); read(a); If a=1 then goto L; end. ________________________________________________________________________ Введите два числа для сложения: 3 4 3+4=7 Для повторения программы введите 1, для выхода любую другую цифру. 1 Введите два числа для сложения: 5 4 5+4=9 Для повторения программы введите 1, для выхода любую другую цифру. 5 На практике, программисты стараются избегать использования оператора безусловного перехода т.к. для реализации нелинейного хода программы существуют другие средства, о которых речь пойдёт дальше. Нелинейный ход программы возникает в том случае, если строчки программы выполняются не одна за другой, а происходит перескакивание на несколько вперёд или назад. Как раз с помощью данного оператора и реализуется нелинейный ход программы. Тем не менее ни кто не запрещает вам использовать этот оператор. В каких-то случаях он может оказаться просто незаменим. Циклы. Основная задача, которая ставится перед вычислительной машиной – это решение сложных задач, которые человеку довольно сложно решить самому. Обычно, если задача решается линейно, т.е. одно действие идёт за другим и больше не повторяется, то такую задачу проще решить самому, чем писать для её решения программу, а затем с помощью компьютера её решить. В другом случае, если какая-либо задача решается нелинейно, т.е. какие-то операции повторяются, то для решения такой задачи проще написать программу. Тогда компьютер повторит любую операцию любое количество раз, и при этом можно будет идти пить чай. Если программа начинает повторять один и тот же код множество раз, то этот код называется циклом. В Pascal существует три вида циклов. Один цикл повторяется определённое количество раз (счётный цикл), другие два повторяются до тех пор, пока выполняется какое-либо условие (циклы с условием). Счётный цикл. Рассмотрим первый цикл. Выглядит он следующим образом: For x:=1 to 3 do ...............; Вместо точек должен находиться код, который необходимо повторять. Как работает этот цикл? Попробуем перевести эту строчку на русский язык: «Для x равной 1 до 3 делать ….». Далее приведём словесное описание того, как работает такой цикл:
Наверно трудно уловить то, как работает цикл, читая словесное описание его работы. Что бы наглядно изображать, то как работает программа или какой-либо её отдельный кусок, существуют блок-схемы. Попробуем изобразить работу данного цикла с помощью блок-схемы: Блок-схема состоит из блоков, отсюда и название. Каждый блок обозначает определённое действие и представляет собой определённую фигуру. Стрелками обозначается порядок перехода из одного блока в другой. В прямоугольнике заключаются простые операторы или линейные процессы. В ромбике заключают какое-либо условие, поэтому из ромбика выходят две стрелки – одна если условие верно, другая если не верно. Овалом обозначается начало или конец алгоритма. В блок-схемах могут использоваться ещё другие фигуры, которые в рамках данного учебника мы рассматривать не будем. Перечисленных фигур вполне достаточно для наглядного изображения большинства алгоритмов. Теперь попробуйте заново прочитать абзац, где описано как работает цикл, и при этом посматривайте на блок-схему. Думаю, что при сочетании двух видов, словесного и графического, описаний алгоритма будет всё понятно. Даже если что-то с данным циклом не понятно, то не зацикливайтесь. Вам главное понять следующее: если нужно повторить цикл 3 раза, то переменной х необходимо присвоить значение 1 и делать его до числа 3: For x:=1 to 3 do ...............; Можно по-другому: присвоить значение 2 и делать до 4: For x:=2 to 4 do ...............; Здесь стоит отметить следующие нюансы. Переменная х должна быть типа byte или любого другого типа, который может содержать в себе только целые переменные. Об этих типах речь пойдёт в отдельном параграфе. Имя переменной может быть любым. Переменную х можно использовать в любом месте программы, а так же и внутри цикла. Однако менять переменную внутри цикла нельзя, можно использовать только её значение. Если код цикла состоит не из одной строчки, а из нескольких, то их необходимо выделить словами begin и end: For x:=2 to 4 do begin ...............; ...............; ...............; end; Так же вместо констант 1 и 3 можно использовать имена констант или переменные, но только типа целых чисел. Далее пример программы: Program ScetniyCikl; var x,y,z:byte; begin y:=1; z:=3; for x:=y to z do begin write('x='); write(x); writeln(' '); end end. ___________________ x=1 x=2 x=3 Обратите внимание, что для удобства чтения перед словами begin и end есть небольшой отступ, а перед строчками кода отступ немного больше. Дело в том, что внутри одного цикла может быть другой цикл, а внутри другого может быть третий и т.д. Что бы было наглядно видно, где начинается и заканчивается один цикл, а где другой, их выделяют отступами. Это, как было уже сказано, и есть хороший тон программирования. Например, код может выглядеть следующим образом: For i:=1 to 3 do begin ...............; For g:=1 to 3 do begin ...............; ...............; end; ...............; ...............; end; Небольшое отступление. Настоятельно рекомендую следовать следующему правилу: если вы написали слово begin, то обязательно сразу под ним напишите слово end, а потом уже вы добавите необходимое вам количество строчек между ними, и впишите туда необходимый код. При соблюдении этого правила вы исключите появление ошибок, которые потом будет трудно отследить. Так же рекомендую в формулах если вы поставили одну открывающую круглую скобку, то сразу же поставьте и другую – закрывающую. Циклы с условием. Двигаемся дальше. Рассмотрим циклы с условием. Эти циклы повторяются в зависимости от какого-то условия. Если условие верно, то цикл повторяется, если нет, то происходит выход из цикла. Разница этих двух циклов заключается в том, что в одном проверка условия происходит перед кодом цикла, в другом после кода цикла. Рассмотрим оба цикла по отдельности. В начале – цикл, в котором условие проверяется перед кодом цикла. В общем виде он выглядят следующем образом: While условие do ………….; По-русски – «Пока условие делать………;» Далее не буду словесно описывать работу данного цикал, а сразу приведу блок-схему: Далее пример программы и блок схема данной программы: Program CiklSUsl; var x:byte; begin x:=1; while x<=3 do begin writeln('x=',x); x:=x+1; end end. _____________________ x=1 x=2 x=3 Как видно, результат работы этой программы CiklSUsl абсолютно похож на результат работы программы ScetniyCikl. Следовательно, программы идентичны друг другу, т.к. делают одно и то же. Однако алгоритмы работы в них организованы по-разному. Основным отличием является то, что в первой программе ScetniyCikl, увеличение х происходит автоматически, а во второй программе CiklSUsl пришлось вручную прописать строчку, в которой х увеличивается. Обратите внимание, что в циклах с условием переменную, находящуюся в условии цикла, менять можно, причём даже нужно иначе вы ни когда можете не выйти из цикла. На данном этапе необходимо усвоить следующее. В первом счётном цикле происходит автоматический счёт целых чисел от одного определённого значения до другого конечного значения, и он выполняется, пока счётная переменная не станет больше определённого конечного значения. Цикл с условием выполняется пока условие верно. Как только условие перестанет выполняться, цикл прекратит свою работу. В начале параграфа мы рассматривали оператор безусловного перехода GoTo, и было сказано, что его использование нежелательно. Приведу пример программы, которая идентична программе ProstKalkulator, но без использования оператора безусловного перехода: Program ProstKalkulator_1; Var a,b,c:real; Begin c:=1; while c=1 do begin Writeln('Введите два числа для сложения:'); read(a,b); Writeln(a,'+',b,'=',a+b); Write('Для повторения программы введите 1,’); Writeln(' для выхода любую другую цифру.'); read(c); end end. _________________________________________________________________________ Введите два числа для сложения: 35 23 35+23=58 Для повторения программы введите 1, для выхода любую другую цифру. 1 Введите два числа для сложения: 45 56 45+56=101 Для повторения программы введите 1, для выхода любую другую цифру. 4 В чём здесь преимущество перед оператором GoTo. Здесь наглядно видно, где начинается и где заканчивается цикл. Допустим цикл состоял бы из нескольких десятков строк, тогда с оператором GoTo было бы менее понятно как работает программа. Далее рассмотрим последний оставшийся цикл с условием. В общем виде он выглядит следующим образом: Repeat ……… until условие; По-русски – «Повторять ……….. до тех пор пока не станет условие;». Блок-схема алгоритма: Обратите внимание, что проверка условия происходит в конце цикла, т.е. один раз (самый первый) код цикла будет выполнен в любом случае. Так же стоит отметить, что код цикла повторяется, если условие ложно, т.е. код цикла повторяется до тех пор, пока условие не станет верным. Так же как и в предыдущем цикле переменные, которые участвуют в условии можно и нужно менять внутри цикла. Далее пример программы: Program CiklSUsl_1; var x:byte; begin x:=0; repeat x:=x+1; writeln('x=',x); until x>=3; end. __________________ x=1 x=2 x=3 Как видно из результата, эта программа идентична программе CilkSUsl и программе ScetniyCikl. Однако задача здесь решена с помощью другого алгоритма. В некоторых случаях задачу можно решить с помощью любого из трёх циклов, однако в более сложном случае может подойти только один. Если вы попытаетесь решить задачу неподходящим циклом, то обречёте себя на лишние хлопоты при отладке программы. Если внимательно изучить программу CilkSUsl_1, то вы увидите, что между словами repeat и until нет слов begin и end, хотя и используется несколько строчек кода. Дело в том, что в данном цикле слова repeat и until сами выполняют функцию слов begin и end. Здесь стоит заметить, что в некоторых случаях может случиться так, что условие никогда не измениться. Тогда компьютер никогда не выйдет из цикла. Он зациклится или попросту зависнет. В практической деятельности необходимо предусматривать изменение переменных, участвующих в условии, внутри цикла. В некоторых случаях, такие переменные могут не измениться. В таком случае необходимо предусмотреть вариант выхода из цикла не по условию. Выход из цикла не по условию. Для немедленного выхода из цикла существуют следующие процедуры: Break – реализует немедленный выход из цикла, действие процедуры заключается в передаче управления оператору, стоящему сразу за концом циклического оператора; Continue – обеспечивает досрочное завершение очередного прохода цикла, передаёт управление в самый конец циклического оператора. Данные процедуры можно использовать не только в циклах с условием, но и в счётном цикле. Теперь пример программы, в которой используется цикл с условием, и где условие ни когда не станет правдой. Выход из цикла здесь реализован с помощью процедур Break и Continue. Можете поэкспериментировать с данной программой, и вам станет яснее, как работаю процедуры Break и Continue. Program DosVihod; {--------------------------------- Программа демонстрирует досрочное завершение прохода цикла и досрочный полный выход из цикла. ---------------------------------} Var c:byte; Begin c:=4;//Инициализация переменной. While c<>3 do begin writeln('Цикл начал свою работу.'); Writeln('Если хотите выйти из цикла введите 1'); Writeln('Если хотите завершить проход цикла введите 2'); Write('Если хотите продолжить нормальный проход введите любую'); Writeln(' другую цифру'); readln(c); If c=1 then break;//Выходим из цикла. If c=2 then begin writeln('Цикл не совершил полный проход.'); Writeln;//вставили пустую строку. continue;//Завершаем проход цикла. end; c:=4;//Что бы цикл повторился снова, если пользователь ввёл цифру 3. writeln('Цикл полностью совершил проход.'); Writeln;//вставили пустую строку. end; writeln;//вставили пустую строку. Writeln ('Конец программы.'); end. _________________________________________________________________________ Цикл начал свою работу. Если хотите выйти из цикла введите 1 Если хотите завершить проход цикла введите 2 Если хотите продолжить нормальный проход введите любую другую цифру 3 Цикл полностью совершил проход. Цикл начал свою работу. Если хотите выйти из цикла введите 1 Если хотите завершить проход цикла введите 2 Если хотите продолжить нормальный проход введите любую другую цифру 2 Цикл не совершил полный проход. Цикл начал свою работу. Если хотите выйти из цикла введите 1 Если хотите завершить проход цикла введите 2 Если хотите продолжить нормальный проход введите любую другую цифру 1 Конец программы. В данном параграфе мы изучили оператор безусловного перехода, т.е. научились «прыгать» из одного места программы в любое другое. Познакомились с блок-схемой алгоритма. А так же изучили три цикла языка Pascal. Задачи: Примечание: все предложенные далее задачи достаточно сложны, поэтому снабжайте их комментариями, и давайте им свои имена. 1. Вывести на экран ряд целых чисел от 1 до 50 в виде таблицы. Причём числа должны идти последовательно друг за другом через пробел по десять в каждой строчке. 2. Написать программу калькулятор, которая будет выполнять сложение, вычитание, умножение и деление двух чисел. Причём, выполнив одно действие, необходимо, что бы для выполнения ещё одного действия программу не нужно было бы запускать заново. 3. Написать программу нахождения факториала заданного с клавиатуры числа. Причём, найдя один факториал, необходимо, что бы для нахождения ещё одного программу не нужно было бы запускать заново. 4. Дано следующее выражение с двумя неизвестными: . – целое число, которое вводится с клавиатуры. Написать программу нахождения неизвестных и . Задача должна быть решена методом подбора значений. Предусмотреть вывод сообщения, если варианты значений неизвестных найдены не будут. Примечание: может получиться несколько вариантов значений неизвестных. Необходимо вывести на экран все варианты и их количество. Решение: 1. Program VivodChisel; {Программа для вывода ряда целых чисел в виде таблицы.} Var k,//Переменная для формирования строк. g,//Переменная для формирования столбцов. x//Переменная для хранения числа, которое выводим на экран. :byte; Begin x:=1; //Начальное значение числа. for k:=1 to 5 do //Формируем строчки. begin for g:=1 to 10 do //Формируем столбцы. begin write(x:3);//Выводим число на экран. x:=x+1;//Увеличиваем число на единицу. end; writeln;//Переходим на следующую строчку. end end. _______________________________________________________________ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 2. Program Calculyator; {Программа производит сложение, вычитание, умножение и деление двух чисел.} Label l;//Метка для возврата на начало программы. Var x,y:real;//Два числа для проведения операций. c:byte;//Переменная для принятия решений. Begin {Вводим два числа.} l:Writeln('Введите два числа'); Readln(x,y); {Предлагаем пользователю выбрать операцию.} Writeln('Введите номер операции согласно следующего списка:'); Writeln('Сложение - 1'); Writeln('Вычитание - 2'); Writeln('Умножение - 3'); Writeln('Деление - 4'); {Считываем номер необходимой операции.} Readln(c); {В зависимости от выбранной пользователем операции производим вычисления.} If c=1 then Writeln(x,'+',y,'=',x+y); If c=2 then Writeln(x,'-',y,'=',x-y); If c=3 then Writeln(x,'*',y,'=',x*y); If c=4 then Writeln(x,'/',y,'=',x/y); {Если пользователь ввёл неверно номер операции выдаём сообщение об этом.} If (c<>1)and(c<>2)and(c<>3)and(c<>4) then writeln('Вы ввели не правильный номер операции'); {Предлагаем пользователю выбор продолжить работу или завершить.} Write ('Для продолжения работы введите 1,'); Writeln(' для выхода из программы - другую цифру'); Read(c); Writeln;//Пустая строка. {Если пользователь решил продолжить переходим на начало программы.} If c=1 then goto l; {Если пользователь решил завершить работу выводим сообщение о завершении работы программы} Writeln('Программ завершила свою работу.'); end. _________________________________________________________________________ Введите два числа 4 3.5 Введите номер операции согласно следующего списка: Сложение - 1 Вычитание - 2 Умножение - 3 Деление - 4 3 4*3.5=14 Для продолжения работы введите 1, для выхода из программы - другую цифру 1 Введите два числа 5.67 34 Введите номер операции согласно следующего списка: Сложение - 1 Вычитание - 2 Умножение - 3 Деление - 4 4 5.67/34=0.166764705882353 Для продолжения работы введите 1, для выхода из программы - другую цифру 5 Программ завершила свою работу 3. Примечание: факториал числа – это произведение целых чисел от одного до этого числа. При записи факториала перед числом ставиться восклицательный знак. Например: . Так как факториалы даже небольших чисел имеют достаточно большие значения, то необходимо для их хранения использовать тип Real. Program Factorial; {Программа вычисляет факториал числа.} Var F:real;//Переменная хранит в себе произведение чисел. k,//Переменная для организации счётного цикла для вычисления //факториала. c,//Переменная для ввода выбора пользователя. x//Переменная для ввода числа, факториал которого будет вычисляться. :Byte; Begin c:=1;//Начальное значения переменной, что бы цикл прошёл первый раз. While c=1 do begin {Предлагаем пользователю ввести число факториал которого будет вычислен.} Writeln('Введите целое число.'); read(x); F:=1;//Начальное значение Факториала равно единице. For k:=1 to x do F:=F*k;//Вычисляем факториал. Writeln('!',x,'=',F);//Выводим на экран результат. {Предлагаем пользователю выбор продолжить работу или завершить.} Write('Для продолжения работы введите 1 для выхода - любую '); Writeln('цифру.'); Read(c); end; end. _________________________________________________________________________ 2 !2=2 Для продолжения работы введите 1 для выхода - любую цифру. 1 Введите целое число. 3 !3=6 Для продолжения работы введите 1 для выхода - любую цифру. 1 Введите целое число. 6 !6=720 Для продолжения работы введите 1 для выхода - любую цифру. 2 4. Var x,//Переменная для перебора значений x. y,//Переменная для перебора значений y. s,//Переменная для счёта количества вариантов, счётчик вариантов. A//Переменная для ввода значения числа А. :byte; Begin Writeln('Введите число А'); Read(A); s:=0;//Начальное значение. {Цикл перебора значений.} For x:=0 to 255 do begin For y:=0 to 255 do begin if (4*x+2*y+5)=A then begin //Если выражение верное, то s:=s+1;//увеличиаем счётчик вариантов Writeln('x=',x:2,' y=',y:2);//и выводим значения //неизвестных. end; end; end; //Сообщение если вариантов нет. If s=0 then writeln('Не найдено ни одного варианта неизвестных.') //Сообщение о количестве найденных вариантов. else writeln('Всего найдено ',s,' вариантов значений неизвестных.'); end. _________________________________________________________________________ Введите число А 45 x= 0 y=20 x= 1 y=18 x= 2 y=16 x= 3 y=14 x= 4 y=12 x= 5 y=10 x= 6 y= 8 x= 7 y= 6 x= 8 y= 4 x= 9 y= 2 x=10 y= 0 Всего найдено 11 вариантов значений неизвестных.
|