Часть iii. программирование на паскале – второй уровень

В случае, если вам думается, что вы уже все имеете возможность, то вы правы и неправы. Правы по причине того, что вы имеете возможность написать сколь угодно громадную программу, разбив ее на разумное число процедур. Неправы по причине того, что ваша свойство манипулировать данными в памяти компьютера еще весьма ограничена. А без нее вам не поддадутся «умные» задачи. К примеру, не познакомившись с так называемыми массивами, вы не сможете запрограммировать игру в крестики-нолики либо решить задачу о выходе из лабиринта; не освоив работу со строчками, файлами и символами, вы не сможете решить задачу о мало-мальски важной расшифровке сообщений и секретной шифровке.

Эта часть посвящена тому, дабы

  • Увеличить ваши знания о возможностях Паскаля
  • Сделать ваши знания о Паскале строгими, в противном случае вы не сможете исправлять в программах грамматические неточности, соответственно программы у вас трудиться не будут.

Начнем с наведения порядка в отечественных знаниях о Паскале.

Глава 11. ключевые слова и Алфавит Паскаля

Алфавит

У каждого языка — собственный алфавит. В русском языке нельзя употреблять латинские буквы, в греческом — китайские иероглифы и т.д., в противном случае вас мало кто осознает.

В Паскале также имеется собственный алфавит — четкий комплект знаков, каковые вы имеете право использовать в программе. Ни одного другого знака использовать запрещено.

Вот алфавит Паскаля:

1) Латинские заглавные (прописные) буквы: A, B, C, D,……., Z.

2) Латинские малые (строчные) буквы: a, b, c, d,……., z.

3) Десять цифр: 0,1,2,3,4,5,6,7,8,9.

4) Знаки подчеркивания “_” и пробела “ “.

5) Особые знаки: + — * / = ( ) [ ] { } . , : ; ’ ^ @ $ #

6) В определенных местах программы возможно использовать и все остальные знаки, среди них и русские буквы. Поясню, о каких знаках и о каких местах идет обращение. Вы понимаете (3.5), что для кодирования одного знака в компьютере употребляется один байт. Ввиду того, что байт складывается из 8 битов, им возможно закодировать 256 знаков. Все они приведены в так называемой таблице ASCII(в 12.11вам будет предложено распечатать эту таблицу). Большая часть из них и имеется в виду. Использовать их возможно лишь в двух местах:

  • В символьных и строковых константах, к примеру, Slovo:=’Чаща’
  • В комментариев, к примеру, { Вот знаки ASCII: % F ! \ Л }

Главные слова

Существует пара десятков слов, некоторым из которых не рекомендуется, а практически всем легко не разрещаеться быть именами. Происходит это по причине того, что Паскаль применяет их для более серьёзных дел. Эти запрещенные слова, а заодно уж и нерекомендованные (хоть это и нестрого) мы будем именовать главными (их кроме этого именуют зарезервированнымиили служебными). Вот главные слова языков Borland Pascal 7.0 для DOS и TurboPascal 7.0 (перечни главных слов вторых предположений Паскаля мало чем отличаются от приведенного):

absolute

AND

array

asm

assembler

begin

case

const

constructor

destructor

div

do

downto

else

end

export

exports

external

far

file

for

forward

function

goto

if

implementation

in

index

inherited

inline

interface

interrupt

label

library

mod

near

nil

not

object

of

or

packed

private

procedure

program

public

record

repeat

resident

set

shl

shr

string

then

to

type

unit

until

uses

var

virtual

while

with

xor

Так, если вы ненароком придумаете собственной переменной имя asm, Паскаль укажет вам на неточность.

Применение пробела

  • Пробелызапрещены в ключевых слов и имён.
  • Пробелы необходимы между ключевыми словами и именами (если они находятся в одной строке).
  • В остальных случаях пробелы несущественны и смогут ставиться произвольно.
  • В том месте, где допускается один пробел, допускается и какое количество угодно.
  • Вместо нажатия на клавишу пробела возможно нажимать на клавишу ввода.

