Структура процедур и функций



Мы поможем в написании ваших работ!


Мы поможем в написании ваших работ!



Мы поможем в написании ваших работ!


ЗНАЕТЕ ЛИ ВЫ?

Структура процедур и функций



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

Каждая из пяти подпрограмм большого проекта может иметь большой объем и руководитель этой подпрограммы должен обладать всем набором средств Паскаля. Поэтому каждая подпрограмма может иметь и свои внутренние типы, метки, переменные, константы, процедуры и функции. Все эти объекты описываются внутри данной подпрограммы, являются локальными в ней и не видны снаружи.

По сути структура подпрограммы копирует структуру программы за исключением того, что в подпрограммах запрещено писать USES.

Приведу пример записи программы с вложенными подпрограммами:

PROGRAM Hard;

Uses ...

Label ...

Const ...

Type ...

Var ...

Procedure a1;

Const ...

Var ...

Procedure a11;

Label ...

Type ...

Var ...

begin

...

end;

Function f11

Var ...

begin

...

end;

begin

...

end;

Function f2;

Procedure a21;

begin

...

end;

begin

...

end;

begin

...

end.

Здесь в программу Hard входят процедура a1 и функция f2. В процедуру a1 вложены процедура a11 и функция f11. В функцию f2 вложена процедура a21.

Из f2 видна a1, но не видны a11 и f11. Точно так же из a21 видны a1 и f2, но не видны a11 и f11. Это значит, что в теле процедуры a21может содержаться вызов a1и f2, но не может содержаться вызов a11и f11.

Выражения

Понятие «выражение» я уже употреблял раньше без особых пояснений. Выражение – это то, что мы привыкли видеть в правой части оператора присваивания и в других местах. Например:

a := b+1 - здесь выражение - b+1

if c-6>f then … - здесь выражение - c-6>f

WriteLn (a+5) - здесь выражение - a+5

 

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

Арифметические выражения(то есть имеющие значением число):

· 0

· 2+5

· Sqrt(b+1) - Sqr(a[4,i]+r) + 1

· a[4,i] + vovka.ves

· ((w+b)/19)*(2/(w+1)+5)

 

Строковые выражения(то есть имеющие значением строку символов):

· ‘Весна’

· Copy(s,a,b)

· Copy(s,a,b)+ ‘Весна’

 

Логические выражения(то есть имеющие значением true или false):

· a>0

· (a+c)/(d+8)<=b+1

· c>’Ю’

· stroka=‘Весна’

· Copy(s,a,b)+ ‘Весна’ <> s1

· a in b

 

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

Под операндомбудем понимать переменную простого типа, константу, элемент массива, поле записи, функцию и вообще любой объект, имеющий конкретное значение одного из простых типов.

Каждое выражение тоже обязано иметь конкретное значение одного из типов. Тип выражения определяется типами входящих в него операндов и операциями над этими операндами. Каким образом – об этом в следующем параграфе.

Совместимость типов

Часто при запуске программы Паскаль выдает сообщение Type mismatch (несовместимость типов) и на этом основании отказывается выполнять программу. Так произойдет, например, при выполнении ошибочного фрагмента VAR y: Integer BEGIN y:=3/8: …., так как результат деления получается вещественный, а переменная y описана, как Integer. Нам нужно знать о том, какие типы совместимы, а какие нет.

Тип выраженияс операндами разных типов. Что будет, если в одном выражении участвуют величины разных типов? Какого типа будет результат выражения? Например, какого типа будет сумма a+b в следующем фрагменте:

VAR a: Byte; b: Word;

BEGIN .... a+b ... ?

Вот ответ - Если осуществляется операция над двумя величинами разных типов, то перед выполнением операции они преобразуются к общему типу и только затем операция выполняется. Общий тип определяется так:

· Если диапазон одного из типов входит в диапазон другого, то общим типом становится тип с большим диапазоном. В приведенном выше примере значение переменной a будет преобразовано к типу Word и полученная сумма также будет иметь этот тип.

· Если диапазоны типов пересекаются, то общим типом становится ближайший тип, “охватывающий” оба типа.

В примере

VAR a: Integer; b: Word;

BEGIN .... a+b ...

значения a и b перед суммированием преобразуются к типу LongInt.

· Если один из типов вещественный, а другой целочисленный, то общий тип - всегда вещественный.

Когда в выражение входит несколько операндов (например, a+b*c) то указанные правила применяются последовательно, пока не будет вычислено все выражение (сначала определяется тип произведения b*c и произведение вычисляется, затем исходя из получившегося типа определяется тип суммы и сумма вычисляется).

