Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Мансуров. Основы программирования в среде Lazarus. 2010

.pdf
Скачиваний:
45
Добавлен:
27.04.2021
Размер:
6.3 Mб
Скачать

Глава 3 Более сложные элементы языка

____________________________________________________________________

Таким образом, одноименные глобальные и локальные переменные - это разные переменные. Любое обращение к таким переменным в теле подпро-

граммы трактуется как обращение к локальным переменным, т. е. глобальные переменные в этом случае попросту недоступны.

Пример использования функции.

Вычислить значение y sin x путем разложения sin x в ряд Тейлора с точ-

ностью 10 3 , x [0,1], x 0.1 Вычисление оформить в виде функции.

Вычисленное значение sin x для каждого x сравнить с "точным" значением пу-

тем применения стандартной функции Паскаля sin(x).

Напомню, что мы уже писали эту программу (см. 2.1.26), но без примене-

ния функций. Разложение sin x в ряд Тейлора имеет вид:

 

x3

 

x5

x7

sin x x

 

 

 

 

 

....

3!

5!

 

7!

 

 

 

Функцию, которая

вычисляет sinx по данному ряду, назовем

No_standard_sin(x).

program sinus_fun; {$mode objfpc}{$H+} uses

CRT, FileUtil;

var

x, y, y1, dx:real;// глобальные переменные, доступны функции

function No_standard_sin (x: real): real; var

eps, s, t: real; // локальные переменные, недоступны

n: integer;

// вызывающей программе

begin

 

s:= x;

 

t:= x;

 

151

3.1 Общая структура Паскаль – программы

____________________________________________________________________

n:= 2; eps:= 1e-7; repeat

t:= -t * sqr(x)/(n * (n + 1)); s:= s + t;

n:= n + 2;

until abs(t) < eps;

No_standard_sin:= s; // возврат значения функции

//Result:= s; // можно и так end;

begin x:= 0;

dx:= 0.2;

writeln(UTF8ToConsole('Значения синуса')); writeln(UTF8ToConsole('моя функции, стандартная функции')); while x <= 1 do

begin

y:= No_standard_sin(x);// вызов моей функции y1:= sin(x); // вызов стандартной функции writeln(' ', y:0:7,' ', y1:0:7); x:= x + dx;

end;

writeln(UTF8ToConsole('Нажмите любую клавишу')); readkey;

end.

Пример.

Вспомним пример из 2.2.2. вычисления интеграла по формуле Симпсона.

Перепишем программу, причем оформим вычисление подынтегральной функ-

152

Глава 3 Более сложные элементы языка

____________________________________________________________________

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

program integral; {$mode objfpc}{$H+} uses

CRT, FileUtil; var

a, b, eps: real;

function Fx(x: real): real; // Подынтегральная функция

{Если потребуется вычислить интеграл для другой функции,

достаточно поменять только один оператор}

begin

Fx:= sin(x); // Для другой функции меняем здесь

end;

{ Процедура вычисления интеграла по формуле Симпсона методом двойного пересчета}

procedure Simpson(a, b, eps: real); var

x, h, s, s1: real; n, k: integer;

begin

k:= 0; // при первом вычислении интеграла k=0

n:= 4; // начальное число точек разбиения интервала (a,b) h:= (b - a)/n; // шаг вычисления подынтегральной функции while true do

begin x:= a;

153

3.1 Общая структура Паскаль – программы

____________________________________________________________________

x:= x + h; s:= 0;

while x < (b-h) do begin

s:= s + Fx(x) + 2 * Fx(x + h); x:= x + 2 * h;

end;

s:= 2 * s;

s:= (h/3) * (Fx(a) + 2 * Fx(b) + s); if k = 0

then begin

k:= 1; s1:= s; h:= h/2; continue;

end else

if abs(s1 - s) > eps then begin

s1:= s; h:= h/2; continue;

end else

break;

end;

writeln(UTF8ToConsole('Значение интеграла s= '), s:0:4);

end; // конец процедуры

154

Глава 3 Более сложные элементы языка

____________________________________________________________________

begin // начало основной программы

{задаем интервал на котором вычисляется интеграл}

a:= 0;

b:= pi/4;

eps:= 1e-5; // заданная точность вычисления интеграла

Simpson(a, b, eps); // вызов процедуры вычисления интеграла writeln(UTF8ToConsole('Нажмите любую клавишу'));

readkey;

end.

3.1.1.4 Способы передачи параметров

Передача параметров по значению

При таком способе передачи параметров в функцию или процедуру пере-

дается копия переменной. Внутри функции или процедуры можно менять зна-

чения переданных параметров, однако в вызывающей программе значения па-

раметров остаются неизменными.

Рассмотрим пример:

program parameters; {$mode objfpc}{$H+} uses

CRT, FileUtil; var

x, y: real; n: integer;

