Структура программы. Описание типов данных. Любая программа,все равно на каком языке программирования, состоит из 2-х частей

Вид материалаПрограмма

Содержание


Операции отношения
Сравнение простых типов
Сравнение строк
Сравнение множеств
Проверка на принадлежность к множеству
Операторы перехода
Структурные операторы
Составные операторы
Условные операторы
If условие then
Оператор варианта (case)
Var operator:(plus,minus,times)
Операторы цикла
Операторы цикла с параметром (for)
For i:=нач.значение to/downto конечное значение do
Оператор with
Uses WinCrt
Summa ( vector,n)
Обращение к функции несколько иное
Подобный материал:
1   2   3   4   5

Операции отношения

Типы операндов и результаты операций отношения приведены ниже:


= равно >= больше или равно in принадлежность

<> не равно <= меньше или равно множеству

Сравнение простых типов

Когда операции =, <>, <, >, >= или <= применяются для операндов простых типов, то это должны быть совместимые типы. Однако, если один операнд имеет вещественный тип, то другой может быть целого типа.


Сравнение строк

Операции отношения =, <>, <, >, >= или <= могут применятся для сравнения строк согласно порядку расширенного набора символов кода ASСII. Любые два значения строковых данных можно сравнить, поскольку все значения строковых данных совместимы.


Сравнение множеств

Если операндами являются множества a и b, то при их сравнении получаются следующие результаты:

1. Выражение a=b истинно (= True) только когда a и b содержат одни и те же элементы, в противном случае a<>b.

2. Выражение a = b истинно, когда каждый элемент множества a является также элементом множества b.

3. Выражение a = b истинно, когда каждый элемент множества b является также элементом множества a.


Проверка на принадлежность к множеству

Операция in возвращает истинное значение (True), когда значение элемента перечислимого типа является элементом операнда множественного типа, в противном случае он возвращает значение False.

Для приведенного выше примера ‘пон’ in den2 равно false.


Лекция 3


Операторы

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


Простые операторы

Простым оператором является такой оператор, который не содержит в себе других операторов.


Оператор присваивания

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

Приведем некоторые примеры операторов присваивания:

X := Y + Z

Done := (I>=1) and (I<100);


Операторы перехода

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


gоtо метка


При использовании оператора перехода должны соблюдаться следующие правила:

1. Метка, которая указывается в операторе перехода, должна находиться в том же блоке или модуле, что и сам оператор перехода. Другими словами, не допускаются переходы из процедуры или функции или внутрь нее.

2. Переход извне внутрь структурного оператора (то есть переход на более глубокий уровень вложенности) может вызвать непредсказуемые эффекты, хотя компилятор не выдает сообщения об ошибке.

3.Метка должна быть описана ключевым словом label.


Структурные операторы

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


Составные операторы

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


begin

операторы

end ;


Приведем пример составного оператора:

begin

Z := X;

X := Y;

Y := Z; end;

Условные операторы

Условные операторы позволяют выбрать для выполнения один из составных операторов (или не выбрать ни одного).В Паскале имеет место 2 оператора:


If условие then else ….. ; оператор условия

Case переключатель of ………else…..end; оператор выбора.


Оператор if

Синтаксис оператора if можно представить следующим образом:

If условие then

Операторы

Else

Операторы

End;

В условии должен получаться результат, имеющий стандартный булевский тип. Если результатом выражения является истинное значение (True), то выполняется оператор, следующий за ключевым словом then.

Если результатом условия является значение False и присутствует ключевое слово else, то выполнятся оператор, следующий за ключевым словом else. Если ключевое слово else отсутствует, то никакой оператор не выполняется.

Синтаксическая неоднозначность, возникающая в конструкции:

if e1 then e2 else e3;

разрешается путем следующей интерпретации этой конструкции:

if e1 then

begin

if e2 then

s1

else

s2

end;


В общем случае ключевое слово else связывается с ближайшим ключевым словом if. Перед else точка с запятой (;) некогда не ставится.

Приведем пример оператора if:

if X < 1.5 then

Z := X+Y else

Z := 1.5;

Оператор варианта (case)

