Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
L03.doc
Скачиваний:
7
Добавлен:
12.07.2019
Размер:
212.48 Кб
Скачать

Лекция 3

<Раздел объявления типов > :: =

type // Признак начала раздела объявления типов

<Имя Типа 1> = <Спецификация Типа 1> ;

<Имя Типа 2> = <Спецификация Типа 2> ;

. . .

Пример.

type

MyInt = integer;

MyDouble = double;

<Раздел объявления типизированных констант> :: =

const // Признак начала раздела объявления констант

<Имя константы 1> : <Тип 1> = < Константное выражение 1> ;

<Имя константы 2> : <Тип 2> = < Константное выражение 2> ;

. . .

Пример:

const

n: longint = 2000000000;

EulerGamma: double = 0.5772156649015329;

pi_half: double = pi / 2.0; pi_quarter: double = pi_half / 2.0;

Замечание. В Turbo Pascal 7.0 «типизированная константа» на деле константой не является: в тексте программы эту «константу» можно изменять. «Типизированная константа» – это, в действительности, инициализированная переменная.

Замечание. Типизированная константа не может участвовать в константном выражении.

Замечание. В Delphi типизированные константы, в отличие от констант без типа, могут принимать значения массивов, записей, процедур, указателей.

Если действует ключ компиляции {$J-} (явно или по умолчанию), значения, принятые типизированными константами при объявлении, не могут быть изменены. Напротив, ключ {$J+} дает типизированным константам возможность изменяться по ходу исполнения программы.

Замечание. В языке «C++» инициализированные переменные объявляются так:

<Тип 1>

<Имя 1> = <Константное выражение 1>,

<Имя 2> = <Константное выражение 2>,

. . .

<Имя N> = <Константное выражение N>;

<Тип 2>

<Имя N+1> = <Константное выражение N+1>,

. . .

Примеры.

int I = 2, J = –5, K = 888;

double x = 1.0, y = –2.2, z = 0.123;

char c = ‘Q’;

Цикл с постусловием

repeat <Операторы> until <Л.В.>

<Операторы> являются телом цикла.

Тело цикла выполняется по меньшей мере один раз, а затем, возможно, многократно, пока < Л.В.> есть ложь.

Если < Л.В.> есть истина при первой же оценке, то тело цикла выполняется один раз.

Если < Л.В.> есть ложь при каждой оценке, то тело цикла выполняется неограниченно много раз.

В случае, если тело цикла содержит несколько операторов, нет необходимости использовать операторные скобки. Слово repeat заменяет собой begin, тогда как слово until заменяет собой end.

Замечание. В языке «C++» родственная конструкция имеет вид:

do <Оператор> while (<Л.В.>)

«Полностью» аналогичная конструкция имеет вид:

do <Оператор> while (! <Л.В.>)

Знак логической инверсии «!» необходим, если истинность <Л.В.> должна приводить к прекращению цикла.

Замечание по теме «циклы»

Инструкция break применяется для досрочного прекращения цикла. Равноценна оператору “goto Metka1”, для которого “Metka1:” расположена сразу после оператора цикла.

Инструкция continue применяется для досрочного перехода на очередную проверку условия продолжения цикла.

Равноценна оператору “goto Metka2”, для которого “Metka2:” расположена сразу после последнего из операторов, составляющих тело цикла.

Инструкции break и continue в Паскале заимствованы из языка «C++».

Процедуры

<Объявление процедуры> :: =

procedure <Имя процедуры>[(<Список формальных параметров)];

<Разделы объявления локальных типов, констант, переменных>

<Разделы объявления локальных процедур и функций>

begin

} Раздел исполнения (тело) процедуры

<Операторы>

end;

<Список формальных параметров> :: =

<Элемент списка 1>; <Элемент списка 2>; . . .

<Элемент списка> :: =

<Список имён параметров-значений>: <Тип>

или

var <Список имён параметров-переменных>: <Тип>

или

const <Список имён параметров-констант>: <Тип>

<Обращение к процедуре> :: =

<Имя процедуры>[(<Список фактических параметров>)]

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

Параметр-значение сам процедуре не передаётся. Передаётся лишь его «численная» (или иная, согласно типу параметра) копия, под которую выделяется дополнительное место в оперативной памяти. Это важно иметь в виду, особенно, если параметр занимает много места в памяти.

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

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