Глава 12. Работа с различными типами данных Паскаля

Перечень типов

Любая переменная величина в Паскале обязана принадлежать какому-нибудь типу: Integer, Char, String и т.п. Вот перечень фактически всех типов, многие из которых нам еще предстоит пройти. Тут не учтены лишь так именуемые процедурные типы, каковые в данной книге освещаться не будут.

Простые типы

Числовые типы

Целочисленные типы

Byte

ShortInt

Word

Integer

LongInt

Вещественные типы

Real

Single (при наличии либо эмуляции матем. сопроцессора)

Double (при наличии либо эмуляции матем. сопроцессора)

Extended (при наличии либо эмуляции матем. сопроцессора)

Comp (при наличии либо эмуляции матем. сопроцессора)

Символьный тип

Char

Логический тип

Boolean

Перечислимый тип

Ограниченный тип (диапазон)

Сложные (структурированные) типы(строятся из несложных):

Массивы array

Записи record

Множества set

Строки String

Файлы

Текстовые файлы

Text

Типизированные файлы

File of …

Бестиповые файлы

File

ОбъектыObject

Ссылки:

Ссылки

Адресный тип

Pointer

Комментарии к перечню типов

Переменная несложного типав любой момент времени имеет своим значением что-то одно: одно число либо один знак и т.п.

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

Аналогия: Несложной тип. Вы желаете приобрести продукты. Вы идете по улице и видите дверь с надписью «Лавка». Вы открываете дверь и видите, что в том месте продаются, к примеру, баранки.

Структурированный тип. Вы желаете приобрести продукты. Вы видите дверь с надписью «Супермаркет». Вы открываете дверь и видите, что в том месте продается множество различных продуктов.

Ссылки. Вы желаете приобрести продукты. Вы видите дверь с надписью «Адресное бюро». Вы открываете дверь, но в никаких продуктов нет. Вместо них вам дают адрес лавки либо супермаркета.

Числовые типы

Целочисленные типыпозволяют переменной принимать значения целых чисел в соответствии с следующей таблице:

Тип Диапазон значений какое количество байтов занимает одно значение
Byte 0..255
ShortInt -128..127
Word 0..65535
Integer -32768..32767
LongInt -2147483648..2147483647

Для чего необходимы Byte и ShortInt, в случае, если имеется Integer? Они занимают меньше места в памяти. В случае, если, к примеру, ваша переменная по смыслу задачи обозначает 60 секунд (другими словами целое число в диапазоне от 0 до 60), то полный суть придать ей тип Byte.

Вещественные типыпозволяют переменной принимать значения вещественных чисел в соответствии с следующей таблице:

Тип Примерный диапазон значений Точность (значащих цифр) какое количество байтов занимает одно значение
Real 2.9´10-39 — 1.7´1038 11-12
Single 1.5´10-45 — 3.4´1038 7-8
Double 5´10-324 — 1.7´10308 15-16
Extended 3.4´10-4932 — 1.1´104932 19-20
Comp [9] приблизительно от -1019 до 1019

Типы Single, Double, какое количество и Comp смогут настойчиво попросить для собственной работы некоей настройки Паскаля.

направляться не забывать, что дробные числа (к примеру, 1/3) компьютер хранит приблизительно в таком виде: 0,3333333333333. Вы понимаете, что такое представление дробных чисел примерно. Дабы совершенно верно представить 1/3, компьютеру пригодилось бы нескончаемое количество троек, но память компьютера ограничена. Ячейка под переменную типа Real разрешает хранить всего 11-12 таких троек. Эту приблизительностьнужно иметь в виду, в то время, когда вы многократно делаете арифметические действия над переменными вещественных типов. При определенном сочетании действий и чисел вы имеете возможность срочно взять совсем неверный итог. Попытайтесь, к примеру, выполнить такую программу:

VAR a,b,y : Real;

BEGIN

a:=55555555555.1; b:=55555555555.0;