Требования к типам в операторе присваивания. Чтобы Паскаль мог выполнить оператор присваивания, тип переменной в левой части (тип 1) и тип выражения в правой части (тип 2) должны друг другу соответствовать по определенным правилам:

· эти типы должны быть одинаковы

· или, если эти типы не одинаковы, то диапазон типа 1 должен включать в себя диапазон типа 2, например:

Тип 1 Тип 2

(sun, mon, tue, wen) (sun, mon, tue)

String Char

· или тип 1 - вещественный, тип 2 – целочисленный

 

Требования к совместимости типов формальныхи фактических параметровпроцедур и функций. Эти требования зависят от того, о каких параметрах идет речь – о параметрах-переменных или параметрах-значениях. В первом случае требование простое – типы должны быть эквивалентны. Во втором случае действуют требования к типам в операторе присваивания, где тип 1 – формальный параметр, тип 2 – фактический.

Форматы вывода данных

Обычный (бесформатный) вывод данныхобладает тем недостатком, что данные, выводимые одним оператором WriteLn и перечисленные в скобках этого оператора через запятую, изображаются на экране подряд, без промежутков. Например, после выполнения фрагмента

c:='Ф'; s:='хорошо'; i:=18; WriteLn(c,s,i)

мы увидим в строке экрана

Ф х о р о ш о            

Мы можем приказать Паскалю отводить под каждое данное столько позиций в строке, сколько нам нужно: WriteLn(c:3,s:8,i:4)

Вот что мы увидим в строке экрана:

    Ф     х о р о ш о                            

Здесь под c отведено поле в три позиции (с 1 по 3), начиная с левого края экрана. Под s отведено поле в 8 позиций (с 4 по 11). Под i отведено поле в 4 позиции (с 12 по 15). Информацией заполняется правая часть поля, а левая часть может остаться пустой.

Еще один недостаток бесформатного вывода: данные типа Real всегда изображаются в неудобочитаемом экспоненциальном виде. Например, после выполнения фрагмента

r:=465.28073; WriteLn(r)

мы увидим на экране

  . E +          

что означает 4.65280730000231 * 102 или, что то же самое, 465.280730000231. Обратите внимание на откуда-то взявшиеся цифры 231. Их появление связано с неточностью представления вещественных чисел в компьютере.

Еще один пример: r:=0.000000308; WriteLn(r)

  . E -          

что означает 3.08000000000079 * 10-7 или, что то же самое, 0.000000308000000000079 .

Еще пример: r:= -0.000003; WriteLn(r)

- . E -          

что означает -2.99999999999953 * 10-6 или, что то же самое, -0.00000299999999999953, а это практически равно -0.000003.

Как избавиться от экспоненциального вида? Формат :9:3 прикажет Паскалю изобразить число типа Real в привычном для нас виде, отведя под него 9 позиций в строке, из них 3 позиции под дробную часть числа. Пример:

r:=465.28073; WriteLn(r:9:3)

    .                                    

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

Еще пример: r:=465.28073; WriteLn(r:10:0)

                                               

Еще пример: r:= -465.28073; WriteLn(r:10)

- . E +                                  

Это у нас получился вывод в "укороченном" экспоненциальном формате.

Переполнение ячеек памяти

После выполнения программы

VAR i:Byte;

BEGIN i:=250; WriteLn(i); i:=i+10; WriteLn(i) END.

мы увидим на экране числа 250 и 4. А почему не 250 и 260? Потому что тип Byte представляет только числа от 0 до 255. Если в процессе выполнения программы значение переменной вышло за диапазон своего типа, Паскаль не замечает ошибки, а в соответствующей ячейкеоказывается ерунда. Это касается всех типов. Впрочем, ценой некоторой потери скорости Паскаль можно легко настроить на проверку выхода за диапазон (см. приложение).

Дерево типов

Паскаль предоставляет солидные возможности для конструирования новых типов. Так, если мы пишем VAR a : array[1..10] of array [2..5] of set of Byte, то имеем в виду, что переменная a является массивом array[1..10], который сконструирован из массивов array [2..5], каждый из которых сконструирован из элементов, являющихся множествами set, каждое из которых сконструировано из элементов типа Byte.

Схема, приводимая ниже, демонстрирует, какие типы из каких можно конструировать. Например, файлы можно конструировать из строк, а записи из массивов. А вот множества из вещественных чисел конструировать нельзя.

 

 





Последнее изменение этой страницы: 2016-07-11; просмотров: 122; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 54.165.57.161 (0.011 с.)