Оператор варианта (casе) состоит из выражения (переключателя) и списка операторов, каждому из которых предшествует одна или более констант (они называются константами выбора) или ключевое слово else. Переключатель (селектор) должен иметь перечислимый тип (размером в байт или слово), и перечислимые значения верхней и нижней границы этого типа должны лежать в диапазоне от -32768 до 32767. Таким образом, строковый тип и длинный целый тип являются недопустимыми типами переключателя. Все константы выбора дожны быть уникальными и иметь перечислимый тип, совместимый с типом переключателя.

case константа выбора of

выбор:операторы

выбор:операторы

else

операторы

end;

Оператор варианта case приводит к выполнению оператора, которому предшествует константа выбора, равная значению переключателя или диапазону выбора, в котором находится значение переключателя. Если такой константы выбора или такого диапазона выбора не существует и присутствует ветвь else, то выполнятся оператор, следующий за ключевым словом else. Если же ветвь else отсутствует, то никакой оператор не выполняется.

Приведем некоторые примеры оператора варианта:


Var operator:(plus,minus,times);

I:1..100;

…………………………

case Operator of

plus: X := X+Y;

minus: X := X-Y;

times: X := X*Y;

end;

case I of

0, 2, 4, 6, 8: Writeln('Четная цифра');

1, 3, 5, 7, 9: Writeln('Нечетная цифра');

10..100: Writeln('Между 10 и 100'); end;


Операторы цикла

Оператор цикла задает повторное выполнение определенных операторов.

Если число повторений заранее известно, то подходящей конструкций является оператор for. В противном случае следует использовать операторы while или repeat.


Оператор цикла с постусловием (repeat)

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

Результатом выражения должен быть результат булевского типа. Операторы, заключенные между ключевыми словами repeat и until, выполняются последовательно до тех пор, пока результат выражения не примет значение True. Последовательность операторов выполнится по крайней мере один раз, поскольку вычисление выражения производится после каждого выполнения последовательности операторов.

Приведем примеры оператора цикла с постусловием:

repeat

K := I mod J;

I := J;

J := K;

until J = 0;

repeat

Write('Введите значение (0..9):');

Readln(I);

until (I >= 0) and (I <= 9);

Операторы цикла с предусловием (while)

Оператор цикла с предусловием (начинающийся с ключевого слова while) содержит в себе выражение, которое управляет повторным выполнением оператора (который может быть составным оператором).

Выражение, с помощью которого осуществляется управление повторением оператора, должно иметь булевский тип. Вычисление его производится до того, как внутренний оператор будет выполнен. Внутренний оператор выполнятся повторно до тех пор, пока выражение принимает значение Тruе. Если выражение с самого начала принимает значение False, то оператор, содержащийся внутри оператора цикла с предусловием, не выполняется.

Примерами операторов цикла с предусловием могут служить следующие операторы:

while Data[I] <> X do I := I + 1;

While I > 0 do begin

if Odd(I) then Z := Z * X; I := I div 2;

X := Sqr(X); end;


Операторы цикла с параметром (for)

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


For i:=нач.значение to/downto конечное значение do

исп операторы ;

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

Когда начинает выполняться оператор for, начальное и конечное значения определяются один раз, и эти значения сохраняются на протяжении всего выполнения оператора for.

Оператор, который содержится в теле оператора for, выполняется один раз для каждого значения в диапазоне между начальным и конечным значением. Управляющая переменная всегда инициализируется начальным значением. Когда работает оператор for, значение управляющей переменной (счетчика циклов) увеличивается при каждом повторении на единицу. Если начальное значение превышает конечное значение, то содержащийся в теле оператора for оператор не выполнятся. Когда в операторе цикла используется ключевое слово downto, значение управляющей переменной уменьшается при каждом повторении на единицу. Если начальное значение в таком операторе меньше, чем конечное значение, то содержащийся в теле оператора цикла оператор не выполняется.

Если оператор, содержащийся в теле оператора for, изменяет значение управляющей переменной, то это является ошибкой. После выполнения оператора for значение управляющей переменной становится неопределенным, если только выполнение оператора for не было прервано с помощью оператора перехода (например процедурами break, continue, exit).