Параметр-переменная именно сам передаётся процедуре. Изменения, произошедшие с таким параметром, сохраняются и по окончании работы процедуры.

Параметр-константа также сам передаётся процедуре. Изменения такого параметра в теле процедуры запрещены.

Пример.

program Example2;

type

MyInt = integer ;

var

I : MyInt ;

J: integer ;

procedure P2(var M: integer);

begin

. . .

end;

begin

P2(J) ; // Нормально

P2(I) ; // Ошибка. Несоответствие типов

end.

Пример.

program Example3;

var

I, J, K : integer ;

procedure P3(L : integer ; var M : integer ; const N : integer);

begin

Inc(L) ; // Бесполезно

Inc(M) ; // Полезно

(* Inc(N) ; *) // Ошибка

end;

begin

I := 1; J := 1; K := 1;

P3(I, J, K) ;

wri teln(‘I=’, I) ; // I = 1, переменная не изменилась

wri teln(‘J=’, J) ; // J = 2, переменная изменилась

end.

Замечание. В языке «C++» процедур нет. Роль процедур исполняют функции, возвращающие значение void (пусто).

<Объявление функции void> :: =

void <Имя функции>([<Список формальных параметров>])

{

} Раздел исполнения (тело) функции

<Операторы>

}

<Список формальных параметров> :: =

<Элемент списка 1>; <Элемент списка 2>; . . .

<Элемент списка> :: =

<Тип> <Имя параметра-значения>

или

const <Тип> <Имя параметра-значения>

Пример.

#include <vcl.h>

#include <stdio.h>

#include <conio.h>

#pragma hdrstop

int

I, J, K, Q;

void P3(int L; int *M; const int N; const int *P)

{

L++ ; // Бесполезно

*M++ ; // Полезно

// N++ ; // Ошибка

// *P++ ; // Ошибка

// P++ ; // Ошибка

}

int main(int argc, char* argv[])