{Объявление процедуры с параметром}

procedure example(x, y: real; n: integer);

begin

x:= 1.5;

155

3.1 Общая структура Паскаль – программы

____________________________________________________________________

y:= 2.8; n:= 10;

end; begin

x:= 1; y:= 1; n:= 1;

writeln('x= ', x:0:2, ' y= ', y:0:2, ' n= ', n); example(x, y, n);

writeln('x= ', x:0:2, ' y= ', y:0:2, ' n= ', n);

writeln(UTF8ToConsole('Нажмите любую клавишу'));

readkey;

end.

Как видите, после вызова процедуры значения переменных x, y, n не изменились.

В предыдущих двух примерах мы использовали передачу параметров по значению.

Передача параметров по ссылке

Другая ситуация при передаче параметров по ссылке. В этом случае изме-

нение параметра внутри функции (процедуры) влечет за собой и изменение значения переменной в вызывающей программе. Для передачи параметра по ссылке нужно перед именем параметра в заголовке указать ключевое слово var. Рассмотрим предыдущий пример, но передадим параметры x и n по ссыл-

ке.

program parameters;

{$mode objfpc}{$H+}

uses

156

Глава 3 Более сложные элементы языка

____________________________________________________________________

CRT, FileUtil;

var

x, y: real;

n: integer;

{Объявление процедуры с параметром}

procedure example(var x: real; y: real; var n: integer); begin

x:= 1.5; y:= 2.8; n:= 10;

end; begin

x:= 1; y:= 1; n:= 1;

writeln('x= ', x:0:2, ' y= ', y:0:2, ' n= ', n); example(x, y, n);

writeln('x= ', x:0:2, ' y= ', y:0:2, ' n= ', n);

writeln(UTF8ToConsole('Нажмите любую клавишу'));

readkey;

end.

Здесь уже значения переменных x и n изменились!

Передача параметров-констант

Если при передаче параметров по значению внутри функции (процедуры)

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

157

3.1 Общая структура Паскаль – программы

____________________________________________________________________

менения компилятор выдаст ошибку. Для передачи параметра как константы нужно перед именем параметра задать ключевое слово const.

program parameters; {$mode objfpc}{$H+} uses

CRT, FileUtil; var

x, y: real; n: integer;

{Объявление процедуры с параметром}

procedure example(var x: real; y: real;

const n: integer);

begin

x:= 1.5;

y:= 2.8;

{Попытка изменить параметр-константу}

//n:= 10; // здесь, если убрать комментарий, компилятор укажет на ошибку end;

begin x:= 1; y:= 1; n:= 1;

writeln('x= ', x:0:2, ' y= ', y:0:2, ' n= ', n); example(x, y, n);

writeln('x= ', x:0:2, ' y= ', y:0:2, ' n= ', n);

writeln(UTF8ToConsole('Нажмите любую клавишу'));

readkey;

end.

158

Глава 3 Более сложные элементы языка

____________________________________________________________________

3.1.1.5 Процедуры завершения

Для досрочного завершения функции или процедуры, а также основной программы применяются специальные процедуры exit и halt. Если exit

выполняется в функции (процедуре), то ее выполнение немедленно прекраща-

ется, даже если не все операторы были выполнены и управление передается вы-

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

дующий за вызовом этой функции (процедуры) оператор. Если exit выполня-

ется в основной программе, то работа программы завершается и управление пе-

редается операционной системе.

Процедура halt сразу завершает работу программы и передает управле-

ние операционной системе. Чаще всего halt используют для аварийного за-

вершения программы.

3.2. Еще раз о типах данных

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

причем язык предусматривает создание пользовательских типов данных. Здесь мы дадим классификацию типов данных в Паскале и рассмотрим некоторые из них.

3.2.1 Классификация типов данных

Все типы в Паскале подразделяются на стандартные и пользовательские типы. Пользовательские типы создаются на основе стандартных. При описании пользовательских типов используется ключевое слово type.

159

3.2 Еще раз о типах данных

____________________________________________________________________

К стандартным типам относятся:

целый;

вещественный;

символьный;

логический.

Кроме того, все типы можно разделить на категории:

простые;

строковые;

даты и времени;

структурированные;

указатели;

объекты;

классы;

варианты.

Простые типы, в свою очередь, делятся на порядковые и вещественные.

Порядковый тип характеризуется тем, что каждому его значению можно поста-

вить в соответствие целое число – его порядковый номер в совокупности зна-

чений. Например, для целого типа само значение числа является его порядко-

вым номером. Для логического типа значению true соответствует 1, а значе-

нию false соответствует 0.

3.2.1.1 Целый тип

Кроме уже знакомого нам типа integer, в Паскале имеются и другие це-

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

ристики целочисленных типов данных (напоминаю, что мы рассматриваем язык применительно к компилятору Free Pascal).

160