y:=a-b;

WriteLn (y :30:3)

END.

Вы найдёте, что вместо результата 0.100 компьютер выдает итог 0.125.

Массивы

Чтобы понять массивы, необходимо владеть некоей культурой математического мышления. В случае, если данный материал покажется вам тяжёлым, не поддавайтесь искушению пропустить его. Настоящего программирования без массивов не бывает, да и большинство предстоящего материала без массивов не будет понятна.

Переменные с индексами

В математике активно используются так именуемые индексированные переменные. На бумаге они записываются так:

x1 x2 b8 yi yi-6 zij zi+1j

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

X[1] X[2] B[8] Y[i] Y[i-6] Z[i,j] Z[i+1,j]

Для чего необходимы индексированные переменные? Их комфортно использовать хотя бы при операциях над числовыми последовательностями. Числовой последовательность – это легко пара чисел, выстроенных по порядку одно за вторым. Чисел в последовательности возможно довольно много а также вечно довольно много.

Заберём, к примеру, нескончаемый последовательность чисел Фибоначчи: 1 1 2 3 5 8 13 21 34….. Попытайтесь додуматься, по какому закону образуются эти числа. Если вы сами не додумались, то я посоветую: каждое из чисел, начиная с третьего, есть суммой двух прошлых. А сейчас попытаемся записать это утверждение посредством языка математики. Для этого обозначим каждое из чисел Фибоначчи индексированной переменной так:

Первое число Фибоначчи обозначим так: f[1],

Второе число Фибоначчи обозначим так: f[2] и т.д.

Тогда возможно записать, что f[1]=1 f[2]=1 f[3]=2 f[4]=3 f[5]=5 f[6]=8 ……

Разумеется, что f[3]=f[1]+f[2],

f[4]=f[2]+f[3],

f[5]=f[3]+f[4] и т.д.

Как математически одной формулой записать тот факт, что каждое из чисел есть суммой двух прошлых? Математики в индексном виде это записывают так:

f[i]=f[i-2]+f[i-1].

Для иллюстрации подставим вместо i любое число, к примеру, 6. Тогда окажется:

f[6]=f[6-2]+f[6-1] либо

f[6]=f[4]+f[5].

Задание 102: Запишите в индексном виде, как получается из прошлого числа последовательности последующее:

1) 14 18 22 26 …..

2) 6 12 24 48 ….

3) 3 5 9 17 33 65 ….

Вот еще примеры, в то время, когда математики предпочитают применять индексы. Пускай мы в течении года ежедневно раз в день измеряли температуру за окном Тогда в полной мере конечно обозначить через t[1] температуру первого дня года, t[2] — второго,….., t[365] — последнего. Пускай 35 спортсменов прыгали в высоту. Тогда через h[1] возможно обозначить высоту, забранную первым прыгуном, h[2] — вторым и т.д.

Одномерные массивы

Одна из обычных задач программирования формулируется приблизительно так. Имеется много данных, к примеру, тех же температур либо высот. С этими данными компьютер обязан что-нибудь сделать, к примеру, вычислить среднегодовую температуру, количество морозных дней, большую забранную высоту и т.п. Раньше мы вычисляли подобные вещи, и эти вводили в компьютер с клавиатуры одно за вторым в одну и ту же ячейку памяти (см. 7.7). Но, программистская опыт говорит, что комфортно, а довольно часто и нужно иметь данные в оперативной памяти сходу все, а не попеременно. Тогда для задачи про температуру нам пригодится 365 ячеек. Эти 365 ячеек мы и назовем массивом. Итак, массивомможно назвать последовательность ячеек памяти, отведенных для хранения значений индексированной переменной. Вопрос о том, как много значений выясняется в памяти, отложим на будущее (15.1).

Разглядим на несложном примере, как Паскаль управляется с массивами. Предположим, в зоопарке живут три удава. Известна протяженность каждого удава в сантиметрах (500, 400 и 600). Какая протяженность окажется у трех удавов, вытянутых в линию?

