Основы программирования на языке Паскаль
Программирование на языке Паскаль: алфавит, решение задач, простейшие программы, разветвляющие программы, циклические программы, ввод-вывод, массивы, подпрограммы, строковые данные, записи, файлы, использование библиотеки CRT, графика в Паскале.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | учебное пособие |
Язык | русский |
Дата добавления | 30.03.2008 |
Размер файла | 211,1 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
spring: writeln('spring');
summer: writeln('summer');
autumn: writeln('autumn');
end; readln;
END.
4. Циклические программы
Наиболее часто в практике программирования встречаются циклические программы. В циклических программах какой-либо алгоритм повторяется многократно, при этом один из параметров изменяется. Например, описанная в п. 3.3 программа Рrim 4 является классическим примером циклического алгоритма. Операторов цикла в Паскале три: for, repeat, while.
4.1. Оператор for
Оператор состоит из заголовка, в котором определяется порядок изменения переменной параметра цикла и тела цикла, являющегося многократно повторяющимся алгоритмом. Общий вид оператора:
for - параметр цикла: = начальное значение to, конечное значение do {заголовок}; оператор; {тело цикла}. Этот оператор применяется, если начальное значение < конечного значения;
for - параметр цикла:=начальное значение downto, конечное значение do; оператор; применяется, если начальное значение > конечного значения.
Пример: найти сумму квадратов целых чисел от 8 до 1.24.
Program Prim12; Var i,s:integer; BEGIN s:=0; for i:= 8 to 124 do s:=s+sqr(i); writeln('s=',s); readln;
END.
Работа программы. В разделе Var выделяется ячейка памяти с именем i и s для хранения величин. Поскольку в S мы должны накапливать сумму, то вначале занесем в S ноль. Затем заголовок цикла присваивает i=8. далее выполняется тело цикла: извлекается содержимое ячейки S (а там у нас 0) и к этому содержимому прибавляется sgr(i), т.е. i2=82. Результат присваивается ячейке S, т.е. в S теперь 82.
Проверяется, не стал ли параметр цикла больше конечного значения параметра 128. Это не произошло, поэтому i присваивается следующее значение равное 9 и вновь выполняется тело цикла, т.е. S:=82+92. Можно сказать так: S присвоить тому S, которое было раньше, + следующее i2. Так как цикл еще не закончился, то i станет равным 10, а S присвоится тому S, которое было раньше, т.е. 82+92, и к нему прибавится еще текущее i2, т.е. 102. Этот процесс повторяется до тех пор, пока параметр цикла не станет равным 124. Тогда в последний раз 1242 прибавляется к накапливаемой сумме.
Итак: выполнение цикла значения i значения S
1 8 82
2 9 82+92
3 10 82+92+102
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
116 117 82+92+102+…+1232
117 124 82+92+102+…+1232 +1242
При i=125 происходит выход из цикла и переход к оператору writeln ('S=' ,S);
Эта, казалось бы, правильно написанная программа дает результат S=-12250. Как может получиться отрицательный результат при суммировании квадратов - заведомо положительных чисел? Такой результат мы получаем путем суммирования и занесения результатов в ячейку S типа integer, а в integer могут быть помещены числа в диапазоне -32768 +32767, поэтому после переполнения ячейки памяти в знаковый разряд переносится 1, которая интерпретируется машиной как '-'. Чтобы этого избежать, можно описать S как longint. Тогда результат работы программы будет правильный и равен 643110.
Program Prim12a; Var i,s:longint;
BEGIN s:=0;
for i:= 8 to 124 do
s:=s+sqr(i);
writeln('s=',s);
readln; END.
Можно также описать S как real. Program Prim12b; Var i:integer; s:real;
BEGIN s:=0;
for i:= 8 to 124 do
s:=s+sqr(i);
writeln('s=',s);
readln;
END.
Результат работы этой программы будет равен 6.4311000000E+05, что то же самое, что и 643110, если считать, что запись 6.4311000000E+05 равносильна математической записи 6,431110+5.
Правила применения оператора цикла for
1.Тело цикла - всегда один оператор. Если нужно, чтобы тело цикла состояло из нескольких операторов, то их объединяют в один с помощью операторных скобок begin, end.
for i:=l to n do
Begin S:=S+sin(x)/cos(x);
x=x+0.01;
writeln('S=' ,S)
end.
Операторы, взятые в операторные скобки begin, end, считаются одним составным оператором.
2. Начальное и конечное значения параметра цикла в общем случае являются выражениями. Тип этих выражений и тип параметра цикла должны совпадать. Здесь допускается применение любых типов, которые упорядочены с каким-либо фиксированным шагом, это может быть любой скалярный тип, кроме вещественного, т.е. байтовый, целый, символьный, перечисляемый, интервальный, булевский. на практике чаще всего применяют целочисленный тип.
3. В теле цикла параметр цикла не должен изменяться.
4. Нельзя с помощью оператора перехода goto войти в тело цикла, минуя заголовок.
5. Выйти из тела цикла в программу можно по if..goto, не дожидаясь полного перебора параметров цикла.
Пример: написать программу, выводящую буквы латинского алфавита в одну сторону, с пробелом между ними.
Применяем здесь в качестве параметра цикла символьную переменную, в качестве начального значения параметра - константу 'A', конечного - 'Z'.
Program Prim13;
Var
i:char;
BEGIN
for i:='a' to 'z' do
write(' ',i);
readln; END.
Пример: вычислить значение определенного интеграла на участке a,b для функции cos х, т.е. определить площадь, заштрихованную на рис. 4.1.
Применим метод трапеций, суть которого заключается в том, что область делится на ряд трапеций, площади которых вычисляются и суммируются. Чем на большее количество трапеций мы разделим область, тем точнее получим результат (см.рис.4.2).
Program Prim14;
Var i,n:integer; a,b,x,h,s:real;
BEGIN writeln(' введите к-во точек разбиения n и величины а, b');
readln(n,a,b);
h:=(b-a)/n; s:=0; x:=a;
for i:=1 to n do
Begin s:=s+(abs(cos(x))+abs(cos(x+h)))/2*h;
x:=x+h; end;
writeln('s=',s);
readln; END.
Замечание: при вычислении S (так как функция пересекает ось OX) часть площадей может иметь отрицательное значение, поэтому мы берем abs(f(x)).
Усложним задачу: пусть нужно найти площадь криволинейной трапеции (интеграл), где функция от точки а до b sin(x), а после b до с cos(x).
Program Prim15;
Var i,n:integer; a,b,c,x,h,s,fxpred,fxposl:real;
BEGIN writeln('введите к-во точек разбиения n и величины а, b, c');
readln(n,a,b,c);
h:=(c-a)/n; s:=0; x:=a;
for i:=1 to n do
Begin
{ определимся, по какой из функций считать стороны трапеций }
if (x>=a) and (x<=b) then fxpred:= abs(sin(x)) else
fxpred:=abs(cos(x));
if (x+h>=a) and (x+h<=b) then fxposl:= abs(sin(x+h)) else
fxposl:=abs(cos(x+h));
s:=s+(fxpred+fxposl)/2*h;
x:=x+h; end;
writeln('s=',s);
readln; END.
В последних двух программах мы заменяем площадь криволинейной трапеции (интеграл) суммой трапеций. При этом нам неизвестно, какую ошибку мы допустим; знаем, что чем больше точек разбиения, тем точнее будет результат. Поставим задачу: совершенно точно знать, что мы посчитаем интеграл с точностью не менее заданной, например, что разность между площадью криволинейной трапеции и суммой прямоугольных трапеций будет не больше Е = 0.01. Для этого нам нужно посчитать результат для количества точек, например 10, затем - 100. Сравнить величины площадей, и, если их разность будет меньше Е, то можно с уверенностью сказать, что площадь для разбиения на 100 интервалов будет найдена с точностью не менее Е. Если разность между расчетами на 10 и 100 интервалов больше Е, то следует разбить область интегрирования на 1000 интервалов и сравнить сумму для 100 интервалов с суммой для 1000 интервалов, и если их разница будет меньше Е, то за результат принять площадь, посчитанную для 1000 разбиений и т.д. рано или поздно мы получим искомый результат. Сравнения сумм площадей трапеций будем производить с помощью оператора if.
Пусть функция будет cos(x). Напишем программу:
Program Prim16;
Label NAH,KON;
Var i,n:integer; a,b,x,h,spred,spos,e:real;
BEGIN writeln('введите точность е и границы a, b');
readln(e,a,b); spred:=9.9e+10; h:=0; n:=10;
NAH: spos:=0; h:=(b-a)/n; x:=a;
for i:=1 to n do
Begin spos:=spos+(abs(cos(x))+abs(cos(x+h)))/2*h;
x:=x+h; end;
if abs(spos-spred)<=e then Begin
writeln('s=',spos,' n=',n); goto KON; end
else spred:=spos; n:=n*10; x:=a; goto nah;
KON: readln; END.
Работа программы: for i: = i to n do, в первый раз оператор
Spоs: = spos+(abs(cos(x))+abs(cos(x+h)))/2h
посчитает значение интеграла для 10 точек разбиения. Затем if сравнит полученное значение spos с 9.9Е+10. Конечно, разница между этими величинами не будет меньше е, тогда мы забудем число 9.9Е+10, так как присвоим spred: = spоs, чтобы при следующем выполнении if сравнивать предыдущее и последующее значения интеграла. После этого увеличим количество точек разбиения n: = n10 и вернемся на начало вычисления spos, т.е. интеграла для 100 интервалов goto nach. После нового вычисления spos сравним 100 интервалов для 10 интервалов spred. Если разность между ними не меньше Е, то забудем значение s для 10 интервалов и занесем в spred значение для 100 интервалов. Затем вычислим значение интеграла для разбиения 1000 и результат занесем в spos, сравним spred и spos и т.д.
4.2. Оператор repeat. Общий вид
В отличие от for, оператор repeat (а также while) применяют тогда, когда неизвестно точно, сколько раз будет выполняться тело цикла. Общий вид оператора
repeat
оператор;
оператор;
- - - - - - - -
оператор until булевское выражение;
Работа оператора. Сначала выполняются операторы, составляющие тело цикла, затем выполняется булевское выражение, и если оно ложно, вновь выполняется тело цикла. Выход из цикла происходит, когда булевское выражение станет истинным.
Явного перебора параметров в repeat не предусмотрено, поэтому изменение параметров осуществляется в теле цикла. Здесь же мы должны позаботиться , чтобы рано или поздно булевское выражение стало истиной.
Замечания: 1.Тело оператора repeat выполняется по меньшей мере один раз. Оператор repeat еще называют циклом с послеусловием.
2. Перед until ';' не ставится.
Пример: найти сумму четных чисел в интервале от 0 до 100.
Program Prim17;
Var i,s:integer;
BEGIN i:=0; s:=0;
repeat
i:=i+2; s:=s+i
until i>100;
writeln('s=',s);
readln; END.
Пример: найти ток в цепи переменного тока в зависимости от частоты тока. Известно, что при последовательном соединении активной, емкостной и индукционной нагрузок сила тока может быть вычислена по формуле
Пусть U = 220, R = 100, L = 0.57, С = 3.210-3, Fначальное=10; F будем менять с шагом 0.5. Печатать все результаты. Результаты, когда i3, нас не интересуют.
Program Prim18;
Var i,r,f,l,c,u:real;
BEGIN writeln(' введите значения u r l c');
readln(u,r,l,c);
f:=50;
repeat i:=u/sqrt(sqr(r)+sqr(2*pi*f*l-1/(2*pi*f*c)));
f:=f-1;
writeln('f=',f,' i=',i)
until i>3;
readln; END.
4.3. Оператор While
Оператор While цикла с предусловием.
While - булевское выражение; do - тело цикла.
Работа оператора. Вначале вычисляется булевское выражение, и если оно истинно, то выполняется тело цикла; если оно ложно, то происходит выход из цикла.
Тело цикла - один оператор, как правило, составной. Мы должны позаботиться о том, чтобы булевское выражение в теле цикла на каком-то этапе стало ложным, иначе цикл никогда не закончится. Цикл можно сделать умышленно бесконечным, написав: while true do оператор;
Мы будем применять эту конфигурацию при написании программ обработки файлов.
Пример: найти сумму четных чисел в интервале от 0 до 100.
Program Prim19;
Var i,s:integer;
BEGIN i:=0; s:=0;
while i<100 do
Begin i:=i+2; s:=s+i; end;
writeln('s=',s);
readln; END.
Пример: в цепи переменного тока найти ток в зависимости от его частоты.
Program Prim20;
Var i,r,f,l,c,u:real;
BEGIN writeln('введите значения u,r,l,c');
readln(u,r,l,c);
f:=50;
while i<3 do
Begin i:=u/sqrt(sqr(r)+sqr(2*pi*f*l-1/(2*pi*f*c)));
f:=f-1;
writeln('f=',f,' i=',i); end;
writeln('i>3, i=',i);
readln; END.
4.4. Вложенные циклы
Поскольку тело любого цикла состоит из операторов или составного оператора, то ничто не помешает в теле цикла располагать другие операторы цикла. Рассмотрим работу программы:
Program Prim21;
Var
i,j:integer;
BEGIN
for i:=1 to 5 do
Begin writeln;
for j:=20 to 23 do
write('i=',i,' j=',j);
end;
readln; END.
Для цикла for i:=1 to 5 do телом цикла является
begin for j:=20 to 23 do
write(' i= ', i, ' , j = ', j);
writeln;
end;
Назовем этот цикл внешним. Кроме того, имеется внутренний цикл
for j: = 20 to 23 do с телом write (' i = ', i , j =', j);
Работа программы. Вначале машина встречает внешний цикл и начинает его выполнять: присваивает i=l, затем переходит к его телу, а здесь встречает внутренний цикл и присваивает j значение 20, после чего выполняет тело внутреннего цикла, т.е. выводит на экран i=l, j=20. Так как внутренний цикл еще не окончен, то машина продолжает его выполнять, т.е. присваивает j значение 21 и добавляет к уже выведенной строке i=l, j=21.
Заметим, что оператор 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,'] элемент матрицы а');
Подобные документы
Международный стандарт на язык программирования Паскаль. Приемы объектно-ориентированного программирования в Турбо Паскале. Символы языка, его алфавит. Этапы разработки программы. Понятие алгоритмов и алгоритмизации. Структура программ на Паскале.
курсовая работа [29,8 K], добавлен 28.02.2010Создание транслятора, обрабатывающего код программы на языке Паскаль и за счет эквивалентных операторов генерирующего программу на Си. Особенности внешней спецификации и работы лексического анализатора. Структура программы, вывод результатов на экран.
курсовая работа [254,0 K], добавлен 02.07.2011Особенности программирования на языке Паскаль в среде Турбо Паскаль. Линейные алгоритмы, процедуры и функции. Структура данных: массивы, строки, записи. Модульное программирование, прямая и косвенная рекурсия. Бинарный поиск, организация списков.
отчет по практике [913,8 K], добавлен 21.07.2012Язык программирования Турбо Паскаль. Запись алгоритма на языке программирования и отладка программы. Правила записи арифметических выражений. Стандартное расширение имени файла, созданного системным редактором. Составной оператор и вложенные условия.
курсовая работа [75,0 K], добавлен 21.03.2013Изучение основных конструкций и способов написания программ на языке Паскаль. Обзор принципов работы и интерфейса написанной программы. Обработка и модификация двумерных массивов. Файловые структуры данных. Текстовые файлы. Элементы машинной графики.
курсовая работа [761,7 K], добавлен 11.03.2015Выбор метода проектирования транслятора с языка Паскаль на язык Си, разработка и кодирование алгоритма программы. Использование допустимых операторов в исходном тексте, определение типов переменных и синтаксиса логических и арифметических выражений.
курсовая работа [1,0 M], добавлен 03.07.2011Освоение технологии структурного программирования и применения стандартных методов работы с одномерными массивами при разработке и создании программы на языке Турбо Паскаль. Разработка программы методом пошаговой детализации с помощью псевдокода.
реферат [276,9 K], добавлен 27.02.2008Алгоритмы, алфавит языка, структура программы, написанной на Турбо Паскале. Целые, вещественные, логические, символьные типы данных, их совместимость. Линейные алгоритмы, пустой и составной операторы, простейший ввод и вывод, разветвляющиеся алгоритмы.
курсовая работа [49,8 K], добавлен 03.11.2009Сравнительный анализ языков программирования высокого уровня Си и Паскаль. Реализация алгоритма обработки данных. Тестирование и отладка программы или пакета программ. Структура программы на языке Турбо Паскаль. Указатели и векторные типы данных.
курсовая работа [233,5 K], добавлен 14.12.2012Схема разбора арифметического и логического выражения. Внешняя спецификация конвертора и алгоритм перевода программ на языке Паскаль в текст на языке Си. Назначение подпрограмм, особенности констант и переменных. Код программы и ее тестирование.
курсовая работа [567,5 K], добавлен 03.07.2011