Мы поможем в написании ваших работ!
ЗНАЕТЕ ЛИ ВЫ?
|
Актуализация знаний и умений учащихся по пройденному материалу
1) Тестирование сообща
2) Найди ошибку в программе:
Уровень
| Вариант 1
| Вариант 2
|
| Пример 1.1
| Пример 1.2
|
| Пример 2.1
| Пример 2.2
|
| Пример 3.1
| Пример 3.2
| Таблица результатов выполнения программ и заработанных баллов
Результат выполнения программы
| Баллы
|
|
|
|
|
|
|
|
|
|
|
|
| другие результаты
|
| 3) Домино. Установите взаимно-однозначное соответствие:
| x:=1;
While x<=10 dox:=x+1;
writeln(x);
| П
| Тело цикла не выполнится ни разу
|
| x:=1
While x=1 do
begin
writeln(x)
x:=x+1
end
| Х
| Тело цикла будет выполнено 10 раз
|
| x:=11;
While x<10 do
begin
writeln(x);
x:=x+1
end;
| У
| Тело цикла будет выполнено 1 раз
|
| x:=1;
While x<5 do
begin
writeln(x);
x:=x-1
end;
| С
| Тело цикла будет выполняться бесконечно
|
| x:=0;
While x<=5 do
begin
writeln(x);
x:=x+6
end;
| Е
| Появится сообщение о ошибке
|
4. Физминутка
Реализация, составление алгоритмов с использованием повторения. Графика в программе Паскаль АВС.
Материал для повторения
Процедура
| Назначение
| uses graphabc;
| Подключение модуля GraphABC
| setwindowsize (940,680);
| Устанавливается ширина и высота графического экрана
| setwindowtitle ('Мой рисунок');
| Заголовок окна
| setpenwidth (2);
| Устанавливает ширину пера, равную 2 пикселям
| setpencolor(color);
| Устанавливает цвет пера, задаваемый параметром color
| rectangle(10,10,80,140);
| Рисует прямоугольник, заданный координатами противоположных вершин (10,10) и (80,140)
| circle(50,90,20);
| Рисует окружность с центром в точке (50,90) и радиусом 20
| line(20,30,110,160);
| Рисует отрезок с началом в точке (20,30) и концом в точке (110,160)
| floodfill(15,15, clfuchsia);
| | Цветовые константы для работы с цветом
| clBlack
| черныйй
| clPurple
| фиолетовый
| clWhite
| белый
| clRed
| красный
| clGreen
| зеленый
| clBrown
| коричневый
| clBlue
| синий
| clYellow
| желтый
| clOlive
| оливковый
| clFuchsia
| сиреневый
| clGray
| темно-серый
| clSilver
| серебряный
|
Пример 1. Составим алгоритм, в результате которого будет нарисован один круг.
Можешь загрузить! Пример 1
Пример 2. Изменим алгоритм примера 1 так, чтобы в результате его выполнения будет нарисовано 10 кругов по горизонтали.
Задание 1. Измените алгоритм примера 2 таким образом, чтобы в результате его выполнения рисовались 6 окружностей по вертикали.
Задание 2. Измените алгоритм примера 2 таким образом, чтобы в результате его выполнения рисовалось несколько красных (clred) окружностей по диагонали.
Ребус. Правильная осанка
7. Практическая работа по составлению алгоритмов
Задание 1. Дан алгоритм, в результате которого будет нарисован квадрат. Составьте алгоритм рисующий 10 квадратов по горизонтали.
Алгоритм 1
Задание 2. Дан алгоритм, в результате которого будет нарисован квадрат. Составьте алгоритм рисующий 10 квадратов по вертикали.
Алгоритм 2
Задание 3. Дан алгоритм, в результате которого будет нарисован квадрат. Составьте алгоритм рисующий 10 квадратов по диагонали.
Алгоритм 3
Задание 4. Дан алгоритм, в результате которого будет нарисован дом. Размножьте рисунок в любом направлении: по вертикали, по горизонтали, по диагонали. Примерный результат выполнения.
Алгоритм 4
Задание 5. Дан алгоритм, в результате которого будет нарисован клоун. Размножьте рисунок клоуна в любом направлении: по вертикали, по горизонтали, по диагонали. Примерный результат выполнения.
Алгоритм 5
Задание 6. Дан алгоритм, в результате которого будет нарисована улитка. Размножьте рисунок улитки в любом направлении: по вертикали, по горизонтали, по диагонали. Примерный результат выполнения.
Алгоритм 6
8. Домашнее задание:
Задание 1. Дан алгоритм.
Вариант 1
| Вариант 2
| Вариант 3
| program figury; uses graphabc; var x,y:integer; begin setwindowsize (940,680); setwindowtitle ('Фигуры'); setpenwidth (2); x:=10; y:=10; begin setpencolor (clblack); circle(x+40,y+40,40); floodfill(x+40,y+40, clbrown); circle(x+50,y+70,35); floodfill(x+50,y+70, clolive); circle(x+70,y+30,30); floodfill(x+70,y+30, clgreen); circle(x+65,y+60,25); floodfill(x+65,y+60, clpurple); end; end.
| program figury; uses graphabc; var x,y:integer; begin setwindowsize (940,680); setwindowtitle ('Фигуры'); setpenwidth (2); x:=10; y:=10; begin setpencolor (clblack); rectangle(x+40,y+40,x+140,y+90); floodfill(x+50,y+50, clyellow); rectangle(x+50,y+70,x+80,y+100); floodfill(x+55,y+75, clolive); rectangle(x+100,y+30,x+130,y+80); floodfill(x+110,y+35, clgreen); end; end.
| program tractor; uses graphabc; var x,y:integer; begin setwindowsize (940,680); setwindowtitle ('Трактор'); setpenwidth (2); x:=10; y:=10; begin setpencolor (clblack); rectangle(x+40,y+40,x+140,y+90); floodfill(x+50,y+50, clyellow); rectangle(x+50,y+50,x+80,y+85); floodfill(x+55,y+75, clolive); rectangle(x+95,y+10,x+130,y+65); floodfill(x+110,y+35, clgreen); circle(x+60,y+100,10); floodfill(x+60,y+100, clgray); circle(x+110,y+90,20); floodfill(x+110,y+90, clgray); end; end.
| Алгоритм_1
| Алгоритм_2
| Алгоритм_3
| Измените алгоритм таким образом, чтобы в результате его выполнения данный там рисунок повторялся несколько раз.
Задание 2*. Составьте программу, которая нарисует любой небольшой рисунок. Внесите изменения в алгоритм, чтобы рисунок повторялся несколько раз.
Задание 3. Это интересно! Отгадайте ребус:
9*. Тестирование
10. <bРефлексия< b="">Рефлексия</bРефлексия<>
Мы находим в жизни лишь то, что сами в нее вкладываем. Р. Эмерсон
Какие трудности одолевали Вас во время урока?
Что нового вы узнали на уроке?
С каким материалом вам бы хотелось поработать на следующем уроке?
Заполните пропуски в программе, в результате выполнения которой будет нарисовано 5 прямоугольников и 5 окружностей.
Program figury; uses graphabc; var x,y,i:___________; begin setwindowsize (940,680); setwindowtitle ('Фигуры'); setpenwidth (2); x:=10; y:=10; _____ i:=1 to _____ do begin ___________(x+10,y+10,x+80,y+40); floodfill(x+15,y+15, clfuchsia); __________(x+50,y+90,20); floodfill(x+50,y+90, clteal); x:=x+100; end; end.
43. В языке Паскаль имеется две разновидности подпрограмм - процедуры и функции.Структура любой подпрограммы аналогична структуре всей программы. Подпрограмма должна быть описана до того, как она будет использована в программе или другой подпрограмме.Все параметры, которые использует подпрограмма, можно разбить на две категории: локальные параметры, объявленные внутри подпрограммы и доступные только ей самой, и глобальные - объявленные в основной программе и доступные как программе, так и всем ее подпрограммам. Обмен информацией между основной программой и подпрограммой может осуществляться только с помощью глобальных параметров.Подпрограмма может использовать глобальные параметры двояким образом: - непосредственно обращаясь к глобальному параметру по его имени или используя механизм формальных параметров. - Подпрограмма может непосредственно использовать любые глобальные параметры за исключением тех, которые имеют те же имена, что и ее локальные параметры. Механизм формальных параметров будет рассмотрен в п. 10.3. 10.1. ПроцедураПодпрограмма-процедура предназначена для выполнения какой-то законченной последовательности действий. Любая процедура начинается с заголовка. В отличие от основной программы заголовок в процедуре обязателен. Он состоит из зарезервированного слова procedure, за которым следует идентификатор имени процедуры, а далее в круглых скобках - список формальных параметров: procedure <имя процедуры>(<список формальных параметров>); За заголовком могут идти такие же разделы, что и в основной программе. В отличие от основной программы процедура завершается не точкой, а точкой с запятой. Пример. Процедура ввода N целых чисел.Пусть в основной программе определен тип type tArr = array[1..100] of Integer; Процедура может иметь вид: procedure InpInt(var Mas: tArr; N: Integer); {заголовок процедуры со списком формальных параметров, проверка N <= 100 - в основной программе}var i: Integer; {локальный параметр - параметр цикла}begin WriteLn('Введите ', N, ' целых чисел'); for i:= 1 to N do Read(Mas[i]) end; Для вызова процедуры из основной программы или другой подпрограммы следует записать оператор, состоящий из имени процедуры и списка фактических параметров, которые должны совпадать по количеству и типам с формальными параметрами процедуры. Например: InpInt(M,K);означает, что вызывается процедура Inplnt для ввода К целых чисел в массив М. Естественно, что в этом случае параметр К целого типа, а М - массив типа tArr. 10.2. ФункцияПодпрограмма-функция предназначена для вычисления какого-либо параметра, у этой подпрограммы два основных отличия от процедуры. - Первое отличие функции в ее заголовке. Он состоит из слова function, за которым следует имя функции, далее в круглых скобках - список формальных параметров (о формальных параметрах см. п. 10.3), затем через двоеточие записывается тип функции - тип возвращаемого параметра. Функция может возвращать параметры следующих типов: любого порядкового, любого вещественного, стандартного типа string, любого указателя, в том числе и типа PChar. - Второе отличие заключается в том, что в теле функции хотя бы раз имени функции должно быть присвоено значение. Пример. Функция вычисления факториала числа N.function Factorial(N: Byte): Longint; var Fact: Longint; i: Byte;begin Fact:= N; for i:= N-l downto 2 do Fact:= Fact * i; Factorial:= Fact end; Если имя функции внутри ее описания используется в правой части оператора присваивания, то это означает, что функция вызывает себя рекурсивно (см. п. 10.6).Для вызова функции из основной программы или другой подпрограммы следует в выражении, где необходимо использовать значение функции, указать имя функции со списком фактических параметров, которые должны совпадать по количеству и типам с формальными параметрами функции, например: Part:=Sqr(T)/Factorial(i); В этом операторе: Sqr(T) - вызов стандартной функции возведения в квадрат с фактическим параметром Т; Factorial (i) - вызов функции, вычисляющей факториал с фактическим параметром i. 10.3. Формальные и фактические параметрыФормальные параметры подпрограммы указывают, с какими параметрами следует обращаться к этой подпрограмме (количество параметров, их последовательность, типы). Они задаются в заголовке подпрограммы в виде списка формальных параметров, разбитого на группы, разделенные точками с запятыми. В группу формальных параметров включаются однотипные параметры одной категории.Все формальные параметры можно разбить на четыре категории: - параметры-значения (значения этих параметров основной программы подпрограммой не меняются); - параметры-переменные (значения этих параметров основной программы подпрограмма может изменить); - параметры-константы (используются только в версии 7.0); - параметры-процедуры и параметры-функции (т. е. процедурного типа). Для каждого формального параметра следует указать имя и, как правило, тип, а в случае параметра-переменной или параметра-константы - его категорию. Имена параметров могут быть любыми, в том числе и совпадать с именами объектов программы. Необходимо лишь помнить, что в этом случае параметр основной программы с таким именем становится недоступным для непосредственного использования подпрограммой. Тип формального параметра может быть практически любым, однако в заголовке подпрограммы нельзя вводить новый тип. Например, нельзя писать: function Max(A: array[1..100] of Real): Real; Чтобы правильно записать этот заголовок, следует в основной программе ввести тип-массив, а затем использовать его в заголовке: type tArr = array[1..100] of Real;function Max(A: tArr): Real; При обращении к подпрограмме формальные параметры заменяются на соответствующие фактические вызывающей программы или подпрограммы. 10.3.1. Параметры-значенияПараметры-значения передаются основной программой в подпрограмму через стек в виде их копий и, следовательно, собственный (т.е. фактический) параметр программы подпрограммой измениться не может.Параметр-значение указывается в заголовке подпрограммы своим именем и через двоеточие - типом. Тип параметра-значения может быть любым за исключением файлового.Если параметров-значений одного типа несколько, их можно объединить в одну группу, перечислив их имена через запятую, а затем уже указать общий тип. Как отмечалось выше, отдельные группы параметров отделяются друг от друга точкой с запятой. Пример.procedure Inp(Max, Min: Real; N: Word); function Mult(X, Y: Integer): Real; В качестве фактического параметра на месте параметра-значения при вызове подпрограммы может выступать любое выражение совместимого для присваивания типа (см. п. 9.3), не содержащее файловую компоненту, например: Inp(Abs(Z), -Abs(T), 2 * К);M:=Mult(X + Y, X - Y);MA:=Max(B, 5); Пример. Функция вычисления максимального элемента в массиве.Пусть в основной программе определен тип-массив, массив этого типа и переменная целого типа type tArr = array[l..100] of Integer; var Massiv: tArr; Maxim: Integer; Функция в этом случае может иметь вид: function Max(Mas: tArr; N: Byte): Integer;var Ma: Integer;i: Byte; begin Ma:= Mas[1]; for i:= 2 to N do if Ma < Mas[i] then Ma:= Mas[i]; Max:= Ma end; Теперь, например, для определения максимального числа из первых пяти чисел массива Massiv и записи его в переменную Maxim можно записать оператор: Maxim:= Max(Massiv,5); Следует иметь в виду, что подпрограмма может работать только с массивами типа tArr. Для массивов другого типа придется создавать другую аналогичную подпрограмму. Кроме того, при работе подпрограммы в стеке будет создана копия исходного массива, что приводит к уменьшению быстродействия и заполнению стека излишней информацией. 10.3.2. Параметры-переменныеПри передаче параметров-переменных в подпрограмму фактически через стек передаются их адреса в порядке, объявленном в заголовке подпрограммы. Следовательно, подпрограмма имеет доступ к этим параметрам и может их изменять.Параметр-переменная указывается в заголовке подпрограммы аналогично параметру-значению, но только перед именем параметра записывается зарезервированное слово var. Действие слова var распространяется до ближайшей точки с запятой, т. е. в пределах одной группы. Пример.procedure MaxMin(A: tArr; var Max, Min: Real; N: Word); Здесь Max, Min - параметры-переменные, А и N - параметры-значения. Тип параметров-переменных может быть любым, включая и файловый.При вызове подпрограммы на месте параметра-переменной в качестве фактического параметра должна использоваться переменная идентичного типа (см. п. 9.1). Так, если формальный параметр имеет тип, определенный следующим образом: type tArr = array[l..100] of Integer; то и фактический параметр должен быть переменной или типизированной константой типа tArr. Пример. Функция вычисления максимального элемента в массиве.Модифицируем подпрограмму примера п. 10.3.1, используя в качестве первого параметра параметр-переменную: function Max(var Mas: tArr; N: Byte): Integer; var Ma: Integer; i: Byte; begin Ma:= Mas[1]; for i:= 2 to N do if Ma < Mas[i] then Ma:= Mas[i]; Max:= Ma end; Этот вариант лучше предыдущего тем, что в данном случае в стеке не создается копия исходного массива, что улучшает быстродействие и экономит память. Однако при такой передаче параметра возможно его нежелательное изменение (такой вариант передачи параметра допустим только в таких небольших подпрограммах, как в данном примере, когда программист может проконтролировать отсутствие несанкционированного изменения параметра). Недостаток же, связанный с тем, что подпрограмма может работать только с одним типом массивов, остается. 10.3.3. Параметры-константыЧасто в качестве параметра в подпрограмму следует передать ту или иную переменную, но изменять ее подпрограмма не должна. В этом случае нежелательно передавать этот параметр как параметр-переменную. Можно его передать как параметр-значение, однако, если эта переменная имеет большой размер (массив, запись и т. д.), то копия такого параметра займет большую часть стека и даже может его переполнить. Это же приводит и к уменьшению быстродействия программы. В этой ситуации параметр лучше передать как параметр-константу. Такой параметр, если он структурированного типа, передается своим адресом, но предусматривается защита от его изменения. Использовать параметр-константу можно только в версии 7.0. Параметр-константа указывается в заголовке подпрограммы аналогично параметру-значению, но перед именем параметра записывается зарезервированное слово const. Действие слова const распространяется до ближайшей точки с запятой, т. е. в пределах одной группы. Пример.function NewString(const S: string): string; Тип параметра-константы может быть любым за исключением файлового.При вызове подпрограммы на месте параметра-константы в качестве фактического параметра можно использовать любое выражение совместимого для присваивания типа (см. п. 9.3), не содержащего файловую компоненту. Параметр-константу нельзя передавать в другую подпрограмму в качестве фактического параметра. Пример. Функция вычисления максимального элемента в массиве.В примере п. 10.3.1 используем в качестве первого параметра параметр-константу: function Max(const Mas: tArr; N: Byte): Integer; var Ma: Integer; i: Byte; begin Ma:= Mas[l]; for i:= 2 to N do if Ma < Mas[i] then Ma:= Masli]; Max:= Ma end; 10.3.4. Параметры без типаВ Turbo Pascal можно использовать параметры-переменные и параметры-константы без указания типа. В этом случае фактический параметр может быть переменной любого типа, а ответственность за правильность использования того или иного параметра возлагается на программиста. Пример.function Equal(var Paraml, Param2; Len: Word): Boolean;Здесь Paraml, Param2 - параметры-переменные без типа (вместо них можно использовать, например, любые переменные простого типа, типа массив, типа запись и т. д.); Len - параметр-значение.Следует иметь в виду, что параметр без типа внутри подпрограммы типа не имеет и его перед использованием следует преобразовать к конкретному типу, применяя идентификатор соответствующего типа так, как это указывалось в п. 9.4, при этом полученный результат может быть любого размера. Пример. Функция вычисления максимального элемента в массиве.Рассмотрим другой вариант подпрограммы примера п. 10.3.1, используя в качестве первого параметра параметр-переменную без типа: function Max(var Mas; N: Byte): Integer; type tArray = array[1..Maxint] of Integer; {тип массива максимального размера}var Ma: Integer; i: Byte; begin Ma:= tArray(Mas)[1]; for i:= 2 to N do if Ma < tArray(Mas)[i] then Ma:= tArray(Mas)[i]; Max:= Ma end; В этом случае в качестве первого передаваемого параметра можно использовать любой массив (и не только массив), так что подпрограмма становится более универсальной. Тем не менее здесь необходимо передавать в качестве второго параметра фактический размер информации, что не очень удобно. 10.3.5. Массивы и строки открытого типаВ версии 7.0 можно в качестве параметров-переменных использовать массивы и строки открытого типа, у которых не задаются размеры. В качестве фактического параметра в этом случае можно использовать массив или строку любого размера, однако массив должен состоять из тех же компонент, что и компоненты открытого массива. Такие параметры введены для того, чтобы подпрограмма могла обрабатывать массив или строку любого размера. Фактический размер массива в этом случае может быть определен с помощью функции High (см. п. 16.1). Открытый массив задается как и обычный массив, но только без указания типа индекса. Следует иметь в виду, что индексация элементов открытого массива всегда начинается с нуля, а максимальный индекс элемента равен значению функции High. Пример. Функция вычисления максимального элемента в массиве.Рассмотрим вариант подпрограммы примера п. 10.3.1, используя в качестве передаваемого параметра массив открытого типа; function Max(var Mas: array of Integer): Integer; var Ma: Integer; i: Byte; begin Ma:= Mas[0]; for i:= 1 to High(Mas) do {цикл до наибольшего индекса} if Ma < Mas[i] then Ma:= Mas[i]; Max:= Ma end; В этом примере в подпрограмму передается только один параметр и она может работать с любым одномерным массивом целых чисел. Однако следует иметь в виду, что при работе подпрограммы для открытого массива в стеке опять-таки создается его копия, что может его переполнить. Разновидность открытого массива - открытая строка, которая может задаваться либо с помощью стандартного типа OpenString, либо с помощью типа string и использования ключа компилятора {$Р+} (см. п. 17.7.1), например заголовок процедуры, заполняющей каким-либо символом строку, может иметь вид: procedure FillChar(var Str: OpenString; Ch: Char); или{$P+}procedure FillChar(var Str: string; Ch: Char); 10.3.6. Параметры-процедуры и параметры-функцииПередаваемым параметром может быть также параметр-процедура или параметр-функция, т. е. параметр процедурного типа. Фактически этот параметр является параметром-значением, т. к. записывается без зарезервированного слова varВ качестве фактического параметра в этом случае используется соответствующая процедура или функция, имеющая необходимое количество параметров требуемых типов.Для параметров-процедур и параметров-функций существуют те же правила, что и для других переменных процедурного типа: подпрограммы должны компилироваться с ключом {$F+} или иметь директиву far, не должны быть стандартными подпрограммами, не должны объявляться внутри других подпрограмм, не иметь директив inline или interrupt. Пример. Программа, печатающая таблицы сложения и умножения двух целых чисел в заданном диапазоне. program EXAMPLE15; typeFunc = function(X, Y: Integer): Integer; {$F+}function Add(X, Y: Integer): Integer;beginAdd:= X + Yend; function Multiply(X, Y: Integer): Integer;begin Multiply:= X * Y end; {$F-} procedure PrintTable(A, B: Integer; Operation: Func);{процедура печати таблицы}var i, j: Integer; begin for i:= 1 to A do begin for j:= 1 to В do Write(0peration(i, j): 5); WriteLn end; WriteLn end; begin {начало основной программы} PrintTable(10, 10, Add); PrintTable(10, 10, Multiply) end. 10.4. Процедура EXITКак указывалось раньше (см. п. 5.1.2), оператор GOTO нельзя использовать для досрочного выхода из подпрограммы. В Turbo Pascal с этой целью используется процедура Exit. Пример. Функция, определяющая первое отрицательное число в массиве. function Minus(var Massiv; N: Integer): Real;{Massiv - параметр без типа}type Т = array [1..1000] of Real;var i: Integer; begin Minus:= 0; for i:= 1 to N do if T(Massiv)[i] < 0 then {преобразование типа} begin Minus:= T(Massiv)[i]; Exit {досрочный выход из функции} end end; 10.5. Директивы подпрограммДирективы дают дополнительную информацию транслятору о размещении подпрограмм. 10.5.1. Директива FORWARDЕсли одна подпрограмма использует другую, а та, в свою очередь, эту первую, то возникает проблема размещения этих подпрограмм в программе (ни одну из них нельзя поместить перед другой). Чтобы устранить это противоречие, используется директива forward, позволяющая как бы разбить на две части одну из подпрограмм.При использовании директивы forward сначала записывается полный заголовок первой подпрограммы. Тело этой подпрограммы заменяется директивой forward. Затем полностью описывается вторая подпрограмма, а уже после этого полностью описывается первая подпрограмма. При этом можно записать сокращенный заголовок подпрограммы, который включает слово procedure или function и ее имя. Список формальных параметров и тип подпрограммы (если это подпрограмма-функция) не указывается. Пример. Процедура First вызывает процедуру Second, а та, в свою очередь, процедуру First. procedure First(A, В: Integer); forward; {заголовок первой процедуры}procedure Second(C: Real); {вторая процедура}var X, Y; Integerbegin... First(X, Y);...end; procedure First; {первая процедура}var Z: Realbegin... Second(Z);...end; Директиву forward можно использовать и просто для более удобного размещения подпрограмм: сначала описать все заголовки, а затем - сами подпрограммы. Эту директиву не следует использовать в модулях (см. п. 16) для подпрограмм, объявленных в интерфейсе модуля. 10.5.2. Директивы FAR и NEARКак правило, компилятор Turbo Pascal автоматически выбирает адресацию к подпрограмме. Например, если подпрограмма находится в одном файле с основной программой, то она компилируется с "ближним" (near) адресом входа и возврата, состоящим только из смещения в текущем сегменте, а если она находится в модуле, то формируется "дальний" (far) адрес, состоящий из адреса сегмента и смещения.В некоторых случаях нужен нестандартный вариант компиляции. Так, например, если подпрограмма используется для переменных процедурного типа, она независимо от своего расположения должна компилироваться с получением "дальнего" адреса. В этом случае в подпрограмме можно использовать директиву far, которая сообщит компилятору, что нужно формировать именно такой адрес. Эта директива эквивалентна ключу компилятора {$F+}, однако в отличие от этого ключа действие директивы распространяется только на одну подпрограмму.Реже используется директива near, которая сообщает компилятору, что подпрограмму следует компилировать с получением именно такого адреса. Эта директива эквивалентна ключу компилятора {$F-}, который выбирается по умолчанию. Действие директивы распространяется только на одну подпрограмму. 10.5.3. Директива EXTERNALДиректива external позволяет использовать в программе подпрограммы, написанные на языке ассемблера и скомпилированные отдельно. Эти подпрограммы должны быть скомпонованы с основной программой, используя ключ {$L <имя файла>}(Здесь имя файла - имя того файла (с расширением.OBJ), в котором находятся скомпилированные объектные модули подпрограмм, написанных на языке ассемблера. Пример.function Max(X, Y: Real): Real; external; procedure Search(var Mas; N: Integer; var Max, Min: Integer); external;{$L ASMBL.OBJ} Директиву external следует использовать, если подпрограммы на ассемблере имеют большой размер и их лучше скомпилировать отдельно, а не использовать встроенный ассемблер или писать их в кодах процессора, используя директиву inline (см. п. 10.5.5). 10.5.4. Директива ASSEMBLERДиректива assembler позволяет написать подпрограмму полностью на языкеассемблера. При этом во время компиляции подпрограмма будет автоматически скомпилирована встроенным ассемблером пакета Turbo Pascal. При отладке такой подпрограммы можно использовать встроенный отладчик пакета. Пример. Функция, определяющая максимальное из двух чисел.function MaxTwo(X, Y: Integer): Integer; assembler;asm MOV AX,X CMP AX,Y JG @1 MOV AX,Y @1: end; 10.5.5. Директива INLINEДиректива позволяет включить в текст программы команды, записанные непосредственно в машинных кодах. В отличие от других подпрограмм подпрограмма с директивой inline непосредственно добавляется всюду, где есть ее вызов (фактически она является макроопределением). Такие подпрограммы могут иметь параметры, которые можно использовать в тексте подпрограммы, получая их из стека.Машинные коды в процедуре записываются в круглых скобках побайтно через прямой слеш (/). Пример. Функция, вычисляющая максимальное из двух чисел.function MaxTwo(X, Y: Integer): Integer; inline($58/ { POP AX - получение Y из стека }$5A/ { POP DX - получение Х из стека }$3B/$C2/ { CMP AX,DX }$7F/$02/ { JG - переход через одну команду }$8В/$С2); { MOV AX.DX } В связи с тем, что такие подпрограммы являются макроопределениями и помещаются всюду, где осуществляется их вызов, нет необходимости организовывать стандартный вход в подпрограмму и выход из нее с сохранением и восстановлением регистров. По этой причине такие подпрограммы являются довольно эффективными по быстродействию и объему занимаемой памяти. Однако использовать их целесообразно лишь в случаях, когда они являются достаточно короткими (не более десятка команд). 10.5.6. Директива INTERRUPTДиректива interrupt предназначена для процедур, обрабатывающих прерывания. Такие процедуры имеют стандартный заголовок: procedure IntHandler(Flags, CS, IP, AX,BX, CX, DX, SI, DI, DS, ES, BP: Word); interrupt; begin...end; В заголовке отдельные параметры можно опускать (но только с начала списка), промежуточные параметры удалять нельзя, например:procedure IntHandler(DI, ES, BP: Word); interrupt; (неправильный заголовок) procedure IntHandler(DI, DS, ES, BP: Word); interrupt; (правильный заголовок) Нельзя в заголовке процедуры обработки прерываний записывать и какие-либо другие параметры. 10.6. Рекурсивные процедуры и функцииЯзык Паскаль допускает, чтобы подпрограмма вызывала саму себя (рекурсивное обращение). Эта возможность связана с тем, что при каждом новом обращении к подпрограмме параметры, которые она использует, заносятся в стек, причем параметры предыдущего обращения также сохраняются.В ряде случаев (обычно для рекурсивных алгоритмов) рекурсивное оформление подпрограммы может быть более компактным и эффективным, но не следует забывать об опасности переполнения стека. Пример. Вариант функции, рекурсивно вычисляющей факториал числа N.function Factorial(N: Byte): Longint; begin if N in [0..1] then Factorial:= 1 else Factorial:= N * Factorial(N - 1) end; 44. Строки в Паскале – это данные типа string. Они используются для хранения последовательностей символов. В Паскале длина стандартной строки ограничена 255 символами. Под каждый символ отводится по одному байту, в котором хранится код символа. Кроме того, каждая строка содержит еще дополнительный байт, в котором хранится длина строки.
Если заранее известно, что длина строки будет меньше 255 символов, то программист может сам задать максимальную длину строки.
Примеры описания строк:
type str_type = string [12]; const n = 50; var s1: string; s2, s3: str_type; s4: string [n]; s5, s6, s7: string [7];… Длина строки хранится в первом ее байте, индекс которого равен 0. Объявление типизированной константы для типа string осуществляется так:
const s: string = 'FreePascal'… Существует понятие пустой строки, т.е. строки, которая не имеет элементов. Пустая строка обозначается двумя рядом стоящими апострофами (например, st:='').
Операции над строками
Строки можно присваивать друг другу. Если максимальная длина переменной слева меньше длины присваиваемой строки, то лишние символы справа отбрасываются.
…s1:= 'this is text';s2:= s1;… Строки можно объединять с помощью операции конкатенации, которая обозначается знаком +.
…s1:= 'John';s2:= 'Black';s1:= s1 + ' ' + s2;… Строки можно сравнивать друг с другом с помощью операций отношения. При сравнении строки рассматриваются посимвольно слева направо, при этом сравниваются коды соответствующих пар символов. Строки равны, если они имеют одинаковую длину и посимвольно эквивалентны. В строках разной длины существующий символ всегда больше соответствующего ему отсутствующего символа. Меньшей будет та строка, у которой меньше код первого несовпадающего символа (вне зависимости от максимальных и текущих длин сравниваемых строк).
'abc' > 'ab' (true)'abc' = 'abc' (true)'abc' < 'abc ' (false) Имя строки может использоваться в процедурах ввода-вывода. При вводе в строку считывается из входного потока количество символов, равное длине строки или меньшее, если символ перевода строки (который вводится нажатием клавиши Enter) встретится раньше. При выводе под строку отводится количество позиций, равное ее фактической длине.
…readln (s1); write (s1);… К отдельному символу строки можно обращаться как к элементу массива символов, например s1[3]. Символ строки совместим с типом char, их можно использовать в выражениях одновременно, например:
…s1[3]:= 'h'; writeln (s2[3] + 'r');… Можно осуществлять коррекцию любого символа строковой переменной, для чего в соответствующем операторе достаточно указать имя переменной типа string, вслед за которым в квадратных скобках задается номер ее элемента (например,str[3]:='j').
Элементы строки нумеруются с единицы, т.к. в каждой строковой переменной имеется элемент с номером 0, в котором в виде символа хранится длина текущей строки. Чтобы узнать текущую длину, достаточно применить функцию ord к нулевому элементу строки. Например:
…writeln(ord(st[0]))… Нулевой элемент строковой переменной можно корректировать. При этом будет изменяться текущая длина строки. Например, выражение str[0]:=#50устанавливает текущую длину равной 50.
Строки в Паскале – это данные типа string. Они используются для хранения последовательностей символов. В Паскале длина стандартной строки ограничена 255 символами. Под каждый символ отводится по одному байту, в котором хранится код символа. Кроме того, каждая строка содержит еще дополнительный байт, в котором хранится длина строки.
Если заранее известно, что длина строки будет меньше 255 символов, то программист может сам задать максимальную длину строки.
Примеры описания строк:
type str_type = string [12]; const n = 50; var s1: string; s2, s3: str_type; s4: string [n]; s5, s6, s7: string [7];… Длина строки хранится в первом ее байте, индекс которого равен 0. Объявление типизированной константы для типа string осуществляется так:
const s: string = 'FreePascal'… Существует понятие пустой строки, т.е. строки, которая не имеет элементов. Пустая строка обозначается двумя рядом стоящими апострофами (например, st:='').
Операции над строками
Строки можно присваивать друг другу. Если максимальная длина переменной слева меньше длины присваиваемой строки, то лишние символы справа отбрасываются.
…s1:= 'this is text';s2:= s1;… Строки можно объединять с помощью операции конкатенации, которая обозначается знаком +.
…s1:= 'John';s2:= 'Black';s1:= s1 + ' ' + s2;… Строки можно сравнивать друг с другом с помощью операций отношения. При сравнении строки рассматриваются посимвольно слева направо, при этом сравниваются коды соответствующих пар символов. Строки равны, если они имеют одинаковую длину и посимвольно эквивалентны. В строках разной длины существующий символ всегда больше соответствующего ему отсутствующего символа. Меньшей будет та строка, у которой меньше код первого несовпадающего символа (вне зависимости от максимальных и текущих длин сравниваемых строк).
'abc' > 'ab' (true)'abc' = 'abc' (true)'abc' < 'abc ' (false) Имя строки может использоваться в процедурах ввода-вывода. При вводе в строку считывается из входного потока количество символов, равное длине строки или меньшее, если символ перевода строки (который вводится нажатием клавиши Enter) встретится раньше. При выводе под строку отводится количество позиций, равное ее фактической длине.
…readln (s1); write (s1);… К отдельному символу строки можно обращаться как к элементу массива символов, например s1[3]. Символ строки совместим с типом char, их можно использовать в выражениях одновременно, например:
…s1[3]:= 'h'; writeln (s2[3] + 'r');… Можно осуществлять коррекцию любого символа строковой переменной, для чего в соответствующем операторе достаточно указать имя переменной типа string, вслед за которым в квадратных скобках задается номер ее элемента (например,str[3]:='j').
Элементы строки нумеруются с единицы, т.к. в каждой строковой переменной имеется элемент с номером 0, в котором в виде символа хранится длина текущей строки. Чтобы узнать текущую длину, достаточно применить функцию ord к нулевому элементу строки. Например:
…writeln(ord(st[0]))… Нулевой элемент строковой переменной можно корректировать. При этом будет изменяться текущая длина строки. Например, выражение str[0]:=#50устанавливает текущую длину равной 50.
45. 1. Структуры
Структура - это именованная совокупность переменных возможно разных типов, расположенная в памяти последовательно друг за другом. Структуры называются пользовательскими типами данных и помогают в организации сложных данных, поскольку позволяют группу связанных между собой переменных трактовать не как множество отдельных элементов, а как единое целое.
Традиционный пример структуры - строка платежной ведомости. Она содержит такие сведения о служащем, как его полное имя, адрес, номер карточки социального страхования, зарплата и т. д. Некоторые из этих характеристик сами могут быть структурами: например, полное имя состоит из нескольких компонент (фамилии, имени и отчества); аналогично адрес, и даже зарплата. Другой пример (более типичный для Си) - из области графики: точка есть пара координат, прямоугольник есть пара точек и т. д.
Главные изменения, внесенные стандартом ANSI в отношении структур, - это введение для них операции присваивания. Структуры могут копироваться, над ними могут выполняться операции присваивания, их можно передавать функциям в качестве аргументов, а функции могут возвращать их в качестве результата. В большинстве компиляторов уже давно реализованы эти возможности, но теперь они точно оговорены стандартом. Для допускается инициализация.
Основные сведения о структурах
Объявление структуры начинается с ключевого слова struct и содержит
|