Обозначим длину первого удава — dlina[1], второго — dlina[2], третьего — dlina[3]. Прикажем Паскалю отвести под эту индексированную переменную массив:

VAR dlina : array [1..3] ofInteger

Тут arrayозначает массив либо последовательность, 1 — первое значение индекса, 3 — последнее. Две точки обозначают диапазон от 1 до 3 (см. 5.7) В целом эту строчок возможно перевести так: Отвести в памяти под переменную dlina последовательность ячеек типа Integer, пронумерованных от 1 до 3.

Вот программа абсолютно:

VAR dlina :array [1..3] of Integer;

summa :Integer;

BEGIN

dlina[1]:=500;

dlina[2]:=400;

dlina[3]:=600;

{Сейчас в трех ячейках памяти уже находятся числа

и с ними возможно делать арифметические действия}

summa:= dlina[1]+dlina[2]+dlina[3];

WriteLn(summa)

END.

В случае, если суть написанного выше вам неясен, запустите отладочный походовый режим исполнения программы, вынудив Паскаль показывать вам текущие значения dlina[1], dlina[2], dlina[3], summa.

Сейчас запишем ту же программу в предположении, что длины удавов заблаговременно малоизвестны и мы их вводим при помощи ReadLn:

VAR dlina :array [1..3] of Integer;

summa :Integer;

BEGIN

ReadLn (dlina[1],dlina[2],dlina[3]);

summa:= dlina[1]+dlina[2]+dlina[3];

WriteLn(summa)

END.

Сейчас решим ту же задачу в предположении, что удавов не три, а тысяча:

VAR dlina :array [1..1000] of Integer;

summa, i :Integer;

BEGIN

{Вводим длины тысячи удавов, хоть это и утомительно:}

for i:=1 to 1000 do ReadLn (dlina[i]);

{Тут на первом исполнении цикла i=1 и исходя из этого компьютер делает ReadLn(dlina[1]),

на втором – i=2 и исходя из этого компьютер делает ReadLn(dlina[2]) и т.д.}

{Определяем суммарную длину тысячи удавов:}

summa:= 0;

for i:=1 to 1000 do summa:=summa+dlina[i]);

WriteLn(summa)

END.

Решим еще одну задачу. Дан последовательность из 10 произвольных чисел: a[1], a[2], … , a[10]. Подсчитать и напечатать суммы троек стоящих рядом чисел: a[1]+a[2]+a[3], a[2]+a[3]+a[4], a[3]+a[4]+a[5], …… , a[8]+a[9]+a[10].

VAR a :array [1..10] of Integer;

i :Integer;

BEGIN

for i:=1 to 10 do ReadLn (a[i]);

for i:=1 to 8 do WriteLn ( a[i]+ a[i+1]+ a[i+2] )

END.

Задание 103:. Разработайте программу вычисления среднегодовой температуры (Для проверки в компьютере годом можно считать семь дней).

Задание 104:. Подсчитайте количество морозных дней (в то время, когда температура ниже -20 град.).

Задание 105:. Каким по порядку идет самый морозный сутки?

Задание 106:. Вычислить и распечатать первые тридцать чисел Фибоначчи.

12.3.3. Двумерные массивы

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

1-й сутки 2-й сутки 3-й сутки 4-й сутки
Метеостанция 1 -8 -14 -19 -18
Метеостанция 2
Метеостанция 3

Требуется:

1) Распечатать показания термометров всех метеостанций за 2-й сутки

2) Выяснить среднюю температуру на третьей метеостанции

3) Распечатать всю таблицу

4) Распечатать, в какие конкретно дни и на каких метеостанциях температура была в диапазоне 24-26 градусов

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

t[1,1] t[1,2] t[1,3] t[1,4]

t[2,1] t[2,2] t[2,3] t[2,4]

t[3,1] t[3,2] t[3,3] t[3,4]

Обратите внимание, что первый индекс в скобках обозначает номер строчка (метеостанции), второй — номер столбца (дня) прямоугольной таблицы.