{

I = 1; J = 1; K = 1; Q = 1;

P3(I, &J, K, &Q) ;

printf(“I=%d”, I) ; // I = 1, переменная не изменилась

printf (“J=%d”, J) ; // J = 2, переменная изменилась

{

Функции

<Объявление функции> :: =

function <Имя функции>(<Список формальных параметров>) :

<Тип возвращаемого значения>;

<Разделы объявления локальных типов, констант, переменных>

<Разделы объявления локальных процедур и функций>

begin

} Раздел исполнения функции

<Операторы>

end;

Среди <Операторов> должен быть хотя бы один «Оператор» вида

<Имя функции> := <Выражение> ;

или

result := <Выражение> ;

Пример.

program Example4;

var

x, y, Eps : Double ;

function BesselI0(x, Eps : Double) : Double ;

var

S, A, B, R: Double ;

begin

. . .

BesselI0 := S ;

end;

begin

writeln(‘x=? ’) ; readln(x);

writeln(‘Eps=? ’) ; readln(Eps);

y := BesselI0(x, Eps) ; writeln(‘y=’, y) ;

end.

,

Условия прекращения цикла суммирования: и

S0 = 0

A0 = 1

S1 = S0 + A1

A1 = A0*B1

B1 = (x/2)2/12

S2 = S1 + A2

A2 = A1*B2

B2 = (x/2)2/22

. . .

. . .

. . .

Si = Si-1 + Ai

Ai = Ai-1* Bi

Bi = (x/2)2/i2

Текст программы на языке Free Pascal, TP7:

program BesselI0 ; // Необязательная строка

var

x,y: Double;

function BesselI0(x, Eps : Double): Double;

var

I, N: integer;

S, A, B, R, x2: Double;

begin

S := 0 ;

x2 := sqr(x/2) ;

A := x2 ;

N := 0 ;

B := x2 / (N + 2) / (N + 2) ;

repeat

inc(N);

A := A * B ;

B := x2 / (N + 2 ) / (N + 2) ;

R := A / (1 - B) ;

until ( B < 1) and ( R < Eps ) ;

S := 1;

A := 1;

S0 = 0

A0 = 1

S1 = S0 + A1

A1 = A0*B1

B1 = (x/2)2/12

S2 = S1 + A2

A2 = A1*B2

B2 = (x/2)2/22

. . .

. . .

. . .

Si = Si-1 + Ai

Ai = Ai-1* Bi

Bi = (x/2)2/i2

for I := 1 to N do

begin

B := x2 / I / I;

A := A * B;

S := S + A;

end;

BesselI0 := S ;

end ;

begin

writeln(‘Введите x’) ; readln(x) ;

writeln(‘Введите Eps’) ; readln(Eps) ;

if (Eps <= 0) or (Eps >= 1) then exit ;

writeln(‘f=’, BesselI(x, Eps));

readln;

end.

Тип «Перечисляемый»

<Перечисляемый тип> : : =

(<Список имён значений>)

Первому из элементов <Списка имён значений> придаётся внутренний (недоступный пользователю) номер 0, второму – номер 1, и т.д.

Переменные типа «Перечисляемый»

Примеры

var

v1: (LeftDyrecton, RightDyrecton, BackDyrecton);

type

MyType2=(Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday);

MyType4=(MyTrue, MyFalse);

var

MyVar2: MyType2;

MyVar3: boolean;

MyVar4: MyType4;

begin

for MyVar2 :=Monday to Friday do writeln(MyVar2); // Ошибка

for MyVar4 :=MyFalse to MyTrue do writeln(MyVar4); // Ошибка

for MyVar3 := False to True do writeln(MyVar3); // Выход: True False

end.

Замечание. boolean ≠ (False, True). Вообще говоря.

Замечание. Тип «Перечисляемый – порядковый тип.

Диапазон

<Диапазон> : : =

<Целое число 1> . . <Целое число 2>

Естественное требование:

<Целое число 1> не более, чем <Целое число 2>

Примеры.

1 . . 5

First . . Third

// Если выше по тексту было что-то наподобие:

// const First = 0; Third = 2;

Тип «Диапазон»

type <Имя типа> = <Диапазон> ;

Пример.

type MyType01 = –3 . . 72 ;

Переменные типа «Диапазон»

Примеры:

var

v1: 22 . . 44 ;

v2: MyType01 ;

const

v3: MyType01 = 6 ;

const

MyConst11 = 1; MyConst12 = 7;

type

MyType02 = MyConst11 .. MyConst12;

var

MyVar02: MyType02;

Замечание. Тип–Диапазон – порядковый тип.

Массивы

Все типы переменных, изученные до сих пор – скалярные (простые) типы.

Массив – вектор, матрица, ...

Массив – упорядоченная совокупность данных одного типа.

Массив – переменная с индексом (со списком индексов).

<Объявление одномерного массива> : : =

<Имя переменной> : array[<Диапазон>] of <Тип элемента> ;

<Объявление нескольких многомерных массивов> : : =

<Список имён > : array[<Список диапазонов>] of <Тип элемента> ;

или

<Список имён > : <Тип-массив> ;

<Тип-массив> : : =

array[<Список диапазонов>] of <Тип элемента > ;

<Обращение к элементу массива> : : =

<имя массива> [ <Список значений индексов> ]

Пример

const

MyConst21 = 1; MyConst22 = 8;

type

MyRange1 = 1 . . 7;

MyRange2 = MyConst21 . . MyConst22;

var

A: array[1 . . 4] of integer;

A1, A2, A3: array[1 . . 4, -1 . . 7] of double;

A4: array[MyRange1] of double;

A5: array[MyRange1, MyRange2] of double;

begin

A[3] := 99;

A1[2, 6] := 5.3;

A2[1][7] := 4.1e-10;

A3[5, 0] := 2;

end.

Пример. Заполнить матрицу числами, составляющими треугольник Паскаля.

, . , .

const

n=16;

type

MyArrayType = array[0 . . n , 0 . . n] of integer;

. . .

procedure PT(var mG: MyArrayType);

// procedure PT(var mG: array[0 . . n , 0 . . n] of integer);

var

m, k: integer;

begin

for m := 0 to n do for k := 0 to n do mG[m, k] := 0;

mG[0, 0] := 1;

for m := 1 to n do

begin

mG[m, 0] := 1; mG[m, m] := 1;

for k := 1 to m-1 do mG[m, k] := mG[m-1, k] + mG[m-1, k-1];

end;

end;

. . .

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]