Основы программирования на языке Паскаль
p align="left">Заметим, что оператор write отличается от оператора writeln тем, что он не начинает вывод с новой строки, а продолжает писать в той же строке, т.е. после второго выполнения внутреннего цикла на экране появитсяi= 1, j=20 i= 1, j=21. Машина продолжит выполнение внутреннего цикла, и, когда он закончится (выполнится для j = 20.21.22.23), на экране будет строка i = 1 j = 20 i =l j = 21 i = 1 j = 22 i = 1 j = 23. Внутренний цикл закончится, однако тело внешнего цикла еще не закончилось, поэтому выполняется оператор writeln, который переводит курсор на новую строку. После этого тело внешнего цикла закончится, но сам цикл отработал только для i = 1. Поэтому внешний цикл продолжит работу, присвоив i: =2 и вновь начав выполнение своего тела. Встретив внутренний цикл j:=1, на экран с новой строки выведется: i=2, j=20, затем j:=2 и к этой строке добавится i=2, j=21 и т.д., пока не закончится внутренний цикл. Таким образом, внешний цикл, изменяя i от 1 до 5, заставит каждый раз выполняться полностью внутренний цикл, и в результате работы программы на экране появится: i=l, j=20 i=1, j=21 i=1, j=22 i=1, j=23 i=2, j=20 i=2, j=21 i=2, j=22 i=2, j=23 i=3, j=20 i=3, j=21 i=3, j=22 i=3, j=23 i=4, j=20 i=4, j=21 i=4, j=22 i=4, j=23 i=5, j=20 i=5, j=21 i=5, j=22 i=5, j=23 Вкладывать циклы друг в друга можно любое количество раз, необходимо лишь помнить, что количество выполнений самого внутреннего тела цикла при этом будет расти в геометрической прогрессии. Так, например, for i:=l to 100 do for j:=l to 100 do for k:=l to 100 do writeln (i, j, k); дает столбик цифр: 111 112 113 114 - - - - - 121 122 123 124 - - - - - 211 212 213 - - - - - 100100100, что составляет 1000000 строчек. Пример: найти rez = f (х1) + f (х2 )+.. .+f (x6), где f(x) считать с точностью не менее e=0.01; х1=0.1, затем xn=xn-l+0.2, пока х не станет равным 1.1. Нам нужно вычислить rez. Поскольку это будет сумма, то вначале положим rez=0, затем вычислим f(х1) с нужной точностью и добавим к rez, и т.д., то есть: Rez : = 0 ; x:=0.l; for i:=l to 6 do Begin Rez:=Rez+f(x); x:=x+0.2; end; Теперь в данную программу нужно "вставить" вычисленные f(x) с необходимой точностью. Для этого найдем сумму, составляющую f(x) для n элементов, затем - для n+l элемента, сравним их по модулю и, когда разность между ними будет меньше Е, сумму для n+l элемента ряда примем за более точную и добавим к Rez. При вычислении f(x) количество членов ряда, которые нам придется суммировать, не известны, поэтому придется применять цикл типа repeat или while. Кроме того, в элементы ряда входит 2n! Факториал подсчитывается по схеме 1! = 1, 21 = 12; з! =123 и т.д., т.е. например, 8! = 12345678. Далее, при подсчете следующего значения ряда, можно величину 2n! найти по схеме: fak: = fak(n-l)n. Ряд у нас знакопеременный, т.е. меняется '+', '-' перед каждым членом ряда. Меняем знак с помощью схемы znak: = znak(-1). Если исходный знак = +l, то в ячейке znak будет храниться то +l, то -1. С учетом сказанного выше f(x) с нужной точностью вычисляется: fxpred: = 0; fxpos: =l, n: = 2; znak: = 1; fak: = 1; while Abs(fxpos - fxpred) > = 0.01 do Begin fxpred: = fxpos: znak: = znak(-1); fak: = fak(n-l)n; fxpos: = fxpos+znakexp(nin (x))/fak; n: = n+2; end; Соединив оба фрагмента программы и снабдив их описаниями, получим готовую программу: Program Prim22; Var n,fak,i,znak:longint; rez,x,fxpred,fxpos:real; BEGIN rez:=0; x:=0.1; writeln; for i:= 1 to 6 do Begin fxpred:=0; fxpos:=1; n:=2; znak:=1; fak:=1; while abs(fxpos-fxpred)>=0.001 do Begin znak:=znak*(-1); fak:=fak*(n-1)*n; fxpred:=fxpos; fxpos:=fxpos+znak*exp(n*ln(x))/fak; n:=n+2; end; writeln('x=',x*180/pi,'(ја ¤) cos(x)=',fxpos); x:=x+0.2; rez:=rez+fxpos; end; writeln('rez=',rez); readln; END. 5. Ввод - вывод5.1. Общие положения Ввод-вывод выполняется с помощью операторов read, readln - читать и write, writeln - писать. Читать и писать определяется по отношению к оперативной памяти (ОП). Так, read, readln - читать, т. е. вводить с внешнего устройства (файла) и заносить данные в ОП, write, writeln - писать, т.е. выводить данные из ОП на внешний файл (устройство). Файл состоит из компонент, структура которых определяется при его создании. Внешними устройствами (файлами) могут быть: экран монитора, клавиатура, память на гибких дисках, память на жестком или лазерном дисках, линии связи и т.п. В операторах ввода-вывода указывается имя файла, с которым будет производиться ввод-вывод, этот файл считается логическим. Кроме того, есть понятие физического файла. Физический файл - это устройство, Например, гибкий магнитный диск, жесткий диск и т. д. Логический файл имеет имя, которое можно указывать в операторах ввода-вывода.
5. 2. Ввод Ввод производится с помощью операторов read или readln. Формат операторов: read (FV, х1, х2, ..., хn); или readln (FV, х1, х2, ..., хn); где FV - имя файла, с которого считывается информация, а х1, х2 и т.д. - ячейки памяти, в которые заносится информация, считываемая с файла. Если FV отсутствует, то чтение производится с клавиатуры. Файл представляет собой как бы ленту с компонентами (рис 5.1): Компонента может быть данным любого типа (см. с.9). Оператор readln начинает считывание с начала новой компоненты, а read может начинать не с начала. Если прежнее чтение закончилось внутри компоненты, то следующий read будет читать с того места, на котором закончилось предыдущее чтение (рис. 5.2). В данном случае файл организован на каком-либо носителе (например на диске) и состоит из компонент, в каждой находится по три данных. Если для чтения из файлов применить операторы read (a, b); read (c, d); то в памяти будет а=3.2, b=8.6, c=0.2, d=7.01; если - операторы readln (a, b); readln (c, d), то в памяти а=3.2, b=8.6, c=7.01, d=8.3. Замечание. При чтении данных с клавиатуры необходимо всегда использовать операторы readln (х1, х2, ..., хn); (без указания имени файла).
5. 3. Вывод Вывод производится с помощью операторов write или writeln. Формат операторов: write (FV, x1, x2, ..., xn); writeln (FV, x1, x2, ..., xn); Работа оператора: в файл с именем FV выводится информация из ячеек оперативной памяти x1, x2, ..., xn. Если FV отсутствует, вывод производится на экран монитора. При этом оператор write начинает вывод в то место компоненты файла, где был закончен прежний вывод, а оператор writeln начнет вывод с начала новой компоненты. Проиллюстрируем работу этих операторов на примере вывода данных на экран монитора. Имеется фрагмент программы (напомним, что текст в скобках { } является комментарием и машиной не воспринимается); Var a, b, c, d : integer; Begin a: = 25; b: = 38; c: = 126; d: = 256; writeln (a, b, c, d); {результат 2538126256} writeln (a, b); writeln (c, d); {результат 2538 } {126256 } writeln (' a= ', a, ' b= ', b); {результат a=25 b=38} {символы в апострофах выводятся как строковая константа} write (a, b, c, d); {результат 2538126256} write (a, b); write (c, d); {результат 2538126256} write (' a= ', a, ' b= ', b); write (' c= ', c, ' d= ',d); {результат a=25 b=38 c=126 d=256 }
5. 4. Некоторые возможности ввода-вывода Оператор Readln; (без скобок, имени файла и списка ячеек памяти) вызовет остановку машины. Продолжение выполнения программы произойдет после нажатия кнопки Enter. Это очень удобно при просмотре каких-либо промежуточных результатов, например: writeln ('a= ', a); Readln; Машина выведет а=. . . и остановится, после нажатия кнопки Enter выполнение программы продолжится. Оператор writeln; вызовет переход к новой компоненте, в случае вывода на экран - к новой строке экрана. Рассмотрим фрагмент программы: Var i, k; integer; Begin i: = 126; k: = 1997; writeln ('i= ', i, ' k= ', k); {результат i=126 k=1997} writeln (i: 3, k: 6); {результат 126 1997} {числа, указанные после : определяют поле вывода, при выводе } {данное "прижимается" в поле к правому краю 1997} writeln (i: 7, k: 8); {результат ....126 ....1997} Пример: Program Prim23;Var r,pl:real;BEGIN writeln('введите радиус шара'); readln(r); pl:=4*pi*sqr(r);writeln('____________________________________________________');writeln('! площадь шара рад.r=',r:14,' = ',pl:14,'!');writeln('____________________________________________________'); readln; END. В результате на экран выведется информация: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! площадь шара радиусом R=хххххххххххххх = ххххххххххххххх ! - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - Здесь ххххххххххххх - изображения чисел. С помощью такого приема строятся различные таблицы. При выводе величины Real в операторах write и writeln отводится поле шириной 18 символов для вывода данных с "плавающей точкой" в следующем формате..х.ххххххххххЕ*хх; здесь х - цифры, * - знак, который может быть '+' или '-', '.' - десятичная точка, отделяющая целую часть от дробной. Перед целой частью, в случае отрицательного данного, может стоять знак минус. Таким образом: в памяти машины вид оператора результат R = 715.432 writeln (R); 7.1543200000E+02 R = -1.919e+01 writeln (R); -1.9190000000E+01 R = -567.986 writeln (R); -5.6798600000E+02 Напоминаем: Е+02 означает 102, а 7.1543200000Е+02 равносильно математической записи 7.15432102. Ширину поля вывода можно указывать для данных любого типа, например: в памяти машины вид оператора результат R = 511.04 writeln (R: 22); ......5.1104000000E+02 ch = 'x' writeln (ch: 3); ..x ch = '!' writeln (ch: 2, ch: 4,ch: 3); .!...!..! strin = 'Day N' writeln (strin: 8); ...Dau.N S = 'RDD' writeln (S: 5, S: 5); ..RDD..RDD Для данных типа Real можно еще указывать кроме ширины поля также количество цифр после десятичной точки. Вывод данных с "фиксированной точкой". в памяти машины вид оператора результат R = 511.04 writeln (R: 8: 4); 511.0400 R = -46.78 writeln (R: 7: 2); .-46.78 R = -46.78 writeln (R: 9: 4); .-46.7800 R = -46.78 writeln (R: 12: 3); .....-46.780 Program Prim24; Var r1,r2:real; BEGIN r1:=-46.78; r2:=-46.78; writeln('r1=',r1:12:3,' r2=',r2:9:4); writeln('_______________________________'); readln; END. 6. Массивы6. 1. Описание массивов В языке Паскаль можно обрабатывать не только отдельные переменные, но и их совокупности. Одной из таких совокупностей (структурированных) данных является массив. Массив - это упорядоченная совокупность данных, состоящих из фиксированного количества элементов одного и того же типа. Тип элементов, из которых состоит массив, может быть как скалярным, так и структурированным. Этот тип называется базовым, им может быть целый, байтовый, логический, символьный, перечисляемый, интервальный, вещественный, множественный типы и т. д. Массивы могут быть одномерные: вектор a1, a2, a3, a4, a5, ...an, т. е. линейка величин - - - - - - - - - - - - двумерные массивы представляют собой матрицы: a11 a12 . . . a1n , т. е. матрицу величин или прямоугольник величин a21 a22 . . . a2n ---- ---- ---- - - - - - - - - - - ---- ---- ---- am1 am2 . . . amn ---- ---- ---- Трехмерный массив - трехмерная матрица или параллелепипед величин, состоящий из набора двухмерных матриц (рис.6.1). Линейка трехмерных массивов составляет четырехмерный массив, матрица трехмерных массивов (параллелепипедов величин) - пятимерный массив и т. д. Количество размерностей не ограничено, однако следует помнить о том, что количество элементов в массиве растет в геометрической прогрессии от количества размерности. Описание массивов может быть, как и других величин, прямое или через описание типов Тype. Прямое описание Var - идентификатор, идентификатор, …, идентификатор: array - [границы индекса, границы индекса, …, границы индекса] of - базовый тип. Описание через TYPE: TYPE - имя типа=array [границы индекса, границы индекса, . . ., границы индекса] of базовый тип; Var - идентификатор, идентификатор, . . . , идентификатор: имя типа; Пример: описать двумерные массивы с количеством элементов 4 строки по 5 элементов в каждой строке (5 столбцов), базовый тип real, массивов три: а, b, c. Прямое описание: Var a, b, c: array [1. . . 4, 1 . . . 5] of real; через TYPE: TYPE mas=array [1. . . 4, 1. . . 5] of real; Var a, b, c : mas; Для указания границ массива можно применять предварительно описанные константы: Const a1=4; a2=6; Var mas y1: array [1. . . a1, 1. . . a2] of integer; Доступ к элементам массива производится через переменные с индексами. Индексы должны не выходить за пределы границ в описаниях массива. Например, описана ma: array [1. . . 12] of integer; выделено 12 ячеек памяти для хранения целых данных типа integer с именами ma [1], ma [2], ma [3], и т. д. , ma [12]. Пример: TYPE klass = ( K1, K2, K3, K4); znak = array [1. . . 255] of char; Var m1: znak; {описан массив с именем M1 типа znak для хранения данных} {типа char в количестве 255 шт. M1[1], M1[2], ... , M1[255]} M2: array [1...60] of integer {прямое описание, описан массив с именем} {M2 для хранения целых величин. всего } {ячеек 60.M2[1], ... , M2[60] } M3: array [1 ... 8] of klass; {описан массив М3, выделено 8 ячеек памяти М3[1], ... , M3[8],} {в каждой из которых могут храниться только величины из} {klass, т. е. туда могут быть занесены только K1, K2, K3, K4} Пример: Program Prim25; Var i:integer; s:real; a:array[1..10] of real; BEGIN for i:=1 to 10 do Begin writeln('введите значение величины a[',i,']'); readln(a[i]); end; { ввод элементов массива } s:=0; for i:=1 to 10 do s:=s+a[i]; { нахождение суммы элементов а [i] } writeln('s=',s); readln; END. Здесь мы проиллюстрировали работу с одномерным массивом. Конечно, данную программу легче представить в следующем виде: Program Prim25a; Var i:integer; s,a:real; BEGIN s:=0; for i:=1 to 10 do begin writeln('введите значение величины a[',i,']'); readln(a); { ввод по одному а (без массива)} { имитация ввода элементов массива } s:=s+a; writeln('s=',s); end; readln; END. Никаких массивов здесь не применять. На примере prim25 мы четко проследим два момента: занесение данных в массив (первый цикл) и обработка данных в массиве (второй цикл). Пример: дана квадратная матрица. Вывести на экран элементы ее главной диагонали (элементы главной диагонали перечеркнуты) a11 a12 a13 a14 a21 a22 a23 a24 a31 a32 a33 a34 a41 a42 a43 a44 Если принять, что индекс строк i, а столбцов j, то на главной диагонали лежат элементы, у которых i = j. Program Prim26; Var i,j,k:integer; a:array[1..4,1..4] of integer; b:array[1..4] of integer; BEGIN for i:=1 to 4 do for j:=1 to 4 do Begin writeln('введите a[',i,',',j,']'); readln(a[i,j]) end; {ввод элементов массива а закончен } k:=1; { устанавливаем индекс для занесения b[1] } for i:=1 to 4 do for j:=1 to 4 do if i=j then Begin b[k]:=a[i,j]; k:=k+1; end; {отыскиваем и заносим в b[1] a[1,1]} {меняем k и заносим в b[2] a[2,2] и т.д.} writeln('на главной диагонали лежат злементы:'); writeln('a[1,1]=',b[1],' a[2,2]=',b[2],' a[3,3]=',b[3],' a[4,4]=',b[4]); readln; END. В этой программе машина запросит ввод 16 элементов матрицы А, найдет элементы главной диагонали, занесет их в массив B и напечатает результат в следующем виде: на главной диагонали лежат элементы: A[1,1] = число A[2,2] = число A[3,3] = число A[4,4] = число Program Prim26a; Var i,j,k:integer; a:array[1..4,1..4] of integer; b:array[1..4] of integer; BEGIN for i:=1 to 4 do for j:=1 to 4 do Begin writeln('ввести a[',i,',',j,']'); readln(a[i,j]); end; { ввести массив а } { вывести элементы массива а } for i:=1 to 4 do Begin writeln; { перевести курсор на новую строку } for j:=1 to 4 do write(a[i,j],' '); { вывести элементы в одну строку } end; k:=1; for i:=1 to 4 do for j:=1 to 4 do if i=j then Begin b[k]:=a[i,j]; k:=k+1; end; {отыскиваем и заносим в b[1] a[1,1]} {меняем k и заносим в b[2] a[2,2] и т.д.} writeln(' на главной диагонали лежат элементы:'); writeln('a[1,1]=',b[1],' a[2,2]=',b[2],' a[3,3]=',b[3],' a[4,4]=',b[4]); readln; END. Эта программа отличается от предыдущей тем, что она вначале вводит массив А, затем его распечатывает в виде a11 a12 a13 a14 a21 a22 a23 a24 a31 a32 a33 a34 a41 a42 a43 a44 а после выводит результаты в том же виде, что и программа Prim26, т.е. Program Prim26b; Var i,j,k,n:integer; a:array[1..40,1..40] of integer; b:array[1..40] of integer; BEGIN writeln('введите размерность массива'); readln(n); for i:=1 to n do for j:=1 to n do Begin writeln('введите a[',i,',',j,']'); readln(a[i,j]); end; { вывести элементы массива а } for i:=1 to n do Begin writeln; {перевести курсор на новую строку} for j:=1 to n do write(a [i , j],' '); {вывести элементы в одну строку} end; k:=1; for i:=1 to n do for j:=1 to n do if i=j then Begin b[k]:=a[i , j]; k:=k+1; end; {отыскиваем и заносим в b[1] a[1,1]} {меняем k и заносим в b[2] a[2,2] и т.д.} writeln(' на главной диагонали лежат элементы:'); for k:=1 to n do write(' a[',k,',',k,']=',b[k]); readln; END. Эта программа работает так же, как и предыдущая, но с массивами и с переменными измерениями. Величина входного массива может быть до 40 строк и 40 столбцов. Чтобы это обеспечить, в разделе Var описываем массив a: array [1..40,1..40] of integer; а затем в программе вводим по запросу n, которое будет определять, с матрицей какой величины мы будем работать конкретно (n должно быть в диапазоне 1-40). Далее все циклы программы работают от 1 до n, т.е. машина решит задачу для массива введенной размерности n. Program Prim27; Var i,j,k,n:integer; a:array[1..40,1..40] of integer; b:array[1..40] of integer; BEGIN writeln('ввести n'); readln(n); for i:=1 to n do for j:=1 to n do Begin writeln('ввести a[',i,',',j,']'); readln(a[i,j]); end; { вывести элементы массива а } for i:=1 to n do Begin writeln; {перевести курсор на новую строку} for j:=1 to n do write(a[i,j],' '); {вывести элементы в одну строку} end; k:=1; for i:=1 to n do for j:=1 to n do if i+j-1=n then Begin b[k]:=a[i,j]; k:=k+1; end; {отыскиваем и заносим в b[1] a[1,1]} {меняем k и заносим в b[2] a[2,2] и т.д.} writeln; writeln(' на дополнительной диагонали лежат элементы:'); for k:=1 to n do write(b[k],' '); readln; END. Программа Prim 27 работает аналогично программе Prim 26b, однако выводит элементы, лежащие на дополнительной диагонали. Program Prim28; Var i,j,min,m,n,k:integer; a:array[1..20,1..10] of integer; b:array[1..10] of integer; BEGIN writeln('ввести m,n'); readln(m,n); for i:=1 to m do {m - количество строк } for j:=1 to n do {n - количество столбцов} Begin writeln('ввести a[', i ,', ', j,']'); readln(a[i , j]); end; { вывести элементы массива а } for i:=1 to m do Begin writeln; for j:=1 to n do write(a[i,j],' '); end; min:=32767; {максимальное integer, чтобы в последующем сравнивать} {и заносить в min все элементы a[i,j], которые меньше min} for i:=1 to m do for j:=1 to n do if a[i , j]<min then Begin min:=a[i , j]; k:=i; end; writeln(' строка, содержащая наименьший элемент'); for j:=1 to n do write(' a[', k ,',', j ,']=',a[k , j]); readln; END. Программа Prim 28 находит в массиве строку размером до 20х10, содержащую наименьший элемент. Program Prim29; Var i,j:integer; a:array[1..5, 1..7] of integer; b:array[1..7] of integer; c:array[1..5] of integer; BEGIN for i:=1 to 5 do for j:=1 to 7 do begin writeln('введите a[',i,',',j,'] элемент матрицы а'); readln(a[i,j]); end; for j:=1 to 7 do begin writeln('введите b[',j,'] элемент вектора b'); readln(b[j]); end; for i:=1 to 5 do {начало перемножения матрицы на вектор} begin c[i]:=0; for j:=1 to 7 do c[i]:=c[i]+ a[i,j]*b[j]; end; {конец перемножения матрицы на вектор} writeln('распечатка массива а'); for i:=1 to 5 do begin writeln; {начать новую строку} for j:=1 to 7 do write(' ',a[i,j]); end; writeln; writeln('распечатка массива b'); for j:=1 to 7 do write(' ',b[j]); writeln; writeln('результирующий массив с'); for i:=1 to 5 do write(' ',c[i]); readln; END. Программа вводит матрицу А размером 5х7 и вектор размером 7 элементов, затем их перемножает по правилу Сi = Сi + a[i,j]b[j] и выводит пять элементов массива С. Заметим, что для вычисления каждого с необходимо каждый элемент строки массива a умножить на соответствующий по индексу элемент массива b, а затем все эти произведения сложить. таким образом, количество элементов массива с будет равно количеству строк матрицы a (и, соответственно, количеству элементов массива b). Program Prim29a; Var i,j,n,m:integer; a:array[1..50,1..70] of integer; b:array[1..70] of integer; c:array[1..50] of integer; BEGIN writeln('ввести количество строк и столбцов'); readln(n,m); for i:=1 to n do for j:=1 to m do begin writeln('ввести a[',i,',',j,'] элемент матрицы а'); readln(a[i,j]); end; for j:=1 to m do begin writeln('ввести b[',j,'] элемент вектора b'); readln(b[j]); end; for i:=1 to n do {начало перемножения матрицы на вектор} begin c[i]:=0;
Страницы: 1, 2, 3, 4, 5, 6, 7
|