Программа:

{В памяти отводим массив из 3*4=12 ячеек под значения типа светло синий индексированной переменной t. Будем именовать его двумерным массивом:}

VAR t :array [1..3, 1..4] ofInteger;

s,i,j :Integer;

BEGIN {Зададим значения элементов массива примитивным присваиванием:}

t[1,1]:=-8; t[1,2]:=-14; t[1,3]:=-19; t[1,4]:=-18;

t[2,1]:=25; t[2,2]:= 28; t[2,3]:= 26; t[2,4]:= 20;

t[3,1]:=11; t[3,2]:= 18; t[3,3]:= 20; t[3,4]:= 25;

{А сейчас распечатаем второй столбец массива:}

for i:=1 to 3 do WriteLn(t[i,2]);

{Определим среднее значение элементов третьей строки:}

i:=3;

s:=0;

for j:=1 to 4 do s:=s+t[i,j];

WriteLn(s/4 :10:3);

{Распечатаем всю таблицу:}

for i:=1 to 3 do for j:=1 to 4 do WriteLn (t[i,j]);

{Распечатаем станции и дни с температурой 24-26 градусов:}

for i:=1 to 3 do for j:=1 to 4 do

if(t[i,j]=24) AND (t[i,j]

END.

Задание 107: Вычислить отличие между большой и минимальной температурой во всей таблице.

Какие конкретно бывают массивы

Массивы смогут быть одномерные, двумерные, трехмерные, четырехмерные и т.д.:

array [1..10] of Integer -одномерный массив 10 ячеек

array [1..10, 1..5] of Integer -двумерный массив 50 ячеек

array [1..10, 1..5, 1..2] of Integer -трехмерный массив 100 ячеек

array [1..10, 1..5, 1..2, 1..3] of Integer -четырехмерный массив 300 ячеек

Массивы бывают не только числовые, но и символьные, строковые и другие. Подходит любой знакомый нам тип. К примеру:

array [1..50] of Char

Это указывает, что в каждой из 50 ячеек должно пребывать не число, а произвольный знак. Еще один пример:

array [1..50] of String

Тут в каждой из 50 ячеек обязана пребывать строчок. Примеры программ с этими массивами мы заметим в 12.13.

Границы индексов в квадратных скобках также смогут быть различными, к примеру:

array [20..60] of Real

Тут под вещественные числа отводится 41 ячейка.

array [0..9, -10..30] of Real

Тут под вещественные числа отводится 10*41=410 ячеек.

По большому счету индексы смогут быть не только числовыми, но и любыми порядковыми. К примеру,

array [‘А’..’Я’] of Real

Для чего это необходимо, будет светло в 12.8.

Полная синтаксическая информация о массивах будет приведена в 14.8.

Какая польза от массивов при программировании игр? Вряд ли хоть одну «умную» игру возможно запрограммировать без применения массивов. Заберём хотя бы «крестики-нолики» на поле 3 на 3. Вам нужно будет рисовать на экране громадные клетки, а в них – нолики (кружочки) по окончании ваших ходов и крестики (пересекающиеся линии) по окончании ходов компьютера. Но этого слишком мало. Дабы компьютер имел возможность поставить крестик в свободном поле, он обязан хотя бы знать, а в нолики клетках и каких крестики уже стоят. Разбирать для этого данные о пикселах экрана весьма некомфортно. Значительно разумнее заблаговременно организовать VAR a: array[1..3,1..3] of Byte и записывать в том направлении в необходимые места нолики по окончании единички и ходов человека по окончании ходов компьютера. Сразу же по окончании записи в массив 0 либо 1 программа обязана рисовать в соответствующем месте экрана кружок либо крестик. Мыслить компьютер имел возможность бы при помощи приблизительно таких операторов – if (a[1,1]=0) AND (a[1,2]=0) then a[1,3]:=1. Это очевидный защитный движение компьютера.

Определения констант

Приведем программу вычисления среднегодовой температуры для задания 1 из 12.3.

VAR s,i:Integer; t:array [1..365] of Integer;

BEGIN

for i:=1 to 365 do ReadLn(t[i]);

s:=0;

for i:=1 to 365 do s:=s+t[i];

WriteLn(s/365)

END.

Пускай нам потребовалось переделать эту программу на вычисление средней недельной температуры. Для этого достаточно везде в тексте программы число (константу) 365 заменить на число (константу) 7. В громадных программах одинаковая константа может видеться десятки раз и подобный процесс может настойчиво попросить большого расхода времени. В 10.4 мы уже сталкивались с таковой обстановкой. В том месте мы нашли выход в том, что вместо константы записывали переменную величину. Но в нашем случае этого не окажется, поскольку Паскаль запрещает задавать границу в описании массива переменной величиной. В таких случаях поступают следующим образом. Константе придумывают имя (как переменной), к примеру k, и в особом разделе constей задается значение. Вот отечественная программа с применением константы k:

CONST k =365; {Обратите внимание, что в определении вместо := стоит = }

VAR s,i :Integer;

t :array [1..k] of Integer;

BEGIN

for i:=1 to k do ReadLn(t[i]);

s:=0;

for i:=1 to k do s:=s+t[i];

WriteLn(s/k)

END.

В приведенном виде программа стала универсальной. Сейчас для ее переделки под средненедельную температуру достаточно в одном месте поменять определение k=365 на k=7.

Значению константы не разрещаеться изменяться в ходе исполнения программы, другими словами запрещены операторы вида k:=30 и ReadLn(k). Паскаль присматривает за этим.

Тип константы показывать нельзя[10]. Паскаль сам додумается о типе по записи:

CONST n =800; {тип целочисленный}

e =2.7; {тип Real}

bukva =’ж’; {тип Char}

Slash =’/’; {тип Char}

slovo =’отлично’; {тип String}

OK =true; {тип Boolean}

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

Типизированные константы

В блоке CONST возможно обрисовывать не только константы, но и переменные размеры. Эти переменные размеры по причине того, что они обрисованы в таком необычном месте, покупают неудачное наименование типизированные константы, но переменными быть не перестают, а самое для нас основное — тут им возможно комфортно придавать начальные значения. Вот пример:

CONST n :Integer =800;

e :Real =2.7;

Вот как запишется программа для вычисления средней недельной температуры из 12.4, в случае, если массив t обрисовать как типизированную константу:

CONST k =7; { k — простая, нетипизированная константа}

t :array [1..k] of Integer = (-14, -12, -8, -2, 0, 1, -3);

{ t — типизированная константа}

VAR s,i :Integer;

BEGIN

s:=0;

for i:=1 to k do s:=s+t[i];

WriteLn(s/k)

END.

Тут в круглых скобках задается перечень начальных значений переменной t, то есть: t[1] равняется -14, t[2] равняется -12 и т.д. В разделе операторов эти значения возможно поменять.

Двумерным массивам начальные значения придаются подобно. Так в программе из 12.3 вместо двенадцати присвоений возможно было записать так:

Const k =3; n=4;

t :array [1..k,1..n] of Integer = (( -8,-14,-19,-18),

( 25, 28, 26, 20),

( 11, 18, 20, 25));

…….

Обратите внимание на расстановку скобок.

Придумываем типы данных

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

Запись TYPE bukva = Char

свидетельствует: ТИП bukva равен (эквивалентен) типу Char,

другими словами мы типу Char еще одно наименование bukva. Сейчас все равно, как записать:

VAR a,b:Char

либо VAR a,b:bukva .

Еще примеры: type Vector = array[1..10] of Integer;

matritsa = array[1..8] of Vector;

var a,b :Vector;

c :matritsa;

d :array[1.. 8] of Vector;

Тут мы создали два новых типа с именами Vector и matritsa. Разумеется, переменные c и d обрисованы одинаково. Обратите внимание, что вместо type matritsa = array[1.. 8] of Vector

возможно записать type matritsa = array[1.. 8] of array[1..10] of Integer

либо type matritsa = array[1..8,1..10] of Integer .

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

писать procedure p(a: array[1..10] of Integer) неправильно,

а писать procedure p(a: Vector) верно.

Логический тип Boolean

В операторах if, while, repeat мы привыкли писать выражения вида ab, i2, (ab)AND(ac) и т.п. Про каждое из этих выражений возможно сообщить, действительно оно сейчас либо ложно. К примеру, выражение 32 действительно в любой момент, а выражение i

Говорят, что логическое выражение 32 имеет значение “истина” (по-английскиtrue- “тру”), а логическое выражение i

Внутренняя идеология построения языка Паскаль требует выяснить новый тип переменных — логический тип Boolean. Запись VAR a:Booleanозначает, что переменная aможет принимать всего два значения — true и false. Так, мы можем записать a:=false.

Слова true и false являются логическими константамии их возможно использовать в логических выражениях либо вместо них. К примеру, if a=true then… Конструкцию if (ab)=false then… возможно перевести “в случае, если неправда, что a больше b, то…”.

Значения true и false комфортно использовать для организации нескончаемых циклов:

while true do …….

repeat ……….. until false

Решим конкретный пример на данный тип.

Задача: В группе — 6 студентов. какое количество из них сдали зачет по физике?

Сперва разработаем программу без применения типа Boolean. В ней единицей я обозначил зачет, нулем — незачет. Массив Zachet из 6 элементов хранит данные о зачете.

CONST Zachet :array[1..6] of Integer = (1,1,0,1,1,1);
VAR c,i :Integer;
BEGIN
c:=0; {c — счетчик зачетов}
for i:=1 to 6 do if zachet[i] = 1 then c:=c+1;
WriteLn(c)
END.

Сейчас разработаем программу с применением типа Boolean. В ней через true я обозначил зачет, через false — незачет.

CONST Zachet :array[1..6] of Boolean = (true,true, false, true, true, true);
VAR c,i :Integer;
BEGIN
c:=0;
for i:=1 to 6 do if zachet[i] = true then c:=c+1;
WriteLn(c)
END.

Отличие второй программы от первой в том, что выражение zachet[i] = true (зачет равен истина) выглядит естественнее и понятнее, чем zachet[i] = 1 (зачет равен единице, другими словами колу?). В общем, чуть-чуть нагляднее.

Кстати, в полной мере верно было бы написать и if zachet[i] then …. Так как условием по окончании слова if может находиться любое логическое выражение, имеющее значением true либо false.

Перечислимые типы

В 5.7 я сказал о порядковых типах- это те типы, все значения которых возможно выстроить по порядку и перечислить от начала до конца. Мы до тех пор пока знаем, что в Паскале порядковыми типами являются целочисленные типы, символьный и логический тип . Помимо этого, программист может придумывать личные порядковые типы. Разглядим, к примеру, такую конструкцию:

VAR Month : (january, february, march, april, may, june, july, august, september, october, november, december)

Она свидетельствует, что переменная Month может принимать лишь одно из перечисленных в скобках значений. К примеру, возможно записать Month:= may. Переменная Month есть переменной перечислимого типа, что есть одним из видов порядковых типов.

Эти значения ни за что не являются строчками. Так, нельзя записать Month:= ‘may’. Помимо этого, их нельзя вывести на печать, по большому счету они не смогут быть введены в компьютер либо выведены из него, к примеру, при помощи операторов Read и Write. Но, их комфортно использовать при программировании. Это удобство выяснится из следующего примера.

Задача: Известно, сколько дней в каждом месяце года. какое количество дней летом?

Сперва запишем программу классическим методом.

Программа:

CONST dni :array[1..12] of Byte = (31,28,31,30,31,30,31,31,30,31,30,31);
VAR s,i :Integer;
begin
s:=0; {Сумматор летних дней}
for i:=6 to 8 do s:=s+dni[i]; {Летние месяцы — 6,7,8}
WriteLn(s)
end.

Недочёт приведенной программы — не наилучшая наглядность, к тому же приходится самому на пальцах вычислять конца месяцев и номера начала лета (6 и 8). Паскаль имеет средства повысить удобство и наглядность таких программ. Запишем отечественную программу по-новому, с применением перечислимого типа данных:

TYPE mes = (january, february, march, april, may, june, july, august, september,
october, november, december);
CONST dni :array[january..december] of Byte =
(31,28,31,30,31,30,31,31,30,31,30,31);
VAR s :Integer;
i :mes;
begin
s:=0;
for i:=june to august do s:=s+dni[i];
WriteLn(s)
end.

Пояснения: Главное достижение отечественной программы в том, что в операторе for возможно написать june to august вместо 6 to 8, а в определении массива dni возможно написать array[january..december] вместо array[1..12]. Для этого было нужно выяснить особый перечислимый тип mes, перечислив в скобках произвольные имена месяцев, а переменную цикла i задать типом mes, а не Integer.

Синтаксис перечислимого типа:

(имя , имя , имя , . . . . , имя)

Значения перечислимого типа возможно применять так же вольно, как и значения порядковых типов, к примеру:

if i = february then dni[i]:= 29

Ограниченный тип (диапазон)

Задача: Поезд отправляется в путь в 22 часа и находится в пути 10 часов. Во какое количество он прибывает на место назначения?

Ошибочная программа:

VAR Otpravlenie, Pribitie :Byte;

BEGIN

Otpravlenie:=22;

Pribitie:=Otpravlenie+10;

WriteLn(Pribitie)

END.

Эта программа вместо ответа “8” напечатает ошибки “32” и ответ не увидит. Паскаль не знает, что имеют суть лишь те значения переменной Pribitie, каковые находятся в диапазоне от 0 до 24. Это должен был знать программист, но он также не обратил на это внимания. Хотелось бы, дабы Паскаль вместо выдачи неправильного ответа напоминал забывчивым программистам, что переменная вышла из имеющего суть диапазона. Для этого программист должен иметь возможность данный диапазон Паскалю указать. Такую возможность дает использование диапазонов(ограниченных типов).

Вот программа, обнаруживающая собственную неточность:

VAR Otpravlenie, Pribitie : 0..24;

BEGIN

Otpravlenie:=22;

Pribitie:=Otpravlenie+10;

WriteLn(Pribitie)

END.

Конструкция VAR Otpravlenie, Pribitie : 0..24 свидетельствует, что переменные Otpravlenie и Pribitie есть в праве принимать значения целых чисел в диапазоне от 0 до 24.

Паскаль будет обнаруживать выход за диапазон лишь в том случае, в то время, когда вы установите флажок (крестик) в Options®Compiler…®Compiler Options®Runtime Errors в положение Range Checking (см. часть IV – «Обзор популярных команд меню»).

Диапазон возможно задавать для любого порядкового типа, к примеру:

VAR Month :(january, february, march, april, may, june, july, august, september, october, november, december);

Spring :march..may;

Autumn :september..november;

tsifra :0..9;

Zaglavnie:’А’..’Я’

Диапазон есть одним из видов порядковых типов.

Задание 108: Известны время и дата (месяц, сутки, час, 60 секунд) отплытия теплохода летом этого года из Москвы в Астрахань. Известно время в пути (в днях, минутах и часах). Оно не превышает 20 дней. Выяснить время и дату прибытия теплохода в Астрахань. Применять диапазоны.

Вариант 1: Для простоты предположим, что путешествие начинается между 1 и 10 июня.

Вариант 2. Путешествие начинается в любой сутки лета. Выясните еще и прибытия недели и дни отправления, в случае, если известно, какой сутки семь дней был 1 июня.

[pascal] 3 урок 2 часть. цикл while


Интересные записи:

Понравилась статья? Поделиться с друзьями: