Учебное пособие для школьников 79 классов СанктПетербург Павловск 20152016 Введение
Скачать 0.84 Mb.
|
Program Formats; Uses CRT; var x : real; begin x:=1234.567; writeln(x); writeln(x:8:3); writeln(x:8:2); writeln(x:8:1); writeln(x:12); writeln(x:14); end Рассмотрим еще одну программу, которая строит таблицу длин окружностей радиусами от 0.1 до 1 см с шагом 0.1 (заметьте, что для числа π используется встроенная константа pi ): Program Table; Uses CRT; var r, s : real; begin r:=0.1; // Начальное значение repeat s:=2*pi*r; // Вычисление длины writeln(r:3:1,s:6:2); // Вывод r:=r+0.1; // Увеличение радиуса на 0.1 until r>1.0; // Условие окончания цикла end Задание 8 (часть 2) 3. Проанализируйте пример и постройте аналогичную программу, вычисляющую площади круга (по формуле 2 s r = π ). (2 балла) 4. Напишите программу, которая вводила бы с клавиатуры значения времени и скорости, вычисляла бы пройденный путь. (3 балла) 5. Напишите программу, которая вводила бы с клавиатуры 10 вещественных чисел и вычисляла бы их среднее арифметическое. (5 баллов) 6. * Напишите программу, которая вводила бы градусы, минуты и секунды дуги переводила их в градусы и его десятичные доли. Тема №9. Подпрограммы-функции А.С.Цветков, ABC Pascal - 27 - 19.09.2015 Занятие №9 Подпрограммы на языке Pascal Функции При решении сложных задач разумно разбить алгоритм на несколько более простых составляющих. В языке Pascal существуют специальные средства для этого – подпрограммы. Есть два вида подпрограмм: процедуры и функции. Функция получает информацию от вызывающей программы через свои параметры. Параметры, описанные в заголовке функции, называются формальными параметрами. Параметры, указанные при вызове функции называют фактическими. Типы и число фактических параметров должны соответствовать типу и числу формальных параметров. Следующий пример иллюстрирует работу функций. Program Table; Uses CRT; // Подключение модулей // Описания функций, требующихся в программе function cube(x:real):real; // возведение в куб begin cube:=x*x*x; // имени функции присваивается значение end; function sign(x:real):integer; // вычисление знака числа begin if x>0 then sign:=1 else if x=0 then sign:=0 else sign:=-1; end; // ==== Начало главной программы ========== var a : real; // блок описания переменных const a1 = -5.0; // блок описания констант (постоянных) a2 = +5.0; st = 0.5; begin a:=a1; while (a<=a2) do begin writeln(a:4:1,cube(a):10:3,sign(a):3); // вызов функций a:=a+st; end; end. Обратите внимание, что внутри тела функции (заключенного в операторные скобки begin … end) вы обязаны хотя бы один раз имени функции присвоить значение. В этой программе также используется новый материал, не связанный с функциями, – это константы. Значение констант задается через знак равенства (а не присваивания). Тип константы определяется из типа присваиваемого значения. Константы, в отличие от переменных, не могут менять свое значение. Тема №9. Подпрограммы-функции А.С.Цветков, ABC Pascal - 28 - 19.09.2015 Рассмотрим еще один пример, в котором функция имеет два параметра разного типа. Program Power2; Uses CRT; function power(x : real; n : integer) : real; // возведение в степень var i : integer; // локальные переменные r : real; begin r:=1.0; for i:=1 to n do r:=r*x; // накопление произведения power:=r; // результат присвоить имени функции end; // ==== Начало главной программы ================ var i : integer; // блок описания переменных begin for i:=1 to 10 do writeln(i:2,power(2.0,i):6:0); end. В данном примере функция имеет два формальных параметра (типа real и типа integer), а также две локальных переменных. Имена локальных переменных действуют только внутри тела функции . Переменная i в главной программе, и переменная i внутри функции – это две разных переменных. При вызове функции первый фактический параметр соответствует первому формальному параметру. Второй параметр – второму. Задание 9 1. Модифицируйте последний пример таким образом, чтобы функция power вычисляла правильно не только натуральные степени, но и отрицательные. Напоминание: 1 n n x x − = . Подсказка: следует использовать оператор if, а также функцию abs(n), которая вычисляет модуль числа. (5 баллов) 2. Напишите функцию, вычисляющую факториал числа ! 1 2 3 n n = ⋅ ⋅ ⋅ ⋅ … . Подсказка: ее несложно сделать, путем модификации функции power. (5-8 баллов) Тема №10. Подпрограммы-процедуры А.С.Цветков, ABC Pascal - 29 - 19.09.2015 Занятие №10 Подпрограммы на языке Pascal Процедуры Для выполнения каких-либо действий (а не вычислений значений) существуют подпрограммы-процедуры . Они также могут принимать параметры, как и подпрограммы- функции. Давайте сразу проиллюстрируем работу процедуры на примере графической программы. В стандартной графической библиотеке нет процедуры, рисующей треугольники. Давайте создадим такую процедуру и проверим ее работу. Program UseProc; Uses GraphABC; Procedure Triangle(x1,y1,x2,y2,x3,y3:integer); // Процедура рисует треугольник begin line(x1,y1,x2,y2); line(x2,y2,x3,y3); line(x3,y3,x1,y1); end; // Главная программа begin SetWindowSize(500,500); Triangle(100,200,400,300,250,150); Triangle(10,20,30,40,50,10); end. Как мы видим, процедура Trianlge имеет шесть целочисленных параметров и вызывает функции трижды функции Line для соединения точек. Создав такую процедуру, мы можем использовать ее столько раз, сколько нам надо в главной программе. Задание 10 1. Создайте еще несколько новых графических процедур, которые бы расширили возможность стандартной библиотеки (ромб, параллелограмм, и т.п.) (по 3-4 балла за каждую) Тема №10. Подпрограммы-процедуры А.С.Цветков, ABC Pascal - 30 - 19.09.2015 Модули (Units) Вы, наверное, обратили внимание на неудобство, связанное с тем, что все подпрограммы (как процедуры, так и функции) размещаются перед главной программой. Хотелось бы разместить их в отдельную библиотеку. Такая возможность есть, её предоставляют модули. Поместим описание процедуры Triangle в модуль MyGraph. Unit MyGraph; // Заголовок модуля. Имя файла модуля должно совпадать // с именем модуля! Т.е. в нашем случае оно должно быть // MyGraph.pas, иначе главая программа его не найдет! Uses GraphABC; // Модули могут использовать другие модули Procedure Triangle(x1,y1,x2,y2,x3,y3:integer); // Эта процедура находится в модуле MyGraph begin line(x1,y1,x2,y2); line(x2,y2,x3,y3); line(x3,y3,x1,y1); end; end . // Этот оператор – завершение модуля. Теперь главная программа будет выглядеть так: Program UseProc; Uses GraphABC, MyGraph; // Использование стандартного и собственного модуля begin SetWindowSize(500,500); // Эта процедура описана в GraphABC Triangle(100,200,400,300,250,150); // Эта процедура описана в MyGraph Triangle(10,20,30,40,50,10); end Модули могут содержать неограниченное число процедур, функций, а также описаний глобальных переменных, констант (об этом позже). Задание 10 2. Сформируйте модуль с вашими собственными графическими процедурами (5 баллов) Тема №11. Способ передачи параметров А.С.Цветков, ABC Pascal - 31 - 19.09.2015 Занятие №11 Способы передачи параметров Параметры-значения и параметры-переменные Каким образом подпрограмма может вернуть главной программе какую-либо информацию? До сих пор это могла делать только подпрограмма-функция, возвращая через свое имя только одно значение. А как поступить, если надо вернуть из подпрограммы несколько значений? Для примера напишем подпрограмму, которая должна вычислить длину окружности ( 2 L r = π ) и площадь круга ( 2 S r = π ) по заданному радиусу. Program ProcUse; Uses CRT; // вычисление длины окружности и площади круга Procedure Pr(R,L,S:real); begin L:=2*PI*R; S:=PI*sqr(R); end; // ГЛАВНАЯ ПРОГРАММА var rad, len, area : real; begin write('Введите радиус '); readln(rad); Pr(rad, len, area); writeln('Длина окружности ', len); writeln('Площадь круга ', area); end. Попробуйте выполнить данную программу. Вы обнаружите странный результат: какое бы значение радиуса вы не вводили, результат будет один и тот же: длина окружности и площадь круга будут равны 0! В чем дело? Оказывается тот способ передачи параметров подпрограмме, который мы использовали не подходит для решения нашей задачи. Используемый до сих пор способ называется передача параметров по значению . Суть его заключается в том, что подпрограмма создает копии параметров (в другой терминологии – локальные переменные подпрограммы), в которые помещаются значения, заданные в фактических параметрах в главной программе. Т.е. по смыслу такие параметры являются входными, т.е. предназначенными для передачи информации из главной программы в подпрограмму, но не наоборот. Однако этот подход имеет тот плюс, что подпрограмма гарантирует, что она не изменит фактические параметры. Тема №11. Способ передачи параметров А.С.Цветков, ABC Pascal - 32 - 19.09.2015 Второй способ называется передача параметров по ссылке. Изменим заголовок процедуры Pr на следующий: Procedure Pr(R: real; var L,S:real); Обратите внимание на появившееся ключевое слово var. Оно говорит о том, что два последних параметра процедуры будут являться изменяемыми. Для таких параметров используется другой способ сопоставления с фактическими (передаются на самом деле адреса параметров). В связи с этим необходимо запомнить, что в качестве формальных параметров, соответствующих параметрам переменным, могут использоваться только переменные, но не константы! Т.е. вызов Pr(5,6,7) ошибочен, возможно, лишь Pr(5,a,b), где a и b – вещественные переменные. Первый параметр мы оставили, как и раньше, обычным параметром, передаваемым по значению. Выполним теперь программу. Работает! Задание 11 1. Напишите процедуру с двумя целочисленными параметрами, которая бы меняла местами их значения. Проверьте ее работу. (3 балла) 2. Напишите процедуру, аналогичную процедуре Pr, которая вычисляла бы периметр и площадь квадрата со стороной r и а также объем куба с тем же самым ребром r. (2 балла) Тема №12. Массивы А.С.Цветков, ABC Pascal - 33 - 19.09.2015 Занятие №12 МАССИВЫ Тема имеет исключительно важное значение В практике программирования часто встречаются задачи, в которых требуется применение регулярных, пронумерованных данных: таблицы, результаты наблюдений, проекции векторов, числовые матрицы, каталоги библиотек и т.д. Для работы с такими данными практически во всех языках программирования существует понятие массива. Массив – это регулярная структура данных, которая состоит из пронумерованных компонент одного и того же типа. Этот тип мы будем называть базовым типом. Массивы могут быть одномерными: A 1 A 2 A 3 A 4 A 5 A 6 A 7 A 8 и многомерными (например, двумерными): A 11 A 12 A 13 A 14 A 21 A 22 A 23 A 24 A 31 A 32 A 33 A 34 С точки зрения машинной реализации, все массивы – одномерные, разница лишь в том, как пронумерованы элементы массива. Описание одномерного массива, если считать его элементы целыми числами выглядит следующим образом: A : array [1..8] of integer; здесь array – ключевое слово, которое и обозначает собственно массив, в квадратных скобках указан диапазон первого и единственного индекса. В Pascal’е в качестве диапазона индекса может выступать любой отрезок перечислимого типа, например ‘A’..’H’, либо 0..7. Однако на практике чаще всего удобнее в качестве индексов использовать отрезок целого типа, причем нижний (меньший) индекс разумно выбирать единицей или нулем. Одной из самых неприятных ошибок программирования – является ошибка обращения к несуществующему элементу массива, или как говорят, ошибка выхода индекса за допустимый диапазон. Поэтому предыдущее определение массива A лучше переписать так: Const N = 8; Var A : array [1..N] of integer; и в дальнейшем в программе при работе с массивом использовать не конкретные числа, а константы, которые определяют диапазон индексов, кроме того, программу можно будет легко модифицировать для работы с массивом другой размерности, так как необходимо будет изменить всего лишь одну строчку! Тема №12. Массивы А.С.Цветков, ABC Pascal - 34 - 19.09.2015 Иногда формальность описания следует развить, выделив описание типа отдельно, это будет абсолютно необходимо, если вы собираетесь использовать в процедурах и функциях параметры-массивы. Const N = 8; Type TA = array [1..N] of integer; Var A : TA; Дополнительные удобства этого подхода заключаются в том, что массивы, описанные в разных местах как массивы типа TA, будут являться совместимыми по типу, а в случае описания массивов A и B одинаковым способом, но без объявления типа- массива, они будут считаться несовместимыми. Например, Const N = 8; Type TA = array [1..N] of integer; Var A : TA; Var B : TA; здесь A и B – массивы одного и того же типа. А здесь: Const N = 8; Var A : array [1..N] of integer; Var B : array [1..N] of integer; здесь A и B – массивы будут считаться разных типов. Хотя следующее описание определяет массивы одинаковых типов: Const N = 8; Var A,B : array [1..N] of integer; В качестве базового типа допустим абсолютно любой тип, в том числе и массив, т.е. допустим массив массивов: Const M = 5; N = 8; Var A : array [1..M] of array [1..N] of integer; Подобная ситуация встречается довольно часто, поэтому для нее существует разумное сокращение: Const M = 5; N = 8; Var A : array [1..M,1..N] of integer; Следует учесть, что многомерные массивы, даже при небольших диапазонах индексов имеют тенденцию занимать много памяти. Основные приемы работы с массивами Рассмотрим выполнение элементарных манипуляций с массивами. Самая простая задача – заполнение всех элементов одним и тем же значением: {Инициализация массива} for i:=1 to N do A[i]:=0; Обратите внимание, как осуществляется доступ к элементам массива – после имени массива в квадратных скобках указывается индекс, который может быть произвольным выражением, лишь бы его значение не выходило за указанный при описании диапазон. Подобная конструкция допустима везде, где допустима простая переменная. Тема №12. Массивы А.С.Цветков, ABC Pascal - 35 - 19.09.2015 Цикл for – чрезвычайно удобная и полезная вещь при работе с массивами. Оператор вида for i:=1 to N do – можно «переводить» как «выполнить для всех элементов массива». Если два массива одного типа, то допустимо присваивание одного массива другому одним оператором: B:=A; Следующие два примера показывают, как осуществить ввод-вывод с небольшим сервисом: {ввод массива} for i:=1 to N do begin write('Ввeдите ',i,'-й элемент: '); readln(A[i]) end ; Из этого примера видно, что массив вводится поэлементно, и как организовать нехитрый сервис. Вывод производится аналогично: {вывод массива} for i:=1 to N do writeln('A[',i,']=',A[i]); Теперь рассмотрим самую первую нашу задачу на обработку массива – поиск максимального элемента. Поступим следующим образом: пусть максимальный элемент массива – первый, заведем для него специальную переменную; затем будем просматривать поочередно последующие элементы, и если окажется, что нам встретится элемент больший, чем уже определенное число, то заменим его на этот элемент массива. Таким образом, когда мы просмотрим весь массив, окажется, что наша переменная содержит искомое значение: {определение максимального значения} max:=A[1]; for i:=2 to N do |