│
Deutsch (de) │
English (en) │
suomi (fi) │
français (fr) │
русский (ru) │
A word is the processor’s native data unit.
Modern consumer processors have a word width of 64 bits.
Data type
Most run-time libraries provide the native data type of a processor as the Pascal data type word
.
It is a subset of all whole numbers (non-negative integers) that can be represented by the processor’s natural data unit size.
On a 64-bit architecture this means a word
is an integer within the range [math]displaystyle{ [0,~2^{64}-1] }[/math].
On a 32-bit architecture a word
will be an integer in the range [math]displaystyle{ [0,~2^{32}-1] }[/math], and so on, respectively.
In GNU Pascal a word
is just an alias for cardinal
, which has the same properties regarding possible values.
If a signed integer having the processor’s native size is wanted, the data type integer
provides this functionality.
FPC
For source compatibility reasons, FPC defines word
in the same way as Turbo Pascal and Delphi: the subrange data type 0..65535
.
The high
value 65535
is [math]displaystyle{ 2^{16}-1 }[/math].
Thus a system.word
occupies two bytes of space.
Subrange data types are stored in a quantity that serves best the goals of performance and memory efficiency.
The processor’s native word size, as defined above, corresponds to different types depending on the purpose you want to use it for:
- the (as of 2022 still undocumented)
system.ALUSint
andsystem.ALUUint
types correspond to the native word size used by the processor’s ALU (arithmetic and logical unit), as defined at the beginning of this page. In general, this type should not be used in high level code. Instead, choose a data type based on the values it should be able to represent, as this is safer and more portable. It is the compiler’s job to generate optimal code. system.CodePtrUInt
corresponds to the size of pointers to code, such as the address of a procedure. This can be different from a pointer to data, e. g. on targets that support multiple memory models.system.PtrUInt
corresponds to the size of pointers to data.
On many platforms, all of these types have the same size, but it is not the case everywhere.
In FPC a smallInt
has the same size as a word
, but is signed.
simple data types |
|
---|---|
complex data types |
|
При описании переменной необходимо указать ее тип. Тип переменной описывает набор значений, которые она может принимать, и действия, которые могут быть над ней выполнены. Описание типа определяет идентификатор, который обозначает тип.
Простые типы делятся на стандартные (порядковые) и перечисляемые (ограниченные).
Стандартные типы
Турбо-Паскаль имеет четыре встроенных стандартных типа: integer (целое), real (вещественное), boolean (логический) и char (символьный).
Целочисленный тип (integer)
В Турбо-Паскале имеется пять встроенных целочисленных типов: shortint (короткое целое), integer (целое), longint (длинное целое), byte (длиной в байт) и word (длиной в слово). Каждый тип обозначает определенное подмножество целых чисел, как это показано в следующей Таблице.
Встроенные целочисленные типы.
Тип |
Диапазон |
Формат |
shortint |
-128 ..+127 |
8 битов со знаком |
integer |
-32768 .. 32767 |
16 битов со знаком |
longint |
-2147483648 +2147483647 |
32 бита со знаком |
byte |
0 .. 255 |
8 битов без знака |
word |
0 .. 65535 |
16 битов без знака |
Арифметические действия над операндами целочисленного типа осуществляются в соответствии со следующими правилами:
- Тип целой константы представляет собой встроенный целочисленный тип с наименьшим диапазоном, включающим значение этой целой константы.
- В случае бинарной операции (операции, использующей два операнда), оба операнда преобразуются к их общему типу перед тем, как над ними совершается действие. Общим типом является встроенный целочисленный тип с наименьшим диапазоном, включающим все возможные значения обоих типов. Например, общим типом для целого и целого длиной в байт является целое, а общим типом для целого и целого длиной в слово является длинное целое. Действие выполняется в соответствии с точностью общего типа и типом результата является общий тип.
- Выражение справа в операторе присваивания вычисляется независимо от размера переменной слева.
Операции совершаемые над целыми числами:
“+” — сложение
“-“ — вычитание
“*” — умножение
SQR — возведение в квадрат
DIV — после деления отбрасывает дробную часть
MOD — получение целого остатка после деления
ABS — модуль числа
RANDOM(X)-получение случайного числа от 0 до Х
Пример:
а:=100; b:=60; a DIV b результат - 1 а MOD b результат - 40
Описываются переменные целого типа следующим образом:
var список переменных: тип;
Например: var а,р,n:integer;
Вещественный тип(real)
К вещественному типу относится подмножество вещественных чисел, которые могут быть представлены в формате с плавающей запятой с фиксированным числом цифр. Запись значения в формате с плавающей запятой обычно включает три значения — m, b и e — таким образом, что m*bе, где b всегда равен 10, а m и e являются целочисленными значениями в диапазоне вещественного типа. Эти значения m и e далее определяют диапазон и точность вещественного типа.
Имеется пять видов вещественных типов: real, singlе, duble, exnende, comp. Вещественные типы различаются диапазоном и точностью связанных с ними значений
Диапазон и десятичные цифры для вещественных типов
Тип |
Диапазон |
Цифры |
Real Single Duble Extende comp |
2.9×10Е-39 до 1.7×10Е 38 1.5×10Е-45 до 3.4×10Е 38 5.0×10Е-324 до 1.7×10Е 308 3.4×10Е-493 до 1.1×10Е 403 -2Е 63 до 2Е 63 |
от 11 до 12 от 7 до 8 от 15 до 16 от 19 до 20 от 19 до 20 |
Операции совершаемые над вещественными числами:
- Все операции допустимые для целых чисел.
- SQRT(x)-корень квадратный из числа х.
- SIN(X), COS(X), ARCTAN(X).
- LN(X)-натуральный логарифм.
- EXP(X)-экспонента Х (ех).
- EXP(X*LN(A))-возведение в степень (Ах).
- Функции преобразования типов:
- TRUNC(X)-отбрасывает дробную часть;
- ROUND(X)-округление.
- Некоторые правила арифметических операций:
- Если в арифметическом действии встречаются числа типа real и integer, то результат будет иметь тип real.
- Все составные части выражения записываются в одну строку.
- Используются только круглые скобки.
- Нельзя подряд ставить два арифметических знака.
Описываются переменные вещественного типа следующим образом:
var список переменных: тип;
Например:
var d,g,k:real;
Символьный тип(char)
K типу char относится любой символ заключенный в апострофы. Для представления апострофа как символьную переменную, надо заключить его в апостроф:’’’’.
Каждый символ имеет свой код и номер. Порядковые номера цифр 0,1..9 упорядочены по возрастанию. Порядковые номера букв также упорядочены по возрастанию, но не обязательно следуют друг за другом.
К символьным данным применимы знаки сравнения:
> , < , >=, <=, <> .
Например: ‘A’ < ‘W’
Функции, которые применимы к символьным переменным:
- ORD(X) — определяет порядковый номер символа Х.
Пример:
ord(‘a’)=97;
- CHR(X) — определяет символ по номеру.
Пример:
chr(97)=’a’;
- PRED(X) — выдает символ, стоящий перед символом Х.
Пример:
pred(‘B’)=’A’;
- SUCC(X) — выдает символ, следующий после символа Х.
Пример:
succ(‘A’)=’B’;
Перечислимый тип
Перечислимый тип данных назван так потому, что задается в виде перечисления констант в строго определенном порядке и в строго определенном количестве. Перечислимый тип состоит из списка констант. Переменные этого типа могут принимать значение любой из этих констант. Описание перечислимого типа имеет вид:
Type <имя типа>=(список констант); Var <имя переменной>:<имя типа>;
где <список констант> — это особый вид констант, задаваемых через запятую и имеющих свой порядковый номер, начиная с 0.
Например:
type направление=(север, юг, запад, восток); месяц=(июнь,июль,август,январь); емкость=(ведро,бочка,канистра,бак); var поворот:направление; отъезд:месяц; объем:емкость;
или так:
var поворот:(свер, юг, запад, восток); отъезд:(июнь, июль, август, январь); объем:(ведро, бочка, канистра, бак);
Можно выполнить такие операторы присваивания:
поворот:=юг; отъезд:=август; объем:=бак;
но нельзя выполнять смешанные присваивания:
отъезд:=юг; объем:=август;
К переменным перечислимого типа применимы следующие функции:
1. ORD — порядковый номер
2. PRED — предшествующий элемент
3. SUCC — последующий элемент.
Пример:
PRED(бочка)=ведро; SUCC(юг)=запад; ORD(июль)=1;
Переменные перечислимого типа можно сравнить, так как они упорядочены и пронумерованы. Так выражения: север < юг, июнь < январь имеют значения TRUE, а юг>запад и бак<бочка значение FАLSE.
Ограниченный тип
Если переменная принимает не все значения своего типа, а только в некотором диапазоне, то ее можно рассматривать как переменную ограниченного типа. Каждый ограниченный тип задается путем накладывания ограничения на базовые типы.
Описывается так:
TYPE <имя типа>=константа1..константа2
При этом должны выполняться следующие правила:
- Обе ограниченные константы должны быть одного типа.
- В качестве базового типа можно использовать любой простой тип, кроме действительного(real).
- Начальные значение при определении ограниченного типа не должно быть больше конечного значения.
Пример:
type index=0..63; letter=’a’..’z’; var char1,char2:letter; a,g:index;
Можно описывать сразу в разделе описания переменных:
var a,g:0..63; char1,char2:’a’..’z’.
Data types of an entity indicates the meaning, constraints, possible values, operations, functions and mode of storage associated with it.
Integer, real, Boolean and character types are referred as standard data types. Data types can be categorized as scalar, pointer and structured data types. Examples of scalar data types are integer, real, Boolean, character, subrange and enumerated. Structured data types are made of the scalar types; for example, arrays, records, files and sets. We will discuss the pointer data types later.
Pascal Data Types
Pascal data types can be summarized as below in the following diagram −
Type Declarations
The type declaration is used to declare the data type of an identifier. Syntax of type declaration is −
type-identifier-1, type-identfier-2 = type-specifier;
For example, the following declaration defines the variables days and age as integer type, yes and true as Boolean type, name and city as string type, fees and expenses as real type.
type days, age = integer; yes, true = boolean; name, city = string; fees, expenses = real;
Integer Types
Following table gives you details about standard integer types with its storage sizes and value ranges used in Object Pascal −
Type | Minimum | Maximum | Format |
---|---|---|---|
Integer | -2147483648 | 2147483647 | signed 32-bit |
Cardinal | 0 | 4294967295 | unsigned 32-bit |
Shortint | -128 | 127 | signed 8-bit |
Smallint | -32768 | 32767 | signed 16-bit |
Longint | -2147483648 | 2147483647 | signed 32-bit |
Int64 | -2^63 | 2^63 — 1 | signed 64-bit |
Byte | 0 | 255 | unsigned 8-bit |
Word | 0 | 65535 | unsigned 16-bit |
Longword | 0 | 4294967295 | unsigned 32-bit |
Constants
Use of constants makes a program more readable and helps to keep special quantities at one place in the beginning of the program. Pascal allows numerical, logical, string and character constants. Constants can be declared in the declaration part of the program by specifying the const declaration.
Syntax of constant type declaration is follows −
const Identifier = contant_value;
Following are some examples of constant declarations −
VELOCITY_LIGHT = 3.0E=10; PIE = 3.141592; NAME = 'Stuart Little'; CHOICE = yes; OPERATOR = '+';
All constant declarations must be given before the variable declaration.
Enumerated types
Enumerated data types are user-defined data types. They allow values to be specified in a list. Only assignment operators and relational operators are permitted on enumerated data type. Enumerated data types can be declared as follows −
type enum-identifier = (item1, item2, item3, ... )
Following are some examples of enumerated type declarations −
type SUMMER = (April, May, June, July, September); COLORS = (Red, Green, Blue, Yellow, Magenta, Cyan, Black, White); TRANSPORT = (Bus, Train, Airplane, Ship);
The order in which the items are listed in the domain of an enumerated type defines the order of the items. For example, in the enumerated type SUMMER, April comes before May, May comes before June, and so on. The domain of enumerated type identifiers cannot consist of numeric or character constants.
Subrange Types
Subrange types allow a variable to assume values that lie within a certain range. For example, if the age of voters should lie between 18 to 100 years, a variable named age could be declared as −
var age: 18 ... 100;
We will look at variable declaration in detail in the next section. You can also define a subrange type using the type declaration. Syntax for declaring a subrange type is as follows −
type subrange-identifier = lower-limit ... upper-limit;
Following are some examples of subrange type declarations −
const P = 18; Q = 90; type Number = 1 ... 100; Value = P ... Q;
Subrange types can be created from a subset of an already defined enumerated type, For example −
type months = (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec); Summer = Apr ... Aug; Winter = Oct ... Dec;
При описании переменной необходимо указать ее тип. Тип переменной описывает набор значений, которые она может принимать, и действия, которые могут быть над ней выполнены. Описание типа определяет идентификатор, который обозначает тип. В программе описание переменной задается следующим образом:
var список переменных: тип;
Простые типы делятся на стандартные (порядковые) и перечисляемые (ограниченные).
Стандартные типы
Язык Pascal имеет четыре встроенных стандартных типа:
- integer (целочисленный)
- real (вещественный)
- boolean (логический)
- char (символьный)
1.Целочисленный тип (integer).
В Pascal имеются следующие целочисленные типы:
- shortint (короткое целое)
- integer (целое)
- longint (длинное целое)
- byte (число длиной в байт)
- word (число длиной в слово)
Каждый тип обозначает определенное подмножество целых чисел, как это показано в следующей таблице.
Тип данных | Диапазон | Количество байт |
---|---|---|
shortint | -128 ..+127 | 1 |
integer | -32768 .. 32767 | 2 |
longint | -2147483648 +2147483647 | 4 |
byte | 0 .. 255 | 1 |
word | 0 .. 65535 | 4 |
Описываются переменные целого типа следующим образом:
Арифметические действия над операндами целочисленного типа осуществляются в соответствии со следующими правилами:
- Тип целой константы представляет собой встроенный целочисленный тип с наименьшим диапазоном, включающим значение этой целой константы.
- В случае бинарной операции (операции, использующей два операнда), оба операнда преобразуются к их общему типу перед тем, как над ними совершается действие. Общим типом является встроенный целочисленный тип с наименьшим диапазоном, включающим все возможные значения обоих типов. Например, общим типом для целого и целого длиной в байт является целое, а общим типом для целого и целого длиной в слово является длинное целое. Действие выполняется в соответствии с точностью общего типа и типом результата является общий тип.
- Выражение справа в операторе присваивания вычисляется независимо от размера переменной слева.
Операция | Описание |
---|---|
+ | сложение |
— | вычитание |
* | умножение |
/ | деление |
div | после деления отбрасывает дробную часть |
mod | получение целого остатка после деления |
В Pascal есть операции целочисленного деления и нахождения остатка от деления. При выполнении целочисленного деления (операция div) остаток от деления отбрасывается.
//Например 15 div 3 = 5; 18 div 5 = 3; 123 div 10 = 12; 7 div 10 = 0;
С помощью операции mod можно найти остаток от деления одного целого числа на другое.
//Например 15 mod 3 = 0; 18 mod 5 = 3; 123 mod 10 = 3; 7 mod 10 = 7;
//Например а:=100; b:=60; c:=a div b; d:=a mod b;
результат: переменная c равна 1, а d равна 40.
При записи алгебраических выражений используют арифметические операции (сложение, умножение, вычитание, деление), функции Pascal, круглые скобки.
Порядок действий при вычислении значения выражения:
- вычисляются значения в скобках;
- вычисляются значения функций;
- выполняется унарные операции (унарный минус — смена знака);
- выполняются операции умножения и деления (в том числе целочисленного деления и нахождения остатка от деления);
- выполняются операции сложения и вычитания.
Встроенные математические функции языка Pascal
Математическая запись | Запись на Pascal | Назначение |
---|---|---|
cos x | cos(x) | Косинус x радиан |
sin x | sin(x) | Синус x радиан |
ex | exp(x) | Значение e в степени x |
[x] | trunc(x) | Целая часть числа x |
|x| | abs(x) | Модуль числа x |
x2 | sqr(x) | Квадрат числа x |
sqrt(x) | Квадратный корень из x | |
{x} | frac(x) | Дробная часть x |
arctg x | arctan(x) | Арктангенс числа x |
ln x | ln(x) | Натуральный логарифм x |
p | Pi | Число p |
Возведение в степень (кроме возведения в квадрат и возведения в степень числа e) отсутствует. Для возведения в произвольную степень можно воспользоваться очевидным равенством: xy=ey ln x. Для возведения числа в натуральную степень можно написать собственную функцию. Например,
{Функция возведения вещественного числа X в натуральную степень N} Function Stepen(X : Real; N : Integer) : Real; Var I:Integer; St:Real; Begin St := 1; For I := 1 To N Do St := St * X; Stepen := St; End;
Другой способ получить натуральное значение z=xy, где x, y — натуральные, это сделать так: Z := Round(Exp(Y * Ln(X))).
Примечание. Интересной является задача получения степени любого целого числа (за исключением нуля), если основание степени — неотрицательное целое, без использования развилки. Одно из возможных решений :
(–1)*ord(odd(y)) * exp(y * ln(x)) + ord(odd(y+1)) * yxp(Y * ln(x))
Здесь Ord(K) — функция, возвращающая порядковый номер величины K в том или ином порядковом типе (в примере использовано свойство, что порядковый номер False равен 0, а порядковый номер True — 1).
2. Вещественный тип (real).
К вещественному типу относится подмножество вещественных чисел, которые могут быть представлены в формате с плавающей запятой с фиксированным числом цифр. Запись значения в формате с плавающей запятой обычно включает три значения — m, b и e — таким образом, что m*bе, где b всегда равен 10, а m и e являются целочисленными значениями в диапазоне вещественного типа. Эти значения m и e далее определяют диапазон и точность вещественного типа.
Имеется следующие виды вещественных типов: real, singlе, double, extended,comp. Вещественные типы различаются диапазоном и точностью связанных с ними значений. Тип comp может содержать только целые числа от -2 63 +1 до +263-1, но эти числа хранятся в вещественном формате, поэтому тип comp считается вещественным. С данными типа Comp можно обращаться так же, как с данными других вещественных типов, но дробная часть числа при этом автоматически отбрасывается.
Диапазон и десятичные цифры для вещественных типов
Тип | Диапазон | Точность | Количество байт |
Real | 2.9×10Е-39 до 1.7×10Е 38 | 11-12 | 6 |
Single | 1.5×10Е-45 до 3.4×10Е 38 | 7-8 | 4 |
Double | 5.0×10Е-324 до 1.7×10Е 308 | 15-16 | 8 |
Extended | 3.4×10Е-4932 до 1.1×10Е 4932 | 19-20 | 10 |
Comp | -9.2E-18 до 9.2E18 | 19-20 | 8 |
Операции совершаемые над вещественными числами:
- Все операции допустимые для целых чисел.
- SQRT(x)-корень квадратный из числа х.
- Тригонометрические функции:
- SIN(X);
- COS(X);
- ARCTAN(X).
- LN(X)-натуральный логарифм.
- EXP(X)-экспонента Х (ех).
- EXP(X*LN(A))-возведение в степень (Ах).
- Функции преобразования типов:
- TRUNC(X)-отбрасывает дробную часть
- ROUND(X)-округление.
Некоторые правила арифметических операций:
- Если в арифметическом действии встречаются числа типа real и integer, то результат будет иметь тип real.
- Все составные части выражения записываются в одну строку.
- Используются только круглые скобки.
- Нельзя подряд ставить два арифметических знака.
Описываются переменные вещественного типа следующим образом:
var список переменных: тип;
Например:
3. Символьный тип(char)
K типу char относится любой символ заключенный в апострофы. Для представления апострофа как символьную переменную, надо заключить его в апостроф:».
Каждый символ имеет свой код и номер. Порядковые номера цифр 0,1..9 упорядочены по возрастанию. Порядковые номера букв также упорядочены по возрастанию, но не обязательно следуют друг за другом.
К символьным данным применимы знаки сравнения:
> , < , >=, <=, <> . Например: 'A' < 'W'
Функции, которые применимы к символьным переменным:
- ord(x) — определяет порядковый номер символа x.
- chr(x) — определяет символ по номеру.
- pred(x) — выдает символ, стоящий перед символом x.
- succ(x) — выдает символ, следующий после символа x.
Перечислимые типы
4. Перечислимый тип.
Перечислимый тип данных назван так потому, что задается в виде перечисления констант в строго определенном порядке и в строго определенном количестве. Перечислимый тип состоит из списка констант. Переменные этого типа могут принимать значение любой из этих констант. Описание перечислимого типа имеет вид:
Type имя типа=(список констант); Var имя переменной:имя типа;
где <список констант> — это особый вид констант, задаваемых через запятую и имеющих свой порядковый номер, начиная с 0.
Например:
type направление=(север, юг, запад, восток); месяц=(июнь,июль,август,январь); емкость=(ведро,бочка,канистра,бак); var поворот:направление; отъезд:месяц; объем:емкость;
или так:
var поворот:(свер, юг, запад, восток); отъезд:(июнь, июль, август, январь); объем:(ведро, бочка, канистра, бак);
Можно выполнить такие операторы присваивания:
поворот:=юг; отъезд:=август; объем:=бак;
но нельзя выполнять смешанные присваивания:
отъезд:=юг; объем:=август;
К переменным перечислимого типа применимы следующие функции:
1. ord — порядковый номер
2. pred — предшествующий элемент
3. succ — последующий элемент.
Пример: pred(бочка)=ведро; succ(юг)=запад; ord(июль)=1;
Переменные перечислимого типа можно сравнить, так как они упорядочены и пронумерованы. Так выражения:
север < юг, июнь < январь имеют значения TRUE, а юг>запад и бак<бочка значение FАLSE.
5. Ограниченный тип.
Если переменная принимает не все значения своего типа, а только в некотором диапазоне, то ее можно рассматривать как переменную ограниченного типа. Каждый ограниченный тип задается путем накладывания ограничения на базовые типы.
Описывается так:
type <имя типа>=константа1..константа2
При этом должны выполняться следующие правила:
- Обе ограниченные константы должны быть одного типа.
- В качестве базового типа можно использовать любой простой тип, кроме действительного(real).
- Начальные значение при определении ограниченного типа не должно быть больше конечного значения.
Пример:
type index=0..63; letter='a'..'z'; var char1,char2:letter; a,g:index;
Можно описывать сразу в разделе описания переменных:
var a,g:0..63; char1,char2:'a'..'z';
Глава 4. Типы данных
— 4.1. Простые типы
— 4.1.1. Порядковые типы
— 4.1.2. Вещественные типы
— 4.2. Структурированные типы
— 4.2.1. Массивы
— 4.2.2. Записи
— 4.2.3. Множества
— 4.3. Строки
— 4.4. Совместимость и преобразование типов
ТИПЫ ДАННЫХ
Любые данные, т.е. константы, переменные, значения функций или выражения, в Турбо Паскале характеризуются своими типами. Тип определяет множество допустимых значений, которые может иметь тот или иной объект, а также множество допустимых операций, которые применимы к нему. Кроме того, тип определяет также и формат внутреннего представления данных в памяти ПК.
Турбо Паскаль характеризуется разветвленной структурой типов данных (рис.4.1).
Рис.4.1. Структура типов данных
В Турбо Паскале предусмотрен механизм создания новых типов данных, благодаря чему общее количество типов, используемых в программе, может быть сколь угодно большим.
В этой главе приводится подробное описание всех типов, за исключением файлов и указателей, которые рассматриваются в следующих двух главах, а также процедурных типов, которые рассматриваются в гл.8, и объектов (гл.10).
4.1. ПРОСТЫЕ ТИПЫ
К простым типам относятся порядковые и вещественные типы. Порядковые типы отличаются тем, что каждый из них имеет конечное число возможных значений. Эти значения можно определенным образом упорядочить (отсюда -название типов) и, следовательно, с каждым из них можно сопоставить некоторое целое число — порядковый номер значения.
Вещественные типы, строго говоря, тоже имеют конечное число значений, которое определяется форматом внутреннего представления вещественного числа. Однако количество возможных значений вещественных типов настолько велико, что сопоставить с каждым из них целое число (его номер) не представляется возможным.
4.1.1. Порядковые типы
К порядковым типам относятся (см. рис.4.1) целые, логический, символьный, перечисляемый и тип-диапазон. К любому из них применима функция ORD(X), которая возвращает порядковый номер значения выражения X. Для целых типов функция ORD(X) возвращает само значение X, т.е. ORD(X) = X для X, принадлежащего любому шелому типу. Применение ORD(X) к логическому, символьному и перечисляемому типам дает положительное целое число в диапазоне от 0 до 1 (логический тип), от 0 до 155 (символьный), от 0 до 65535 (перечисляемый). Тип-диапазон сохраняет все свойства базового порядкового типа, поэтому результат применения к нему функции ORD(X) зависит от свойств этого типа.
К порядковым типам можно также применять функции:
PRED (X) — возвращает предыдущее значение порядкового типа (значение, которое соответствует порядковому номеру ORD(X)- 1), т.е.
ORD(PRED(X)) = ORD(X) — 1;
SUCC (X) — возвращает следующее значение порядкового типа, которое соответствует порядковому номеру ORD(X) +1, т.е.
ORD(SUCC(X)) = ORD(X) + 1.
Например, если в программе определена переменная
var
с : Char;
begin
с := ‘5’ ;
end.
то функция PRED(C) вернет значение ‘4’, а функция SUCC(C) — значение ‘6’.
Если представить себе любой порядковый тип как упорядоченное множество значий, возрастающих слева направо и занимающих на числовой оси некоторый отрезок, то функция PRED(X) не определена для левого, a SUCC(X) — для правого конца этого отрезка.
Целые типы. Диапазон возможных значений целых типов зависит от их внутреннего представления, которое может занимать один, два или четыре байта. В табл. 4.1 приводится название целых типов, длина их внутреннего представления в байтах и диапазон возможных значений.
Таблица 4.1
Целые типы |
---|
Название | Длина, байт | Диапазон значений |
---|---|---|
Byte | 1 | 0. . .255 |
ShortInt | 1 | -128. . .+127 |
Word | 2 | 0. . .65535 |
Integer | 2 | -32768.. .+32767 |
LongInt | 4 | -2 147 483 648… +2 147 483 647 |
При использовании процедур и функций с целочисленными параметрами следует руководствоваться «вложенностью» типов, т.е. везде, где может использоваться WORD, допускается использование BYTE (но не наоборот), в LONGINT «входит» INTEGER, который, в свою очередь, включает в себя SHORTINT.
Перечень процедур и функций, применимых к целочисленным типам, приведен в табл.4.2. Буквами b, s, w, i, l обозначены выражения соответственно типа BYTE, SHORTINT, WORD, INTEGER и LONGINT, x — выражение любого из этих типов; буквы vb, vs, vw, vi, vl, vx обозначают переменные соответствующих типов. В квадратных скобках указывается необязательный параметр.
Таблица 4.2
Стандартные процедуры и функции, применимые к целым типам |
---|
Обращение | Тип результата | Действие |
---|---|---|
abs (x) | x | Возвращает модуль х |
chr(b) | Char | Возвращает символ по его коду |
dec (vx[, i] ) | — | Уменьшает значение vx на i, а при отсутствии i -на 1 |
inc(vx[, i] ) | — | Увеличивает значение vx на i, а при отсутствии i — на 1 |
Hi(i) | Byte | Возвращает старший байт аргумента |
Hi(w) | To же | То же |
Lo(i) | « | Возвращает младший байт аргумента |
Lo (w) | « | То же |
odd(l) | Boolean | Возвращает True, если аргумент — нечетное число |
Random (w) | Как у параметра | Возвращает псевдослучайное число, равномерно распределенное в диапазоне 0…(w-l) |
sgr (x) | X | Возвращает квадрат аргумента |
swap (i) | Integer | Меняет местами байты в слове |
swap (w) | Word |
При действиях с целыми числами тип результата будет соответствовать типу операндов, а если операнды относятся к различным целым типам, — типу того операнда, который имеет максимальную мощность (максимальный диапазон значений). Возможное переполнение результата никак не контролируется, что может привести к недоразумениям, например:
var
а : Integer;
х, у : Real;
begin
а := 32767; {Максимально возможное значение типа INTEGER}
х := а + 2; {Переполнение при вычислении этого выражения!}
у := LongInt(а)+2; {Переполнения нет после приведения переменной к более мощному типу}
WriteLn(x:10:0, у:10:0)
end.
В результате прогона программы получим
-32767 32769
Логический тип. Значениями логического типа может быть одна из предварительно объявленных констант FALSE (ложь) или TRUE (истина). Для них справедливы правила:
ord(False) = 0;
ord(True) = 1;
False < True;
succ(False)= True;
pred(True) = False.
Поскольку логический тип относится к порядковым типам, его можно использовать в операторе счетного типа, например:
var
1 : Boolean;
begin
for 1 := False to True do ….
Символьный тип. Значением символьного типа является множество всех символов ПК. Каждому символу приписывается целое число в диапазоне 0…255. Это число служит кодом внутреннего представления символа, его возвращает функция ORD.
Для кодировки используется код ASCII (American Standard Code for Information Interchange — американский стандартный код для обмена информацией). Это 7-битный код, т.е. с его помощью можно закодировать лишь 128 символов в диапазоне от 0 до 127. В то же время в 8-битном байте, отведенном для хранения символа в Турбо Паскале, можно закодировать в два раза больше символов в диапазоне от 0 до 255. Первая половина символов ПК с кодами 0…127 соответствует стандарту ASCII (табл. 4.3). Вторая половина символов с кодами 128…255 не ограничена жесткими рамками стандарта и может меняться на ПК разных типов (в прил.2 приведены некоторые распространенные варианты кодировки этих символов).
Таблица 4.3
Кодировка символов в соответствии со стандартом ASCII |
---|
Код | Символ | Код | Символ | Код | Символ | Код | Символ |
---|---|---|---|---|---|---|---|
0 | NUL | 32 | BL | 64 | ® | 96 | ‘ |
1 | ЗОН | 33 | ! | 65 | A | 97 | a |
2 | STX | 34 | « | 66 | B | 98 | b |
3 | ЕТХ | 35 | # | 67 | C | 99 | c |
4 | EOT | 36 | $ | 68 | D | 100 | d |
5 | ENQ | 37 | % | 69 | E | 101 | e |
6 | АСК | 38 | & | 70 | F | 102 | f |
7 | BEL | 39 | ‘ | 71 | G | 103 | g |
8 | BS | 40 | ( | 72 | H | 104 | h |
9 | НТ | 41 | ) | 73 | I | 105 | i |
10 | LF | 42 | * | 74 | J | 106 | j |
11 | VT | 43 | + | 75 | K | 107 | k |
12 | FF | 44 | , | 76 | L | 108 | l |
13 | CR | 45 | — | 77 | M | 109 | m |
14 | SO | 46 | . | 78 | N | 110 | n |
15 | SI | 47 | / | 79 | O | 111 | o |
16 | DEL | 48 | 0 | 80 | P | 112 | p |
17 | DC1 | 49 | 1 | 81 | Q | 113 | q |
18 | DC2 | 50 | 2 | 82 | R | 114 | r |
19 | DC3 | 51 | 3 | 83 | S | 115 | s |
20 | DC4 | 52 | 4 | 84 | T | 116 | t |
21 | NAK | 53 | 5 | 85 | U | 117 | u |
22 | SYN | 54 | 6 | 86 | V | 118 | v |
23 | ETB | 55 | 7 | 87 | W | 119 | w |
24 | CAN | 56 | 8 | 88 | X | 120 | x |
25 | EM | 57 | 9 | 89 | Y | 121 | y |
26 | SUB | 58 | : | 90 | Z | 122 | z |
27 | ESC | 59 | / | 91 | [ | 123 | { |
28 | FS | 60 | < | 92 | 124 | | | |
29 | GS | 61 | = | 93 | ] | 125 | } |
30 | RS | 62 | > | 94 | ^ | 126 | ~ |
31 | US | 63 | ? | 95 | — | 127 | п |
Символы с кодами 0…31 относятся к служебным кодам. Если эти коды используются в символьном тексте программы, они считаются пробелами. При использовании их в операциях ввода-вывода они могут иметь следующее самостоятельное значение:
Символ | Код | Значение |
---|---|---|
BEL | 7 | Звонок; вывод на экран этого символа сопровождается звуковым сигналом |
НТ | 9 | Горизонтальная табуляция; при выводе на экран смещает курсор в позицию, кратную 8, плюс 1 (9, 17, 25 и т.д.) |
LF | 10 | Перевод строки; при выводе его на экран все последующие символы будут выводиться, начиная с той же позиции, но на следующей строке |
VT | 11 | Вертикальная табуляция; при выводе на экран заменяется специальным знаком |
FF | 12 | Прогон страницы; при выводе на принтер формирует страницу, при выводе на экран заменяется специальным знаком |
CR | 13 | Возврат каретки; вводится нажатием на клавишу Enter (при вводе с помощью READ или READLN означает команду «Ввод» и в буфер ввода не помещается; при выводе означает команду «Продолжить вывод с начала текущей строки») |
SUB | 26 | Конец файла; вводится с клавиатуры нажатием Ctrl-Z; при выводе заменяется специальным знаком |
SSC | 27 | Конец работы; вводится с клавиатуры нажатием на клавишу ESC; при выводе заменяется специальным знаком |
К типу CHAR применимы операции отношения, а также встроенные функции: СНR(В) — функция типа CHAR; преобразует выражение В типа BYTE в символ и возвращает его своим значением;
UPCASE(CH) — функция типа CHAR; возвращает прописную букву, если СН -строчная латинская буква, в противном случае возвращает сам символ СН, например:
var
cl,c2: Char;
begin
cl := UpCase(‘s’) ;
c2 := UpCase (‘Ф’) ;
WriteLn(cl,’ ‘,c2)
end.
Так как функция UPCASE не обрабатывает кириллицу, в результате прогона этой
программы на экран будет выдано
S ф
Перечисляемый тип. Перечисляемый тип задается перечислением тех значений, которые он может получать. Каждое значение именуется некоторым идентификатором и располагается в списке, обрамленном круглыми скобками, например:
typе
colors =(red, white, blue);
Применение перечисляемых типов делает программы нагляднее. Если, например, в программе используются данные, связанные с месяцами года, то такой фрагмент программы:
type
ТипМесяц=(янв,фев,мар,апр,май,июн,июл,авг,сен,окт,ноя,дек);
var
месяц : ТипМесяц;
begin
…….
if месяц = авг then WriteLn(‘Хорошо бы поехать к морю!’);
…….
end.
был бы, согласитесь, очень наглядным. Увы! В Турбо Паскале нельзя использовать кириллицу в идентификаторах, поэтому мы вынуждены писать так:
type
TypeMonth=(jan,feb,mar,may,jun,jul,aug,sep,oct,nov,dec);
var
month: TypeMonth;
begin
…….
if month = aug then WriteLn(‘Хорошо бы поехать к морю!’);
…….
end.
Соответствие между значениями перечисляемого типа и порядковыми номерами этих значений устанавливается порядком перечисления: первое значение в списке получает порядковый номер 0, второе — 1 и т.д. Максимальная мощность перечисляемого типа составляет 65536 значений, поэтому фактически перечисляемый тип задает некоторое подмножество целого типа WORD и может рассматриваться как компактное объявление сразу группы целочисленных констант со значениями О, 1 и т.д.
Использование перечисляемых типов повышает надежность программ благодаря возможности контроля тех значений, которые получают соответствующие переменные. Пусть, например, заданы такие перечисляемые типы:
type
colors = (black, red, white);
ordenal= (one, two, three);
days = (monday, tuesday, Wednesday);
С точки зрения мощности и внутреннего представления все три типа эквивалентны:
ord(black)=0, …, ord(white)=2,
ord(one)=0, …ord(three)=2,
ord(monday)=0, …ord(Wednesday)=2.
Однако, если определены переменные
var
col :colors; num :ordenal;
day : days;
то допустимы операторы
col := black;
num := succ(two);
day := pred(tuesday);
но недопустимы
col := one;
day := black;
Как уже упоминалось, между значениями перечисляемого типа и множеством целых чисел существует однозначное соответствие, задаваемое функцией ORD(X). В Турбо Паскале допускается и обратное преобразование: любое выражение типа WORD можно преобразовать в значение перечисляемого типа, если только значение целочисленного выражения не превышает мощное1™ перечисляемого типа. Такое преобразование достигается применением автоматически объявляемой функции с именем перечисляемого типа (см. п. 4.4). Например, для рассмотренного выше объявления типов эквивалентны следующие присваивания:
col := one;
col := colors(0);
Разумеется, присваивание
col := 0;
будет недопустимым.
Переменные любого перечисляемого типа можно объявлять без предварительного описания этого типа, например:
var
col: (black, white, green);
Тип-диапазон. Тип-диапазон есть подмножество своего базового типа, в качестве которого может выступать любой порядковый тип, кроме типа-диапазона. Тип-диапазон задается границами своих значений внутри базового типа:
<мин.знач.>..<макс.знач.>
Здесь <мин.знач. > — минимальное значение типа-диапазона;
<макс.знач.> — максимальное его значение.
Например:
type
digit = ‘0’..’9′;
dig2= 48..57;
Тип-диапазон необязательно описывать в разделе TYPE, а можно указывать непосредственно при объявлении переменной, например:
var
date : 1..31;
month: 1. .12;
Ichr : ‘A’..’Z’;.
При определении типа-диапазона нужно руководствоваться следующими правилами:
два символа «..» рассматриваются как один символ, поэтому между ними недопустимы пробелы;
левая граница диапазона не должна превышать его правую границу. Тип-диапазон наследует все свойства своего базового типа, но с ограничениями, связанными с его меньшей мощностью. В частности, если определена переменная
type
days = (mo,tu,we,th,fr,sa,su);
WeekEnd = sa .. su;
var
w : WeekEnd;
begin
…..
w := sa;
…..
end;
то ORD(W) вернет значение 5 , в то время как PRED(W) приведет к ошибке.
В стандартную библиотеку Турбо Паскаля включены две функции, поддерживающие работу с типами-диапазонами:
НIGН(Х) — возвращает максимальное значение типа-диапазона, к которому принадлежит переменная X;
LOW(X) -возвращает минимальное значение типа-диапазона.
Следующая короткая программа выведет на экран строку
-32768…32767
var
k: Integer;
begin
WriteLn(Low(k),’..’,High(k))
end.
4.1.2. Вещественные типы
В отличие от порядковых типов, значения которых всегда сопоставляются с рядом целых чисел и, следовательно, представляются в ПК абсолютно точно, значения вещественных типов определяют произвольное число лишь с некоторой конечной точностью, зависящей от внутреннего формата вещественного числа.
Таблица 4.4
Длина, байт | Название | Количество значащих цифр | Диапазон десятичного порядка |
---|---|---|---|
6 | Real | 11. . .12 | -39. ..+38 |
8 | Double | 15. ..16 | -324. . .+308 |
10 | extended | 19. . .20 | -4951. . .+4932 |
5 | comp | 19. . .20 | -2*1063+1. . .+2*63-1 |
Как видно из табл.7, вещественное число в Турбо Паскале занимает от 4 до 10 смежных байт и имеет следующую структуру в памяти ПК:
s | e | m |
---|
Здесь s — знаковый разряд числа; е — экспоненциальная часть; содержит двоичный порядок; m — мантисса числа.
Мантисса m имеет длину от 23 (для SINGLE) до 63 (для EXTENDED) двоичных разрядов, что и обеспечивает точность 7.. .8 для SINGLE и 19.. .20 для EXTENDED десятичных цифр. Десятичная точка (запятая) подразумевается перед левым (старшим) разрядом мантиссы, но при действиях с числом ее положение сдвигается влево или вправо в соответствии с двоичным порядком числа, хранящимся в экспоненциальной части, поэтому действия над вещественными числами называют арифметикой с плавающей точкой (запятой).
Как видим, Турбо Паскаль характеризуется богатой гаммой вещественных типов, однако доступ к типам SINGLE, DOUBLE и EXTENDED возможен только при особых режимах компиляции. Дело в том, что эти типы рассчитаны на аппаратную поддержку арифметики с плавающей точкой и для их эффективного использования в состав ПК должен входить арифметический сопроцессор. Компилятор Турбо Паскаля позволяет создавать программы, работающие на любых ПК (с сопроцессором или без него) и использующие любые вещественные типы. Необходимая для этого настройка компилятора описана в прил.1. В процессе запуска Турбо Паскаль проверяет состав аппаратных средств и выявляет наличие или отсутствие сопроцессора.
В некоторых случаях бывает необходимо отключить автоконтроль. Для этого перед запуском Турбо Паскаля следует дать такую команду ДОС:
set 87=N
команда
set 87=Y
напротив, включает автоконтроль — эта команда активна по умолчанию.
Отметим, что арифметический сопроцессор всегда обрабатывает числа в формате EXTENDED, а три других вещественных типа в этом случае получаются простым усечением результатов до нужных размеров и применяются в основном для экономии памяти.
Например, если «машинное эпсилон» (см. пример 2.6 в гл.2) вычисляется с помощью такой программы:
{$N+,E+}
type
RealType = Real:
var
epsilon : RealType;
begin
epsilon := 1;
while 1+epsilon/2 > 1 do
epsilon := epsilon/2;
WriteLn(epsilon)
end.
то независимо от объявления типа REALTYPE (он может быть SINGLE, REAL, DOUBLE или EXTENDED) на печать будет выдан результат
1.08420217248550Е-0019
что соответствует типу EXTENDED. Происходит это по той причине, что все операнды вещественного выражения 1 + epsilon/2 в операторе WHILE, перед вычислением автоматически преобразуются к типу EXTENDED. Чтобы получить правильный результат (например, для типа REALTYPE = REAL он будет 9 . 09494701772928Е-0013), программу необходимо изменить следующим образом:
{$N+,E+}
type
RealType= Real;
var
epsilon, epsl:RealType;
begin
epsilon := 1;
repeat
epsilon := epsilon/2;
epsl := 1 + epsilon
until epsl = 1;
WriteLn(2*epsilon)
end.
Следует учесть, что тип REAL оптимизирован для работы без сопроцессора. Если Ваш ПК оснащен сопроцессором, использование типа REAL приведет к дополнительным затратам времени на преобразование REAL к EXTENDED. Поэтому никогда не используйте REAL на ПК с сопроцессором, т.к. дополнительные затраты времени на преобразование типов могут свести на нет все преимущества сопроцессора. При разработке программ, критичных ко времени счета, следует заменять его типами SINGLE или DOUBLE: по сравнению с типом REAL скорость вычислений на машинах с сопроцессором в этом случае увеличивается в 2…3 раза. Если в ПК нет арифметического сопроцессора, скорость обработки данных всех вещественных типов приблизительно одинакова.
Особое положение в Турбо Паскале занимает тип СОМР, который трактуется как вещественное число без экспоненциальной и дробной частей. Фактически, СОМР — это «большое» целое число со знаком, сохраняющее 19…20 значащих десятичных цифр (во внутреннем представлении СОМР занимает 8 смежных байт). В то же время в выражениях СОМР полностью совместим с любыми другими вещественными типами: над ним определены все вещественные операции, он может использоваться как аргумент математических функций и т.д. Наиболее подходящей областью применения типа СОМР являются бухгалтерские расчеты: денежные суммы выражаются в копейках или центах и действия над ними сводятся к операциям с достаточно длинными целыми числами.
Для работы с вещественными данными могут использоваться встроенные математические функции, представленные в табл. 2.5. В этой таблице REAL означает любой вещественный тип, INTEGER — любой целый тип.
Таблица 4.5
Стандартные математические функции Турбо Паскаля |
---|
Обращение | Тип параметра | Тип результата | Примечание |
---|---|---|---|
abs (x) | Real, Integer | Тип аргумента | Модуль аргумента |
АrсТаn (х) | Real | Real | Арктангенс ( значение в радианах) |
cos (х) | To же | То же | Косинус, угол в радианах |
ехр (х) | « | « | Экспонента |
frас (х) | « | « | Дробная часть числа |
int(x) | « | « | Целая часть числа |
ln(x) | « | « | Логарифм натуральный |
Pi | — | « | л = 3.141592653… |
Random | — | « | Псевдослучайное число, равномерно распределенное в диапазоне 0…[1] |
Pandom(x) | Integer | Integer | Псевдослучайное целое число, равномерно распределенное в диапазоне 0…(х-1) |
Randomize | — | — | Инициация генератора псевдослучайных чисел |
sin(x) | Real | Real | Синус, угол в радианах |
sqr (x) | To же | То же | Квадрат аргумента |
sqrt (x) | « | « | Корень квадратный |
4.2. СТРУКТУРИРОВАННЫЕ ТИПЫ
Любой из структурированных типов (а в Турбо Паскале их четыре: массивы, запиcи, множества и файлы) характеризуется множественностью образующих этот тип элементов, т.е. переменная или константа структурированного типа всегда имеет неcколько компонентов. Каждый компонент, в свою очередь, может принадлежать cтруктурированному типу, что позволяет говорить о возможной вложенности типов. В Турбо Паскале допускается произвольная глубина вложенности типов, однако суммарная длина любого из них во внутреннем представлении не должна превышать -5520 байт.
В целях совместимости со стандартным Паскалем в Турбо Паскале разрешается черед описанием структурированного типа ставить зарезервированное слово PACKED, предписывающее компилятору, по возможности, экономить память, отводимую под объекты структурированного типа; но компилятор фактически игнорирует это указание: «упаковка» данных в Турбо Паскале осуществляется автоматически зезде, где это возможно.
4.2.1. Массивы
Массивы в Турбо Паскале во многом схожи с аналогичными типами данных в других языках программирования. Отличительная особенность массивов заключается в том, что все их компоненты суть данные одного типа (возможно, структурированного). Эти компоненты можно легко упорядочить и обеспечить доступ к любому из них простым указанием его порядкового номера, например:
type
digit =array[0..9] of Char ;
matrix =array[Byte] of Single;
var
m : matrix;
d : digit;
i : Integer;
begin
…….
m[17] := ord(d[i-l])/10;
…….
end.
Описание типа массива задается следующим образом:
<имя типа> = ARRAY [ <сп.инд.типов> ] OF <тип>
Здесь <имя типа> — правильный идентификатор;
ARRAY, OF — зарезервированные слова (массив, из);
<сп.тд.типов> — список из одного или нескольких индексных типов, разделенных запятыми; квадратные скобки, обрамляющие список, — требование синтаксиса;
<тип> — любой тип Турбо Паскаля.
В качестве индексных типов в Турбо Паскале можно использовать любые порядковые типы, кроме LONGINT и типов-диапазонов с базовым типом LONGINT.
Определить переменную как массив можно и непосредственно при описании этой переменной, без предварительного описания типа массива, например:
var
а,b : array [1..10] of Real;
Обычно в качестве индексного типа используется тип-диапазон, в котором задаются границы изменения индексов. Так как тип <тип>, идущий за словом OF, — любой тип Турбо Паскаля, то он может быть, в частности, и другим массивом, например:
type
mat = array [0..5] of array [-2..2] of array [Char] of Byte;
Такую запись можно заменить более компактной:
type
mat = array [0..5,-2..2,Char] of Byte;
Глубина вложенности структурированных типов вообще, а следовательно, и массивов — произвольная, поэтому количество элементов в списке индексных типов (размерность массива) не ограничено, однако суммарная длина внутреннего представления любого массива, как уже говорилось, не может быть больше 65520 байт. В памяти ПК элементы массива следуют друг за другом так, что при переходе от младших адресов к старшим наиболее быстро меняется самый правый индекс массива. Если, например,
var
а : array[1. .2,1. .2] of Byte;
begin
a [1,1]:=1;
a [2,1]:=2;
a [l, 2]:=3;
a [2,2]:=4;
end.
то в памяти последовательно друг за другом будут расположены байты со значениями 1,3,2, 4 . Это обстоятельство может оказаться важным при использовании стандартной процедуры копирования памяти MOVE.
В Турбо Паскале можно одним оператором присваивания передать все элементы одного массива другому массиву того же типа, например:
var
а,b:array [1..5] of Single;
begin
…..
a := b;
…..
end.
После этого присваивания все пять элементов массива А получат те же значения, что и в массиве В. Однако над массивами не определены операции отношения. Нельзя, например, записать
if a = b then …
Сравнить два массива можно поэлементно, например:
var
a,b:array [1..5] of Single;
eq:Boolean;
i:Byte;
begin
…..
eq := True; for i := 1 to 5 do
if a[i] <> b[i] then
eq := False;
if eq then
…..
end.
4.2.2. Записи
Запись — это структура данных, состоящая из фиксированного числа компонентов, называемых полями записи. В отличие от массива, компоненты (поля) записи могут быть различного типа. Чтобы можно было ссылаться на тот или иной компонент записи, поля именуются.
Структура объявления типа записи такова:
<имя типа> = RECORD <сп.полей> END
Здесь <имя типа> — правильный идентификатор;
RECORD, END — зарезервированные слова (запись,конец); <сп.полей> — список полей; представляет собой последовательность разделов записи, между которыми ставится точка с запятой.
Каждый раздел записи состоит из одного или нескольких идентификаторов полей, отделяемых друг от друга запятыми. За идентификатором (идентификаторами) ставится двоеточие и описание типа поля (полей), например:
type
BirthDay = record
day,month : Byte;
year : Word
end;
var
a,b : Birthday;
…….
В этом примере тип BIRTHDAY (день рождения) есть запись с полями DAY, MONTH и YEAR (день, месяц и год); переменные А и В содержат записи типа BIRTHDAY.
Как и в массиве, значения переменных типа записи можно присваивать другим переменным того же типа, например
а := b;
К каждому из компонентов записи можно получить доступ, если использовать составное имя, т.е. указать имя переменной, затем точку и имя поля:
а.day := 27;
b.year := 1939;
Для вложенных полей приходится продолжать уточнения:
type
BirthDay = record
day,month: Byte;
year : Word
end;
var
с : record
name : String;
bd : BirthDay
end;
begin
…..
if c.bd.year = 1939 then …
end.
Чтобы упростить доступ к полям записи, используется оператор присоединения WITH:
WITH <переменная> DO <оператор>
Здесь WITH, DO — ключевые слова (с, делать);
<переменная> — имя переменной типа запись, за которым, возможно, следует список вложенных полей; <оператор> — любой оператор Турбо Паскаля.
Например:
with c.bd do month := 9;
Это эквивалентно
with с do with bd do month := 9;
или
with c,bd do month := 9;
или
c.bd.month := 9;
Турбо Паскаль разрешает использовать записи с так называемыми вариантными полями, например:
type
Forma = record
Name: String;
case Byte of
0: (Birthplace: String [40]);
1: (Country : String [20];
EntryPort : String [20];
EntryDate : 1. . 31;
ExitDate : 1..31)
end;
В этом примере тип FORMA определяет запись с одним фиксированным полем NAME и вариантной частью, которая задается предложением CASE… OF. Вариантная часть состоит из нескольких вариантов (в примере — из двух вариантов: 0 и 1). Каждый вариант определяется константой выбора, за которой следует двоеточие и список полей, заключенный в круглые скобки. В любой записи может быть только одна вариантная часть, и, если она есть, она должна располагаться за всеми фиксированными полями.
Замечательной особенностью вариантной части является то обстоятельство, что все заданные в ней варианты «накладываются» друг на друга, т.е. каждому из них выделяется одна и та же область памяти. Это открывает дополнительные возможности преобразования типов, например:
var
mem4 : record case Byte of
0 : (by : array'[0..3] of Byte);
1 : (wo : array [0..1] of Word);
2 : (lo : longint);
end;
В этом примере запись МЕМ4 имеет три варианта, каждый из которых занимает в памяти один и тот же участок из 4 байт. В зависимости от того, к какому полю записи мы обращаемся в программе, этот участок может рассматриваться как массив из 4 байт (поле ВТ), массив из двух целых типа WORD (поле WO) или, наконец, как одно целое число типа LONGINT (поле LO). Например, этой записи можно сначала присвоить значение как длинному целому, а затем проанализировать результат по байтам или словам:
var
х : Word;
xb: Byte;
x1: Longint;
begin
…..
with m do
begin
lo := trunc(2*pi*x);
if wo[1] = 0
then if by[l] = 0 then
xb := x[0]
else
x := wo[0]
else
x1 := lo
end;
…..
end.
Предложение CASE… OF, открывающее вариантную часть, внешне похоже на соответствующий оператор выбора, но на самом деле лишь играет роль своеобразного служебного слова, обозначающего начало вариантной части. Именно поэтому в конце вариантной части не следует ставить END как пару к CASE… OF. (Поскольку вариантная часть — всегда последняя в записи, за ней все же стоит END, но лишь как пара к RECORD). Ключ выбора в предложении CASE… OF фактически игнорируется компилятором: единственное требование, предъявляемое к нему Турбо Паскалем, состоит в том, чтобы ключ определял некоторый стандартный или предварительно объявленный порядковый тип. Причем сам этот тип никак не влияет ни на количество следующих ниже вариантных полей, ни даже на характер констант выбора. В стандартном Паскале в качестве ключа выбора необходимо указывать некоторую переменную порядкового типа, причем в исполняемой части программы можно присваивать значение этой переменной и таким образом влиять на выбор полей. В Турбо Паскале также можно в поле ключа выбора указывать переменную порядкового типа и даже присваивать ей в программе значение, что однако не влияет на выбор поля: значения констант выбора в Турбо Паскале могут быть произвольными, в том числе повторяющимися, например:
type
reel = record
a : Byte;
b : Word;
end;
rec2 = record
с : longint;
case x : Byte of
1 : (d : Word);
2 : (e : record
case Boolean of
3 freel);
3 g Single);
‘3’:( с Word);
end)
end;
var
r : rec2;
begin
r.x := 255;
if r.e.g = 0 then
WriteLn(‘O.K. ‘)
else
WriteLn(r.e.g)
end.
В этом примере предложение
case Boolean of
в записи, определяемой в поле Е, объявляет ключом выбора логический тип, который, как известно, имеет лишь два значения — TRUE и FALSE. Константы же выбора следующих далее вариантов не только содержат совершенно не свойственные этому типу значения, но и две из них повторяются, а общее количество вариантов — три, а не два, как следовало бы ожидать.
Имена полей должны быть уникальными в пределах той записи, где они объявлены, однако, если записи содержат поля-записи, т.е. вложены одна в другую, имена могут повторяться на разных уровнях вложенности (см. поле С в последнем примере).
4.2.3. Множества
Множества — это наборы однотипных логически связанных друг с другом объектов. Характер связей между объектами лишь подразумевается программистом и никак не контролируется Турбо Паскалем. Количество элементов, входящих в множество, может меняться в пределах от 0 до 256 (множество, не содержащее элементов, называется пустым). Именно непостоянством количества своих элементов множества отличаются от массивов и записей.
Два множества считаются эквивалентными тогда и только тогда, когда все их элементы одинаковы, причем порядок следования элементов в множестве безразличен. Если все элементы одного множества входят также и в другое, говорят о включении первого множества во второе. Пустое множество включается в любое другое.
Пример определения и задания множеств:
type
digitChar= set of ‘0’..’9′;
digit = set of 0. .9;
var
sl,s2,s3 :digitChar;
s4,s5,s6 :digit;
begin
…..
s1:=[‘1′,’2′,’3’];
s2:=[‘3′,’2′,’1’];
s3:=[‘2′,’3’];
s4:=[0..3,6];
s5:=[4,5];
s6:=[3..9];
…..
end.
В этом примере множества S1 и S2 эквивалентны, а множество S3 включено в S2 , но не эквивалентно ему.
Описание типа множества имеет вид:
<имя типа> = SET OF <баз.тип>
Здесь <имя типа> — правильный идентификатор;
SET, OF — зарезервированные слова (множество, из);
<баз.тип> — базовый тип элементов множества, в качестве которого может
использоваться любой порядковый тип, кроме WORD, INTEGER, LONGINT.
Для задания множества используется так называемый конструктор множества: список спецификаций элементов множества, отделяемых друг от друга запятыми; список обрамляется квадратными скобками (см. предыдущий пример). Спецификациями элементов могут быть константы или выражения базового типа, а также — тип-диапазон того же базового типа.
Над множествами определены следующие операции:
* пересечение множеств; результат содержит элементы, общие для обоих множеств; например, S4*S6 содержит [3], S4*S5 — пустое множество (см. выше);
+ объединение множеств; результат содержит элементы первого множества, дополненные недостающими элементами из второго множества:
S4+S5 содержит [0,1,2,3,4,5,6];
S5+S6 содержит [3,4,5,6,7,8,9];
— разность множеств; результат содержит элементы из первого множества, которые не принадлежат второму:
S6-S5 содержит [3,6,7,8,9];
S4-S5 содержит [0,1,2,3,6];
= проверка эквивалентности; возвращает TRUE, если оба множества эквивалентны;
<> проверка неэквивалентности; возвращает TRUE, если оба множества неэквивалентны;
<= проверка вхождения; возвращает TRUE, если первое множество включено во второе;
>= проверка вхождения; возвращает TRUE, если второе множество включено в первое;
IN проверка принадлежности; в этой бинарной операции первый элемент — выражение, а второй — множество одного и того же типа; возвращает TRUE , если выражение имеет значение, принадлежащее множеству:
3 in s6 возвращает TRUE;
2*2 in s1 возвращает FALSE.
Дополнительно к этим операциям можно использовать две процедуры. INCLUDE — включает новый элемент во множество. Обращение к процедуре:
INCLUDE (S,I)
Здесь S — множество, состоящее из элементов базового типа TSetBase;
I — элемент типа TSetBase, который необходимо включить во множество.
EXCLUDE — исключает элемент из множества. Обращение:
EXCLUDE(S,I)
Параметры обращения — такие же, как у процедуры INCLUDE.
В отличие от операций + и -, реализующих аналогичные действия над двумя множествами, процедуры оптимизированы для работы с одиночными элементами множеcтва и поэтому отличаются высокой скоростью выполнения.
В примере 4.1, иллюстрирующем приемы работы с множествами, реализуется алгоритм выделения из первой сотни натуральных чисел всех простых чисел. В его основе лежит прием, известный под названием «решето Эратосфена». В соответствии с этим алгоритмом вначале формируется множество BEGINSET, состоящее из всех целых чисел в диапазоне от 2 до N. В множество PRIMERSET (оно будет содержать искомые простые числа) помещается 1. Затем циклически повторяются следующие действия:
взять из BEGINSET первое входящее в него число NEXT и поместить его в PRIMERSET;
удалить из BEGINSET число NEXT и все другие числа, кратные ему, т.е.2*NEXT, 3*NEXT и т.д.
Цикл повторяется до тех пор, пока множество BEGINSET не станет пустым.
Эту программу нельзя использовать для произвольного N, так как в любом множестве не может быть больше 256 элементов.
Пример 4.1
Program Primer_numbers_detect;
{Выделение всех простых чисел из первых N целых}
const
N = 255; {Количество элементов исходного множества}
type
SetOfNumber = set of 1..N;
var
n1,next,i : Word; {Вспомогательные переменные}
BeginSet, {Исходное множество}
PrimerSet : SetOfNumber; {Множество простых чисел} .
begin
BeginSet := [2. .N] ; {Создаем исходное множество}
PrimerSet:= [1]; {Первое простое число}
next:= 2; {Следующее простое число}
while BeginSet <> [] do {Начало основного цикла}
begin
n1 := next;{n1-число,кратное очередному простому (next)}
{Цикл удаления из исходного множества непростых чисел:}
while n1 <= N do
begin
Exclude(BeginSet,nl);
n1 := n1+next {Следующее кратное}
end; {Конец цикла удаления}
Include(PrimerSet,next);
{Получаем следующее простое, которое есть первое невычеркнутое из исходного множества}
repeat
inc(next)
until (next in BeginSet) or (next > N)
end; {Конец основного цикла}
{Выводим результат:}
for i := 1 to N do
if i in PrimerSet then Write(i:8);
WriteLn
END.
Перед тем как закончить рассмотрение множеств полезно провести небольшой эксперимент. Измените описание типа SETOFNUMBER следующим образом:
type
SetOf Number = set of 1. . 1 ;
и еще раз запустите программу из предыдущего примера. На экран будет выведено
1 3 5 7
Множества BeginSet и PrimerSet состоят теперь из одного элемента, а программа сумела поместить в них не менее семи! Секрет этого прост: внутреннее устройство множества таково, что каждому его элементу ставится в соответствие один двоичный разряд (один бит); если элемент включен во множество, соответствующий разряд имеет значение 1, в противном случае — 0. Минимальной единицей памяти является один байт, содержащий 8 бит. Компилятор выделил множествам по одному байту, в результате мощность каждого из них стала равна 8 элементов. Максимальная мощность множества — 256 элементов. Для таких множеств компилятор выделяет по 16 смежных байт.
И еще один эксперимент: измените диапазон базового типа на 1.256. Хотя мощность этого типа составляет 256 элементов, при попытке компиляции программы компилятор сообщит:
Error 23: Set base type out of range.
(Ошибка 23: Базовый тип множества выходит за допустимые границы.)
Компилятор разрешает использовать в качестве базового типа целочисленный тип-диапазон с минимальной границей 0 и максимальной 255 или любой перечисляемый тип не более чем с 256 элементами (максимальная мощность перечисляемого типа -5536 элементов).
4.3. СТРОКИ
Тип STRING (строка) в Турбо Паскале широко используется для обработки текстов. Он во многом похож на одномерный массив символов ARRAY[O..N] OF CHAR, однако, в отличие от последнего, количество символов в строке-переменной может меняться от 0 до N, где N — максимальное количество символов в строке. Значение N определяется объявлением типа STRING [N] и может быть любой константой порядкового типа, но не больше 255 . Турбо Паскаль разрешает не указывать N, в этом случае длина строки принимается максимально возможной, а именно N=255 .
Строка в Турбо Паскале трактуется как цепочка символов. К любому символу в строке можно обратиться точно так же, как к элементу одномерного массива ARRAY [0..N] OF CHAR, например:
var
st : String;
begin
…..
if st[5] = ‘A’ then…
end.
Самый первый байт в строке имеет индекс 0 и содержит текущую длину строки, первый значащий символ строки занимает второй байт и имеет индекс 1. Над длиной троки можно осуществлять необходимые действия и таким способом изменять длину. Например, удалить из строки все ведомые пробелы можно следующим образом:
var
st : String;
i : Byte;
begin
i := ord(st [0] ) ; {i — текущая длина строки}
while (i <> 0) and (st[i] = ‘ ‘) do
begin
dec(i);
st[0] := chr(i)
end;
…..
end.
Значение ORD(st[0]) , т.е. текущую длину строки, можно получить и с помощью функции LENGTH(st), например:
while (Length(st)<>0) and (st[Length(st)]=’ ‘) do
st[0] := chr(Length(st)-1)
К строкам можно применять операцию «+» — сцепление, например:
st := ‘а1 + ‘b’;
st := st + ‘с’; {st содержит «abc»}
Если длина сцепленной строки превысит максимально допустимую длину N, то «лишние» символы отбрасываются. Следующая программа, например, напечатает символ 1:
var
st: String [1] ;
begin
St:=’123′;
WriteLn(st)
end.
Все остальные действия над строками и символами реализуются с помощью описываемых ниже стандартных процедур и функций.
CONCAT(S1 [,S2, … , SN]) — функция типа STRING; возвращает строку, представляющую собой сцепление строк-параметров SI, S2, …, SN.
COPY(ST, INDEX, COUNT) — функция типа STRING; копирует из строки ST COUNT символов, начиная с символа с номером INDEX.
DELETE (ST, INDEX, COUNT) — процедура; удаляет СОUNT символов из строки ST, начиная с символа с номером INDEX.
INSERT (SUBST, ST, INDEX) — процедура; вставляет подстроку SUBST в строку ST, начиная с символа с номером INDEX.
LENGTH (ST) — функция типа INTEGER; возвращает длину строки ST.
POS (SUBST, ST) — функция типа INTEGER; отыскивает в строке STпервое вхождение подстроки SUBST и возвращает номер позиции, с которой она начинается; если подстрока не найдена, возвращается ноль.
STR(X [; WIDTH [: DECIMALS] ], ST) — процедура; преобразует число X любого вещественного или целого типов в строку символов ST так, как это делает процедура WRITELN перед выводом; параметры WIDTH и DECIMALS, если они присутствуют, задают формат преобразования: WIDTH определяет общую ширину поля, выделенного под соответствующее символьное представление вещественного или целого числа X, a DECIMALS — количество символов в дробной части (этот параметр имеет смысл только в том случае, когда Х- вещественное число).
VAL(ST, X, CODE) — процедура; преобразует строку символов ST во внутреннее представление целой или вещественной переменной X, которое определяется типом этой переменной; параметр CODE содержит ноль, если преобразование прошло успешно, и тогда в X помещается результат преобразований, в противном случае он содержит номер позиции в строке ST, где обнаружен ошибочный символ, и в этом случае содержимое Х не меняется; в строке ST могут быть ведущие пробелы, однако ведомые пробелы недопустимы; например, обращение val (‘ 123’,k,i) пройдет успешно: k получит значений 123, в i будет помещен 0, в то время как обращение val (‘ 123 ‘ , k, i) будет ошибочным: значение k не изменится, a i будет содержать 4.
UPCASE (СН) — функция типа CHAR; возвращает для символьного выражения СН, которое должно представлять собой строчную латинскую букву, соответствующую заглавную букву; если значением СН является любой другой символ (в том числе строчная буква русского алфавита), функция возвращает его без преобразования.
Примеры:
var
х : Real;
у : Integer;
st,st1: String;
begin
st := concat(’12’,’345′); {строка st содержит 12345}
st1 := copy(st,3,Length(st)-2); {st1 содержит 345}
insert(‘-‘,st1,2); {строка st1 содержит 3-45}
delete(st,pos(‘2’,at),3); {строка st содержит 15}
str(pi:6:2,st); {строка st содержит 3.14}
val(»3,1415′ ,x,y) ; {у содержит 2, х остался без изменения}
end.
Операции отношения =, о, >, <, >=, <= выполняются над двумя строками посимвольно, слева направо с учетом внутренней кодировки символов (см. табл.4.1 и прил.2). Если одна строка меньше другой по длине, недостающие символы короткой строки заменяются значением СНR(0) .
Следующие операции отношения дадут значение TRUE:
»» < ‘ . ‘
‘А’ > ‘1’
‘Turbo’ <‘ Turbo Pascal’
‘Паскаль’ >’Turbo Pascal’
4.4. СОВМЕСТИМОСТЬ И ПРЕОБРАЗОВАНИЕ ТИПОВ
Как уже неоднократно отмечалось, Турбо Паскаль — это типизированный язык. Он построен на основе строгого соблюдения концепции типов, в соответствии с которой все применяемые в языке операции определены только над операндами совместимых типов. При обсуждении операций над вещественными данными мы уже затрагивали проблему совместимости вещественных и целых типов. Аналогичные проблемы возникают при операциях над строками разной длины, строками и символами и т.д. Ниже приводится более полное определение совместимости типов.
— Два типа считаются совместимыми, если:
— оба они есть один и тот же тип;
— оба вещественные;
— оба целые;
— один тип есть тип-диапазон второго типа;
— оба являются типами-диапазонами одного и того же базового типа;
— оба являются множествами, составленными из элементов одного и того же базового типа;
— оба являются упакованными строками (определены с предшествующим словом PACKED) одинаковой максимальной длины;
— один тип есть тип-строка, а другой — тип-строка, упакованная строка или символ;
— один тип есть любой указатель, а другой — нетипизированный указатель;
— один тип есть указатель на объект, а другой — указатель на родственный ему объект;
— оба есть процедурные типы с одинаковыми типом результата (для типа-функции), количеством параметров и типом взаимно — соответствующих параметров.
Совместимость типов приобретает особое значение в операторах присваивания. Пусть T1 — тип переменной, а Т2 — тип выражения, т.е. выполняется присваивание T1 := T2. Это присваивание возможно в следующих случаях:
— T1 и T2 есть один и тот же тип и этот тип не относится к файлам или массивам файлов, или записям, содержащим поля- файлы, или массивам таких записей;
— T1 и T2 являются совместимыми порядковыми типами и значение T2 лежит в диапазоне возможных значений T1;
— T1 и T2 являются вещественными типами и значение T2 лежит в диапазоне возможных значений T1;
— T1 — вещественный тип и T2 — целый тип; ,
— T1 — строка и T2 — символ;
— T1 — строка и T2 — упакованная строка;
— T1 и T2 — совместимые упакованные строки;
— T1 и T2 — совместимые множества и все члены T2 принадлежат множеству возможных значений T1;
— T1 и T2 — совместимые указатели;
— T1 и T2 — совместимые процедурные типы;
— T1 — объект и T2 — его потомок.
В программе данные одного типа могут преобразовываться в данные другого типа. Такое преобразование может быть явным или неявным.
При явном преобразовании типов используются вызовы специальных функций преобразования, аргументы которых принадлежат одному типу, а значение — другому. Таковыми являются уже рассмотренные функции ORD, TRUNC, ROUND, CHR. В гл. 6 описывается функция PTR, преобразующая четырехбайтный целочисленный аргумент к типу-указателю.
В Турбо Паскале может использоваться и более общий механизм преобразования типов, согласно которому преобразование достигается применением идентификатора имени) стандартного типа или типа, определенного пользователем, как идентификатора функции преобразования к выражению преобразуемого типа (так называемое автоопределенное преобразование типов). Например, допустимы следующие вызовы функций:
type
МуТуре = (а, Ь, с, d);
…..
МуТуре (2)
Integer (‘D’)
pointer (longint(a)+ $FF)
Char (127 mod c)
Byte (k)
При автоопределенном преобразовании типа выражения может произойти изменение длины его внутреннего представления (длина может увеличиться или уменьшиться).
В Турбо Паскале определен еще один явный способ преобразования данных: в ту область памяти, которую занимает переменная некоторого типа, можно поместить значение выражения другого типа, если только длина внутреннего представления вновь размещаемого значения в точности равна длине внутреннего представления переменной. С этой целью вновь используется автоопределенная функция преобразования типов, но уже в левой части оператора присваивания:
type
byt = array [1..2] of Byte;
int = array [1..2] of Integer;
rec = record
x, у : Integer
end;
var
vbyt : byt;
vint : int;
vrec : rec;
begin
byt(vint[1])[2] := 0;
int(vrec)[1] := 256
end.
Неявное преобразование типов возможно только в двух случаях:
— в выражениях, составленных из вещественных и целочисленных переменных, последние автоматически преобразуются к вещественному типу, и все выражение в целом приобретает вещественный тип;
— одна и та же область памяти попеременно трактуется как содержащая данные то одного, то другого типа (совмещение в памяти данных разного типа).
Совмещение данных в памяти может произойти при использовании записей с вариантными полями (см. 4.2.2), типизированных указателей, содержащих одинаковый адрес (см. гл. 6), а также при явном размещении данных разного типа по одному и тому же абсолютному адресу. Для размещения переменной по нужному абсолютному адресу она описывается с последующей стандартной директивой ABSOLUTE, за которой помещается либо абсолютный адрес, либо идентификатор ранее определенной переменной. Абсолютный адрес указывается парой чисел типа WORD, разделенных двоеточием; первое число трактуется как сегмент, второе — как смещение адреса (см. гл. 6). Например:
b : Byte absolute $0000:$0055; w : Longlnt absolute 128:0;
Если за словом ABSOLUTE указан идентификатор ранее определенной переменной, то происходит совмещение в памяти данных разного типа, причем первые байты внутреннего представления этих данных будут располагаться по одному и тому же абсолютному адресу, например:
var
х : Real;
у : array [1..3] of Integer absolute x;
В этом примере переменные X и Y будут размещены, начиная с одного и того же абсолютного адреса. Таким образом, одну и ту же область памяти длиной 6 байт, а следовательно, и размещенные в этой области данные теперь можно рассматривать как данные либо типа REAL, либо как массив из трех данных типа INTEGER. Например, следующая программа выдаст на экран содержимое первых двух байт внутреннего представления вещественного числа п = 3.1415 в виде целого числа:
var
х : Real; у : array[1..3] of Integer absolute x;
begin
х := pi; WriteLn(y[1])
end.
На экран будет выдан результат 8578.
Неявные преобразования типов могут служить источником трудно обнаруживаемых ошибок в программе, поэтому везде, где это возможно, следует избегать их.
Понятие данных является одним из ключевых в программировании, да и вообще в компьютерных науках. Грубо говоря, данные в информатике это информация, находящиеся в состоянии хранении, обработки или передачи, в какой-то отрезок времени. В машинах Тьюринга информация имеет тип, а он в свою очередь, зависит от рода информации.
Типы данных в Паскале определяют возможные значения переменных, констант, выражений и функций. Они бывают встроенными и пользовательскими. Встроенные типы изначально присутствуют в языке программирования, а пользовательские создаются программистом.
По способу представления и обработки типы данных бывают:
- простые
- структурированные
- указатели
- объекты
- процедуры
В этой статье будут рассмотрены лишь, наиболее простые типы данных, так как на начальных этапах обучения, вашей программе будет проще обойтись, например, без файлов и записей, чем без целочисленных или строковых переменных.
Целочисленный тип
Сюда входят несколько целочисленных типов, которые различаются диапазоном значений, количеством байт отведённых для их хранения и словом, с помощью которого объявляется тип.
Тип | Диапазон | Размер в байтах |
shortint | -128…127 | 1 |
integer | -32 768…32 767 | 2 |
longint | -2 147 483 648…2 147 483 647 | 4 |
byte | 0…255 | 1 |
word | 0…65 535 | 2 |
Объявить целочисленную переменную можно в разделе Var, например:
Var book: word;
Над переменными этой категории можно выполнять все арифметические и логические операции за исключением деления (/), для него нужен вещественный тип. Также могут быть применены некоторые стандартные функции и процедуры.
Вещественный тип
В Паскале бывают следующие вещественные типы данных:
Тип | Диапазон | Память, байт | Количество цифр |
Real | 2.9e-39 … 1.7e38 | 6 | 11-12 |
Single | 1.5e-45 … 3.4e38 | 4 | 7-8 |
Double | 5.0e-324 …1.7e308 | 8 | 15-16 |
Extended | 3.4e-4932 … 1.1e493 | 10 | 19-20 |
Comp | -9.2e63 … (9.2e63)-1 | 8 | 19-20 |
Над ними может быть выполнено большее количество операций и функций, чем над целыми. Например, эти функции возвращают вещественный результат:
sin(x) – синус;
cos(x) – косинус;
arctan(x) – арктангенс;
ln(x) – натуральный логарифм;
sqrt(x) – квадратный корень;
exp(x) – экспонента;
Логический тип
Переменная, имеющая логический тип данных может принимать всего два значения: true (истина) и false (ложь). Здесь истине соответствует значение 1, а ложь тождественная нулю. Объявить булеву переменную можно так:
Var A: Boolean;
Над данными этого типа могут выполняться операции сравнения и логические операции: not , and, or, xor.
Символьный тип
Символьный тип данных – это совокупность символов, используемых в том или ином компьютере. Переменная данного типа принимает значение одного из этих символов, занимает в памяти компьютера 1 байт. Слово Char определяет величину данного типа. Существует несколько способов записать символьную переменную (или константу):
- как одиночный символ, заключенный в апострофы: ‘W’, ‘V’, ‘п’;
- указав код символа, значение которого должно находиться в диапазоне от 0 до 255.
- при помощи конструкции ^K, где K – код управляющего символа. Значение K должно быть на 64 больше кода соответствующего управляющего символа.
К величинам символьного типа данных применимы операции отношения и следующие функции:
Succ(x) — возвращает следующий символ;
Pred(x) — возвращает предыдущий символ;
Ord(x) — возвращает значение кода символа;
Chr(x) — возвращает значение символа по его коду;
UpCase(x) — переводит литеры из интервала ‘a’..’z’ в верхний регистр.
Для плодотворной работы с символьным типом рекомендую пользоваться таблицей ASCII.
Строковый тип
Строка в Паскале представляет собой последовательность символов заключенных в апострофы, и обозначается словом String. Число символов (длина строки) должно не превышать 255. Если длину строки не указывать, то она автоматически определиться в 255 символов. Общий вид объявления строковой переменной выглядит так:
Var <имя_переменной>: string[<длина строки>];
Каждый символ в строке имеет свой индекс (номер). Индекс первого байта – 0, но в нем храниться не первый символ, а длина всей строки, из чего следует, что переменная этого типа будет занимать на 1 байт больше числа переменных в ней. Номер первого символа – 1, например, если мы имеем строку S=‘stroka’, то S[1]=s;. В одном из следующих уроков строковый тип данных будет рассмотрен подробнее.
Перечисляемый тип данных
Перечисляемый тип данных представляет собой некоторое ограниченное количество идентификаторов. Эти идентификаторы заключаются в круглые скобки, и отделяются друг от друга запятыми.
Пример:
Type Day=(Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday);
Var A: Day;
Переменная A может принимать лишь значения определенные в разделе Type. Также можно объявить переменную перечисляемого типа в разделе Var:
Var A: (Monday, Tuesday);
К данному типу применимы операции отношения, при этом заранее определенно, что Monday<Tuesday<Wednesday т. д. Также можно применять функции succ, pred, ord, процедуры inc и dec, и использовать операцию присваивания: A:=Tuesday;
Интервальный тип данных
Когда необходимо задать какой то диапазон значений, то в таких ситуациях применяется интервальный тип данных. Для объявления используется конструкция m..n, где m – минимальное (начальное) значение, а n – максимально (конечное); здесь m и n являются константами, которые могут быть целого, символьного, перечисляемого или логического типа. Описываться величины интервального типа могут как в разделе типов, так и в разделе описания переменных.
Общий вид:
TYPE <имя_типа> = <мин. значение>..<макс. значение>;
Пример:
TYPE Cards = 1..36;
Похожие записи:
Любые данные – константы, переменные, значения функций характеризуются в Паскале типом данных.
Определим понятие типа данных. Как уже известно, все объекты программы (переменные, константы и т.д.) должны быть описаны.
Описания информируют транслятор, во-первых, о существовании используемых переменных и других объектов, во-вторых, указывают на свойства этих объектов. Например, описание переменной, значение которой является числом, указывает на свойства чисел. Формально числа могут быть целыми и вещественными (дробными). В Паскале, как и в других языках программирования, числа разделены на два типа: целые (зарезервированное слово integer ) и вещественные (зарезервированное слово real ).
Выделение целых чисел в отдельный тип объясняется тем, что в вычислительной машине целые и вещественные числа представляются по-разному: целое число может быть представлено абсолютно точно, а вещественное – неизбежно с некоторой конечной погрешностью, которая определяется свойствами транслятора.
Например, пусть переменная x имеет тип real и ее значение равно единице: x=1 . Соответствующее значение в памяти компьютера может быть и 0.999999999, и 1.000000001, и 1.000000000 . Но если переменная x будет объявлена как переменная целого типа, то единица в компьютере будет представлена абсолютно точно и переменная x не сможет принимать вещественные (дробные) значения – ведь она была описана как переменная целого типа.
Таким образом, тип данных определяет:
- внутреннее представление данных в памяти компьютера;
- множество значений, которые могут принимать величины этого типа;
- операции, которые могут выполняться над величинами этого типа.
Введение типов данных является одной из базовых концепций языка Паскаль, заключающейся в том, что при выполнении операции присваивания переменной значения выражения, переменная и выражение должны быть одного типа. Такая проверка выполняется компилятором, что значительно упрощает поиск ошибок и приводит к повышению надежности программы.
Множество типов данных языка Турбо Паскаль можно разделить на две группы:
- стандартные (предопределенные) типы;
- типы, определяемые пользователем (пользовательские типы).
К стандартным типам Турбо Паскаль относят:
- целый тип – integer ;
- вещественный тип – real ;
- символьный тип – char ;
- логический тип – boolean ;
- строковый тип – string ;
- указательный тип – pointer ;
- текстовый тип – text .
Пользовательские типы данных представляют собой различные комбинации стандартных типов.
К пользовательским типам относят:
- перечисляемый тип;
- интервальный тип;
- указательный тип;
- структурированные типы;
- процедурный тип.
Замечание. Возможна и другая классификация типов данных, согласно которой типы делятся на простые и сложные.
К простым типам относят: целый тип, вещественный тип, символьный тип, логический тип, перечислимый тип и интервальный тип.
Сложный тип представляет собой различные комбинации простых типов (массивы, записи, множества, файлы и т.д.)
Стандартные типы
Стандартный тип данных определен самим языком Паскаль. При использовании в программе стандартных типов достаточно указать подразделы необходимых типов ( const, var ) и далее описать используемые в программе константы и переменные. Необходимость использования подраздела Type отсутствует.
Например, если в программе используются только переменные:
i,j – integer (целые);
x,y — real (вещественные);
t,s — char (символьные);
a,b – boolean (логические),
то необходим только подраздел переменных – Var . Поэтому в описательной части программы объявления переменных записываются следующим образом:
Var
i,j:integer;
x,y:real;
t,s:char;
a,b:boolean;
Целые типы
Данные этого типа могут принимать только значения целых чисел. В компьютере значения целого типа представляются абсолютно точно. Если переменная отрицательная, то перед ней должен стоять знак «–», если переменная положительная, то знак «+» можно опустить. Данный тип необходим в том случае, когда какую-то величину нельзя представить приближенно – вещественным числом. Например, число людей, животных и т.д.
Примеры записи значений целых чисел: 17, 0, 44789, -4, -127.
Диапазон изменения данных целого типа, определяется пятью стандартными типами целых чисел и представлен в таблице:
Тип | Диапазон | Размер в байтах |
Shortint | -128…+128 | 1 |
Integer | -32768…32767 | 2 |
Longint | -2147483648…2147483647 | 4 |
Byte | 0…255 | 1 |
Word | 0…65535 | 2 |
Последние два типа служат для представления только положительных чисел, а первые три как положительных, так и отрицательных чисел.
В тексте программы или при вводе данных целого типа значения записываются без десятичной точки. Фактические значения переменной не должны превышать допустимых значений того типа ( Shortint, Integer, Longint, Byte, Word ), который был использован при описании переменной. Возможные превышения при вычислениях ни как не контролируются, что приведет к неверной работе программы.
Пример использования переменной целого типа
Var
a:integer;
b:word;
c:byte;
Begin
a:=300; {a присвоено значение 300}
b:=300; {b присвоено значение300}
c:=200; {c присвоено значение200}
a:=b+c; {a присвоено значение500}
c:=b; {Ошибка! Переменная c может принимать значения не более 255. Здесь переменной c присваивается значение 500,что вызовет переполнение результата.}
End.
Вещественные типы
Значения вещественных типов в компьютере представляются приближенно. Диапазон изменения данных вещественного типа определяется пятью стандартными типами: вещественный ( Real ), с одинарной точностью ( Single ), двойной точностью ( Double ), с повышенной точностью ( Extended ), сложный ( Comp ) и представлен в таблице:
Тип | Диапазон | Число значащих цифр | Размер в байтах |
Real | 2.9E-39…1.7E+38 | 11-12 | 6 |
Single | 1.5E-45…3.4E+38 | >7-8 | 4 |
Double | 5E-324…1.7E+308 | 15-16 | 8 |
Extended | 3.4E-4951…1.1E+4932 | 19-20 | 10 |
Comp | -2E+63+1…+2E+63-1 | 19-20 | 8 |
Вещественные числа могут быть представлены в двух форматах: с фиксированной и плавающей точкой.
Формат записи числа с фиксированной точкой совпадает с обычной математической записью десятичного числа с дробной частью. Дробная часть отделяется от целой части с помощью точки, например
34.5, -4.0, 77.001, 100.56
Формат записи с плавающей точкой применяется при записи очень больших или очень малых чисел. В этом формате число, стоящее перед символом «E», умножается на число 10 в степени, указанной после символа «E».
1E-4 | 1*10-4 |
3.4574E+3 | 3.4574*10+3 |
4.51E+1 | 4.51*10+1 |
Примеры чисел с плавающей точкой:
Число | Запись на Паскале |
0,0001 | 1E-4 |
3457,4 | 34574E-1 |
45,1 | 451E-1 |
40000 | 4E+4 |
124 | 0.124E+3 |
124 | 1.24E+2 |
124 | 12.4E+1 |
124 | 1240E-1 |
124 | 12400E-2 |
В таблице с 5 по 9 строку показана запись одного и того же числа 124. Изменяя положение десятичной точки в мантиссе (точка «плывет», отсюда следует название «запись числа с плавающей точкой») и одновременно изменяя величину порядка, можно выбрать наиболее подходящую запись числа.
Пример описания переменных вещественного типа.
Var
x,y,z:real;
Символьный тип
Значениями символьного типа являются символы, которые можно набрать на клавиатуре компьютера. Это позволяет представить в программе текст и производить над ним различные операции: вставлять, удалять отдельные буквы и слова, форматировать и т.д.
Символьный тип обозначается зарезервированным словом Char и предназначен для хранения одного символа. Данные символьного типа в памяти занимают один байт.
Формат объявления символьной переменной:
<имя переменной>: Char;
При определении значения символьной переменной символ записывается в апострофах. Кроме того, задать требуемый символ можно указанием непосредственно его числового значения ASCII-кода. В этом случае необходимо перед числом, обозначающим код ASCII необходимого символа, поставить знак #.
Пример использования переменных символьного типа:
Var
c:char; {c – переменная символьного типа}
Begin
c:=’A’; {переменной c присваивается символ ’A’}
c:=#65; {переменной c также присваивается символ A. Его ASCII код равен 65}
c:=’5’; {переменной c присваивается символ 5,
End. здесь 5 это уже не число}
Логический тип
Логический тип данных называют булевским по имени английского математика Джорджа Буля, создателя области математики – математической логики.
Формат объявления переменной логического типа:
<имя переменной>: boolean;
Данные этого типа могут принимать только два значения:
- True – истина;
- False – ложь.
Логические данные широко используются при проверке правильности некоторых условий и при сравнении величин. Результат может оказаться истинным или ложным.
Для сравнения данных предусмотрены следующие операции отношений:
= | равно | |
<> | не равно | |
> | больше | |
< | меньше | |
>= | больше или равно | |
<= | меньше или равно |
Пример использования операций отношения:
отношение 5>3, результат true (истина);
отношение 5=3, результат false (ложь).
Пример использования переменных логического типа.
Var
a,b:boolean; {a,b – переменные логического типа}
Begin
a:=Тrue; {переменной a присваивается значение «истина»}
b:=false; {переменной b присваивается значение «ложь»}
End.
Константы
В качестве констант могут использоваться целые, вещественные числа, символы, строки символов, логические константы.
Константу необходимо объявить в описательной части с помощью зарезервированного слова const.
Формат объявления константы
Const <имя константы>= <значение>;
Если в программе используются несколько констант, допускается использование только одного ключевого слова Const, описание каждой константы заканчивается точкой с запятой. Блок констант заканчивается объявлением другого раздела или объявлением блока исполняемых операторов.
Пример:
Const {объявление раздела констант}year=2003; {константа целого типа, т.к. нет в записи десятичной точки}
time=14.05; {константа вещественного типа}
N=24; {константа целого типа, т.к. нет в записи десятичной точки}
P=3.14; {константа вещественного типа}
A=true; {константа логического типа}
str1=’7’; {константа символьного типа}
str2=’A’; {константа символьного типа}
str3=’Turbo’; {константа строкового типа}
Var {объявление раздела переменных}
X,y:integer; {переменные целого типа}
Пользовательские типы
Из совокупности пользовательских типов рассмотрим только
- перечисляемый тип;
- интервальный тип.
Эти два типа нам будут необходимы при изучении массивов.
Перечисляемый тип
Перечисляемый тип данных описывает новые типы данных, значения которых определяет сам программист. Перечисляемый тип задается перечислением тех значений, которые он может получать. Каждое значение именуется некоторым идентификатором и располагается в списке, обрамленном круглыми скобками. Перечисляемый тип относится к типам данных, определяемым пользователем, поэтому объявление этого типа начинается зарезервированным словом TYPE .
Формат перечисляемого типа:
Type
<имя типа>= (константа1, константа2,…, константаN);
где
константа1, константа2,…, константаN – упорядоченный набор значений идентификаторов, рассматриваемых как константы.
Пример описания перечисляемого типа:
Type
ball=(one, two, three, four, five);
var
t:ball;
Здесь ball – имя перечисляемого типа; one, two, three, four, five – константы; t – переменная, которая может принимать любое значение констант.
В перечисляемом типе константа является идентификатором, поэтому она не заключается в кавычки и не может быть числом. Таким образом, в перечисляемом типе под константой понимается особый вид констант, которые не могут быть:
- константами числового типа: 1, 2, 3, 4 и т. д;
- константами символьного типа: ‘a’, ‘s’, ‘1’, ‘3’ и т. д.;
- константами строкового типа: ‘first’, ‘second’ и т.д.
Кроме того, к значениям этого типа не применимы арифметические операции и стандартные процедуры ввода и вывода Read, Write .
Пример использования переменных перечисляемого типа:
Type
days = (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday);
Var
day: days;
begin
if day = Sunday then writeln(‘Сегодня Воскресенье!’);
End.
Элементы, входящие в определение перечисляемого типа, считаются упорядоченными в той последовательности, в которой они перечисляются. Нумерация начинается с нуля. Поэтому в приведенном примере дни недели имеют следующие порядковые номера
Для программного определения порядкового номера используется функция Ord() .
В нашем примере порядковые номера равны:
Ord(Monday) = 0;
Ord(Saturday) = 5;
Ord(Sunday) = 6.
Интервальный тип
Если какая-то переменная принимает не все значения своего типа, а только значения, содержащиеся в некотором диапазоне, то такой тип данных называется интервальным типом. Часто интервальный тип называют ограниченным типом и типом-диапазоном. Интервальный тип задается границами своих значений:
<минимальное значение>..<максимальное значение>
Здесь:
- два символа «..» рассматриваются как один символ, поэтому между ними недопустимы пробелы;
- левая граница диапазона не должна превышать его правую границу.
Интервальный тип относится к типам данных, определяемых пользователем, поэтому объявление этого типа начинается со служебного слова TYPE .
Пример описания интервального типа:
Typedigit = 1..10;
month = 1..31;
lat = ’A’..’Z’;