Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

function st(x,y:real):real;. stn:=exp(y*Ln(x));. z:=(3*tg(x/pi)+4.3*st(r,8.65))/(12*stn(a,5));. procedure <имя> (список формальных параметров);




function st(x, y: real): real;

begin

stn: =exp(y*Ln(x));

end;

Описанные выше функции теперь могут быть использованы в основной части программы, например, в операторе присваивания:

 

z: =(3*tg(x/pi)+4. 3*st(r, 8. 65))/(12*stn(a, 5));

 

Данный оператор вычислит значение выражения .

3. Процедуры

Для использования подпрограммы-процедуры необходимо сначала описать процедуру, а затем обращаться к ней (обращение к процедуре – отдельный оператор). Описание процедуры включает заголовок, свой раздел описаний и тело процедуры. Заголовок состоит из зарезервированного слова procedure, имени процедуры и заключенного в скобки списка формальных параметров с указанием типа. Название «формальные» эти параметры получили в связи с тем, что в этом списке заданы только имена для обозначения исходных данных и результатов работы процедуры, а при вызове подпрограммы на их место будут поставлены конкретные значения. Допускается отсутствие параметров, если в них нет необходимости. Тело процедуры – блок, по структуре аналогичный программе.

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

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

Общий вид описания процедуры:

procedure < имя> (список формальных параметров);

const …;

… {раздел описания}

var …;

begin

< операторы>;

end;

4. Оператор вызова процедуры

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

Например, в рассматриваемом ниже примере будут использованы стандартные процедуры ClrScr, Gotoxy и Textcolor, описанные в модуле crt, а также будет описана своя процедура name.

 

Пример 3. 4. Вывести по четырем углам экрана свое имя цветными буквами с эффектом мерцания.

program names;

{объявление использования процедур модуля crt}

uses crt;

procedure name(x, y, c: byte);

begin

Gotoxy(x, y); {позиционирование курсора}

Textcolor(c+16); {установка цвета с и мерцания}

Write(‘Иван’);

end;

begin

Clrscr; {очистка экрана}

name(2, 2, 14); {вызов процедуры}

name(2, 22, 8);

name(75, 2, 3);

name(75, 22, 5);

end.

 

5. Механизм передачи параметров в подпрограммах

Как вы уже заметили, параметры в процедуры и функции передаются согласно порядку следования.

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

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

Число фактических параметров должно быть равным числу формальных параметров.

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

Тип каждого фактического параметра должен соответствовать типу своего описанного формального параметра.

Если формальный параметр описан с ключевым словом var, то в качестве соответствующего фактического может стоять только переменная. В противном случае в качестве фактических параметров могут быть переменные, константы и выражения.

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

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

6. Стандартные библиотечные модули

В систему Турбо Паскаль версии 6. 0 и старше включены 8 модулей: System, Crt, Dos, Graph, Graph3, Overlay, Printer, Turbo3 и специализированная библиотека Turbo Vision. Модуль System подключается по умолчанию, поэтому в любой программе становятся доступными все его встроенные процедуры и функции (см. табл. 1. 6). Остальные модули должны подключаться с помощью зарезервированного слова usesс добавлением имени модуля. Например: uses сrt;.

Рассмотрим кратко назначение каждого модуля:

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

Crt – содержит средства управления дисплеем и клавиатурой компьютера.

Dos – включает средства, позволяющие реализовывать различные функции Dos.

Graph3 – поддерживает использование стандартных графических подпрограмм.

Overlay – содержит средства организации специальных оверлейных программ.

Printer – обеспечивает быстрый доступ к принтеру.

Turbo3 – обеспечивает максимальную совместимость с версией Турбо Паскаль 3. 0.

Graph – содержит пакет графических средств.

Turbo Vision – библиотека объектно-ориентированных программ для разработки пользовательских интерфейсов.

На примере модуля Crt познакомимся поближе с работой встроенных процедур и функций. Он устанавливает режим работы адаптера дисплея, организует вывод в буфер экрана, регулирует яркость свечения символов и т. д. С момента подключения пользователю доступны все содержащиеся в нем стандартные средства. Рассмотрим некоторые из них.

TextMode(Mode: integer); – Установка текстового режима. Значение Mode равно 1 (40 символов / 25 строк) или 3(80 / 25).

ClrScr; – полностью очищает экран;

ClrEol; – стирает все символы в строке, начиная с текущей позиции до конца строки;

GotoXY(x, y); – перемещает курсор в позицию, заданную координатами x, y.

TextColor(Color: byte); – установка цвета выводимых символов;

TextBackGround(Color); – установка цвета фона.

Чтобы добавить при выводе эффект мерцания, при установке цвета указывается Blink (16). Смотрите пример 3. 4.

Подробное описание модулей и описанных в них процедур и функций смотрите в [3].

 

 

Тема 3. 3 Команды сдвига. Упаковка данных.

 

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

КОП op1, op2

где op1 может быть r8, m8, r16 или m16, а op2 – иметь значение единицы или быть коротким регистром cl. [40] Мы рассмотрим сначала команды сдвига вида КОП op1, 1, а затем обобщим их на случай команд вида КОП op1, cl.

Команда сдвига операнда на один бит влево имеет показанный ниже вид

 

 

и её выполнение можно так описать в виде цикла на Паскале:

CF: =op1[N]; for i: =N downto 1 do op1[i]: =op1[i-1]; op1[0]: =0

Как видим, при сдвиге битового вектора на одну позицию влево самый левый бит не теряется, а попадает во флаг переноса CF, а на освободившееся справа место записывается нулевой бит. Все команды сдвига устанавливают флаги по значению результата по тем же правилам, что и команды сложения и вычитания. Например, флагу – признаку отрицательного результата SF приваивается самый левый бит результата, т. е. SF: =op1[N]. Однако среди флагов, изменяемых командами сдвигов, в практическом программировании имеет смысл рассматривать только флаг переноса CF и флаг нуля ZF (он устанавливается в единицу, если, как обычно, получается полностью нулевой вектор-результат).

Команда сдвига влево часто называется логическим сдвигом влево, у кода операции этой команды есть синоним sal, который называется арифметическим сдвигом влево. Логический и арифмети­ческий сдвиги выполняются одинаково, а различие в их названиях будет понятно из дальнейшего изложения.

В том случае, если мы будем трактовать операнд команды сдвига влево на один бит как целое число, то результатом сдвига является умножение этого числа на два. При этом результат умножения получается правильным, если во флаг переноса CF попадает незначащий бит результата. Таким обра­зом, для беззнакового числа при правильном умножении на 2 должно быть CF=0, а для знакового опе­ранда результат получается правильным только тогда, когда значение флага переноса совпадает со знаковым (крайним слева) битом результата, т. е. после выполнения команды сдвига справедливо равенство CF=op1[N].

Рассмотрим теперь команды сдвига на один разряд вправо. По аналогии со сдвигом на один разряд влево, сдвиг на один разряд вправо можно трактовать как деление целого числа на два. Однако, так как деление на два должно выполняться по разным правилам для знаковых и беззнаковых целых чисел (вспомним различные команды div и idiv ), то существуют две разные команды сдвига операнда на один бит вправо. Команда логического сдвига на один разряд вправо

shr op1, 1

выполняется по правилу:

CF: =op1[0]; for i: =0 to N-1 do op1[i]: =op1[i+1]; op1[N]: =0

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

 

она выполняется по правилу:

CF: =op1[0]; for i: =0 to N-1 do op1[i]: =op1[i+1]

Как видим, крайний левый бит аргумента при арифметическом сдвиге вправо не меняется. Особым здесь является случай, когда операнд равен минус единице, тогда операция деления этого операнда на два не эквивалентна операции арифметического сдвига вправо на один бит. Легко прове­рить, что (-1) div 2 = 0, а результат арифметического сдвига вправо операнда со значением –1 снова даёт -1 (т. е. sar -1, 1 = -1).

Заметим далее, что, как и " настоящие" команды деления, сдвиг вправо даёт два результата: частное на месте своего операнда и остаток от деления на 2 во флаге CF. Действительно, легко видеть, что

CF: =op1 mod 2 для беззнакового операнда и

CF: = abs (op1 mod 2) для знакового операнда.

Таким образом, для проверки того, является ли целое число X нечётным, можно использовать следующие две команды

shl X, 1

jc ODD; Нечётное X

Программисты, однако, не любят этот способ проверки на нечётность, так как при этом портится операнд X. Лучше проверять целое число X на нечётность двумя командами

test X, 1

jne ODD; Нечётное X

Следующая группа команд сдвига – так называемые циклические сдвиги. Эти команды рассматривают свой операнд как замкнутый в кольцо: после бита с номером N располагается бит с номером 0, а перед битом с номером 0 – бит с номером N. Ясно, что при циклическом сдвиге операнд сохраняет все свои биты, меняются только номера этих битов. Команда циклического сдвига влево

rol op1, 1

выполняется по правилу

shl op1, 1; op1[0]: =CF

Команда циклического сдвига вправо

ror op1, 1

выполняется по правилу

shr op1, 1; op1[N]: =CF

Команда циклического сдвига через флаг переноса включают в кольцо сдвигаемых битов дополнительный бит – флаг переноса CF, который включается между битами с номерами 0 и N. Таким образом, в сдвиге участвуют N+1 бит. Команда циклического сдвига влево через флаг переноса

rcl op1, 1

выполняется по правилу

t: =CF; rol op1, 1; op1[0]: =t

Здесь t – некоторая вспомогательная (врé менная) переменная.

Команда циклического сдвига вправо через флаг переноса

rcr op1, 1

выполняется по правилу

t: =CF; ror op1, 1; op1[N]: =t

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

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

КОП op1, cl

Выполняется по правилу

for cl: =cl downto 1 do КОП op1, 1; cl: =0

Таким образом, значение регистра cl задаёт число разрядов, на которые в цикле происходит сдвиг операнда, после цикла, как обычно, счётчик цикла (в данном случае регистр cl) обнуляется. Ясно, что задавать сдвиги более чем на N разрядов не имеет большого смысла.

 

 

Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...