Break ---- прервать выполнение цикла и продолжить исполнение

следующих операторов прграммы

Continue продожать циклы с переходом на следующий

Exit покинуть циклы и уйти из программы

Приведем примеры оператора цикла с параметром:

for I := 2 to 63 do

if Data[I] > Max then Max := Data[I];

-----------------

for I := 1 to 10 do

for J := 1 to 10 do

begin

X := 0;

for K := 1 to 10 do

X := X + Mat1[I,K]*Mat2[K,J];

Mat[I,J] := X;

end;

for i:=1 to 100 do

begin

if i=15 then break;end;

В последнем примере цикл на деле завершается при достижении 15.


Оператор with

В операциях над записями ( тип record) оператор with удобно использовать для краткого обращения к полям записи. В операторе with к полям одной или более конкретных переменных типа запись можно обращаться, используя только идентификаторы полей. Оперaтор with имеет следующий синтаксис:

Приведем пример оператора with:

with Date do

if month = 12 then

begin

month := 1;

year := year + 1

end else

month := month + 1;

Это эквивалентно следующему:

if Date.month = 12 then

begin

Date.month := 1;

Date.year := Date.year + 1 end

else

Date.month := Date.month + 1;

end;

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

Допустим описаны следующие переменные:

type

Point = record

x,y: integer;

end;

var

x: Point;

y: Integer;

В этом случае и к x, и к y можно обращаться, как к переменной или как к полю записи. В операторе:

with x do

begin

x := 10;

y := 25;

end;

x между ключевыми словами with и dо относится к переменной типа указатель, а в составном операторе x и y ссылаются на x.x и y.y.


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


1.Найти корни квадратного уравнения ах2+вх+с=0


program radex;

{ax2+bx+c=0}

uses

WinCrt; { Разрешает использовать Writeln, Readln, cursor movement, etc. }

label lend; {метка выхода из программы}


var

a,b,c:real; {коэффициенты уравнений}

x1,x2:real; {корни уравнений}

p,q,d:real; {дискриминант d=b*b-4*a*c ,p=b/a,q=c/a)}

i,n:integer;

begin

Writeln('привет - решаем квадратное уравнение!');

Writeln('сколько раз будем решать уравнение - введите целое число циклов');

readln(n);

for i:=1 to n do

begin

Writeln('введите вещественные значения ');

writeln('для коэффициентов а,в,с - коэффициенты вводятся через пробел');

readln(a,b,c); (** ввод с дисплея *)

if (a=0) and (b=0) then {проверяем на 0 коэффициеты}

begin {число операторов больше 1-го}

{поэтому применяем составной оператор begin....end;}

writeln('нет корней или корень любое значение');

goto lend; {уходим из программы}

end; {здесь ; - конец оператора if...end;}

if (a=0) and (b<>0) then

begin {условие для а=0 и b#0}

x1:=-c/a;

writeln('единственный корень х1=',x1:5:2);

goto lend;

end;

d:=b*b-4*a*c; {дискриминант }

p:=b/a; q:=c/a; {приводим к стандартному виду}

if d>=0 then {проверяем на положительность дискриминант}

begin {составной оператор -- начало}

x1:=-p/2+sqrt((p/2)*p/2-q); {1-ый корень х1}

x2:=-p/2-sqrt((p/2)*p/2-q); {2-ой корень х2}

writeln('дискриминант d=',d:5:2);

writeln('1-ый корень х1=',x1:5:2); {выводим корни на диспдей}

writeln('2-ый корень х2=',x2:5:2);

goto lend;

end {сoставной оператор --- конец}

else {if ... then еще не закончился! ; не ставится!!} {проверяем на минус}

begin

x1:=sqrt(q-(p/2)*(p/2));

writeln('корни мнимые');

writeln('дискриминант d=',d:5:2);

writeln('1-ый корень х1=',(-p/2):5:2,'+i*',x1:5:2);

writeln('2-ый корень х2=',(-p/2):5:2,'-i*',x1:5:2);

end; {составной оператор -- конец и ; для закрытия оператора if}

lend: end; {конец счетчика повторений для нахождения корней}

writeln('программа закончила работу! Нажмите любую клавишу');

readkey; {readkey; применяется для останова программы}

end.


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

program RIM;

uses

WinCrt; { Allows Writeln, Readln, cursor movement, etc. }

var

f,h,s:integer;

n:0..3999;

k:(M,CM,D,CD,C,XC,L,XL,X,IX,V,IV,I);

begin

writeln('введите число обращеинй: ');readln(f);writeln;

for h:=1 to f do

begin

writeln(' ');

writeln('обращение ',h);

writeln;

Writeln('введите исходное арабское число');

readln(n);

writeln; (** ввод данного *)

Write('результат: ');

for k:=M to I do

begin

case k of

M:s:=1000;CM:s:=900;D:s:=500;

CD:s:=400;C:s:=100;XC:s:= 90;

L:s:= 50;XL:s:= 40;X:s:= 10;

IX:s:=9;V:s:=5;IV:s:=4;

I:s:=1;

end;

while n-s>=0 do

begin

n:=n-s;

case k of

M:write('M');CM:write('CM');D:write('D');

CD:write('CD');C:write('C');XC:write('XL');

L:write('L');XL:write('XL');X:write('X');

IX:write('IX');V:write('V');IV:write('IV');

I:write('I');

end;

end;

end;

end;

end.


Лекция 4.


Процедуры и функции.


В процессе разработки больших программ неизбежно возникает проблема разбиения программы на отдельные независимые подпрограммы.Такое деление позволяет программировать одну большую программу многими программистами в отдельности с последующей сборкой всей программы через единый модуль,называемый головным. Для этого используются независимые подпрограммые единицы называемые в языке Паскаль модулями, процедурами и функциями. Паскаль допускает эапись процедур и функций в отдельные библитечные модули с приращением имя_библиотеки,DLL. При формировании головных программ необходимы приемы вызова и обращения к различным функцим и подпрограммам. Отдельные подпрограммы могут находится как в самих программах, так и на внешних носителя (диски, дискеты, лазерные диски и.т.д.).

Структура программы выглядит при наличии процедур, функций и модуле выглядит так:

Program MyProg;

Uses (* Список модулей через запятую *)

WinCrt, WinType, WinProg, MyModule;

(* Глобальные переменные, используемые процедурами и функциями *)

Procedure Имя_Процедуры1 (параметры:тип…);

(*……..описание локальных констант, переменных, меток …*)

Begin

…..операторы..

End;

Function Имя_Функции (параметры:тип):тип;

(* Описание переменных,констант,меток…*)

Begin

(* операторы *)

End;

Begin {Головной модуль}

(* операторы*)

End.


Процедуры.


В общем случае обращение к процедуре записывается так:

Procedure имя_процедуры (параметры); [external | forward ].

External – указывает на обращение к откомпилированному коду процедуры, который записан на внешний носитель как объектный файл, т.е. в виде

Имя_процедуры.OBJ.

Такие файлы получаются при использовании на панеле Турбо-Паскаль команду меню Run-Compile.

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

В качестве параметров используется список формальных параметров, составленный как объявление переменных. Они могут быть 3-х типов:
  • 1.параметры-значения,
  • 2.параметры-переменные,
  • 3.нетипизированные параметры.


1.Параметры – значения используются так:


Procedure Myname( x : integer; a,b,y : real);


Приведем пример такой процедуры с обращением из головной программы:

Program Psumma;

Uses WinCrt;

Const n=20;

Type

Tvector = array[1..n] of real;

Var

Vector : tvector;

I : integer;

{исходная процедура пишется всегда в разделе описаний}

Procedure Summa(vec: tvector;len : integer);

Var i:integer; s : real;

Begin

s:=0;

For i:=1 to len do

s:=s+vec[i];

end;

{конец раздела описаний}

Begin {Головной модуль}

randomize;

for i:=1 to n do vector[i]:=random(25);

{обращение к процедуре}

Summa ( vector,n);

Writeln(‘сумма векторных значений ’,s:7:2);

End.


2.Параметры-переменные используют ключевое слово Var:


Procedure HerName (var a,b:real; var c: pchar; z:extended);


Здесь, в случае a,b,c – компилятор рассматривает параметр как адрес переменной укаэанного типа, т.е. формальный параметр. Так как передается не значение, а его адрес появляется возможность изменения значения оригинала передаваемой таким образом переменной.

Приведем пример:

Program scalar;

Uses WinCrt;

Var a,b,c:real;

Procedure quadrat(var x,y,z:real);

Begin

Z:=sqrt(x*x+y*y);

End;

Begin {Головной модуль}

A:=1.0; b:=2.0;

Quadat(a,b,c);

Writeln(‘квадратный корень из суммы квадратов= ’,c:5:2);

End.

3.Нетипизированные параметры используют var без указания типа:


Procedure UsName (var myarray; var abc);


В этом случае для получения передаваемых значений применяется сaмостоятельное преобразование типов.




В процедуре или функции у нетипизованного параметра-переменной тип

отсутствует, то есть он несовместим с переменными всех типов, пока ему не

будет присвоен определенный тип с помощью присваивания типа переменной.


Для примера приведем следующую процедуру с бестиповым параметром

Program stat {подсчет среднего для массива 100 чисел}

uses WinCrt;

type ll=array[1..100] of real;

mm=array[1..100] of real;

var

ss:ll;

vec:mm;

s:real;

j:integer;

procedure myname(var sss);

var i:integer;

begin

randomize;

for i:=1 to 100 do

mm(sss)[i]:=random(50)/3; {уточняем тип параметра sss }

end;

begin

myname(vec); { обращение к внутренней процедуре myname}

for j:=1 to 100 do

s:=s+vec[j];

s:=s/100;

writeln(‘среднее ‘,s:3:2);

end.


Здесь внутренняя процедура myname заносит в массив случайное значение в интервале 0..50. Головная программа после обращения к внутренней процедуре, которaя заполняет массив vec подсчитывает среднее s.


функция.

Функция записывается так:


Function(параметры:тип):тип;


В функции работают все раннее перечисленные приемы передачи параметров для процедуры. Обращение к функции несколько иное. Если внимательно посмотреть на запись, то заметно различие в написании: функция имеет тип. Коль скоро она типизирована, то она действует как готовое значение и пишется всегда, в отличие от процедуры, только в правой части. Например, стандартная функция Пакаля извлечения корня sqrt(x) тип real и применяется в программе так:

Z:=sqrt(x);

Итак,функция своим результатом имеет конкретное значение с конкретным типом (число целое или вещественное, строка символов).


Приведем небольшой пример:

Program Mysting;

Var a:string;

Function addstring(var s:string):string;

S:=s+’Турбо-Паскаль’;

End;

Begin {Головной модуль}

A:=’привет’;

A:=a+addstring(a);

Writeln(a);

End;


Область видимости.

Областью видимости идентификатора называтся часть программы, где он может быть использован. Коль скоро идентификаторы используются и в проедурах (функциях) и в головной программе, то естетвенно раздельная их интепретация. Так, идентификаторы, объявленные в начале описания головной программы, определяются как глобальные, если объявленные идентификаторы используются подпрограммами (процедурами и функциями). Идентификаторы, заявленные в процедурах или функциях, определяются как локальные. Применяемые термииы: локальный и глобальный имеют смысл для конкретной программы. Локальный идентификатор работает только в пределах процедуры (функции).

Пример.

program m1;

var a,b,c:real;

procedure sum1 (var v,s:real);

begin

c:=v+s; {здесь процедура пользуется идентификатором c}

end; {который заявлен в описании головного модуля}

begin {Головной модуль}

a:=21.234; b:=978.66;

sum1(a,b);

Writeln(‘сумма c= ’,c:4:2)

End.


Ниже приводится набор арифметических функций. Более подробно этих и других функциях и процедурах можно найти в литературе :

Марченко А.И. «Программирование среде Borland Pascal 7.0»,Киев,1996.

Или заглянув в Help транслятора Турбо_Паскаль.HH