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

Часть 2-Основы программирования (Delphi)

.pdf
Скачиваний:
65
Добавлен:
09.06.2015
Размер:
1.93 Mб
Скачать

Константы определяют области памяти, которые не могут изменять своего значения в ходе работы программы. Как и любые другие элементы программы, константы могут иметь свои собственные имена. Объявлению имен констант должно предшествовать зарезервированное слово Const (от англ. constants - константы). Например, мы можем определить константы

const

Kbyte = 1024; n=100;

Тип константы определяется способом ее записи и легко распознается компилятором в тексте программы, поэтому программист может не использовать именованные константы (т. е. не объявлять их в программе явно).

В качестве констант в Object Pascal могут использоваться целые, вещественные и шестнадцатеричные числа, логические константы, символы, строки символов, конструкторы множеств и признак неопределенного указателя NIL.

Целые числа записываются со знаком или без него по обычным правилам и могут иметь значение в диапазоне от -263 до +263-1. Следует учесть, что, если целочисленная константа выходит за указанные границы, компилятор дает сообщение об ошибке. Такие константы должны записываться с десятичной точкой, т. е. определяться как вещественные числа.

Вещественные числа записываются со знаком или без него с использованием десятичной точки и/или экспоненциальной части.

Экспоненциальная часть начинается символом е или Е, за которым могут следовать знаки “+” или “-” и десятичный порядок. Символ е(Е) означает десятичный порядок и имеет смысл “умножить на 10 в степени”. Например,

3.14Е5 - 3,14 умножить на 10 в степени 5;

-17e-2 -минус 17 умножить на 10 в степени минус 2.

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

Шестнадцатеричное число состоит из шестнадцатеричных цифр, которым предшествует знак доллара $ (код символа 36).

Логическая константа - это либо слово false (ложь), либо слово true (истина). Символьная константа - это любой символ ПК, заключенный в апострофы: 'z' - символ “z”; 'Ф' - символ “Ф”.

Строковая константа - любая последовательность символов, заключенная в апострофы. Если в строке нужно указать сам символ апострофа, он удваивается, например: 'Это - строка символов'; 'That''s string'.

Строка символов может быть пустой, т. е. не иметь никаких символов в обрамляющих ее апострофах. Строку можно составлять из кодов нужных символов с предшествующими каждому коду символами #, например, строка

#83#121#109#98#111#108 эквивалентна строке ' Symbol '.

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

должна строиться переменная. Разделу объявления переменной (переменных) должно предшествовать слово Var. Например:

var

inValue: Integer; byValue: Byte;

Здесь идентификатор inValue объявляется как переменная типа Integer, а идентификатор byValue - как переменная типа Byte. Стандартный (т. е. заранее определенный в Object Pascal) тип integer определяет четырехбайтный участок памяти, содержимое которого рассматривается как целое число в диапазоне от –2147483648 до +2147483647, а стандартный тип Byte - участок памяти длиной 1 байт, в котором размещается беззнаковое целое число в диапазоне от 0 до 255.

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

Первоначальное знакомство с типами начнем со строкового типа String. Этот тип определяет участок памяти переменной длины, каждый байт которого содержит один символ. Для символов в Object Pascal используется тип Char, таким образом, String - это цепочка следующих друг за другом символов Char. Каждый символ в String пронумерован, причем первый символ имеет номер 1. Программист может обращаться к любому символу строки, указывая его порядковый номер в квадратных скобках сразу за именем переменной:

var // Начало раздела описания переменных

S: String; // Объявление переменной строкового типа

begin

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

S := 'Строка символов';

//Переменная S содержит значение ”Строка символов” S[6] := 'и'; // Теперь переменная содержит значение

//”Строки символов”

end;

// Конец раздела исполняемых операторов

Программист обязан объявить любой вводимый им идентификатор. Идентификатор S неизвестен Delphi - он введен нами для переменной строкового типа. После его объявления в разделе переменных Delphi выделит для него начальную область памяти минимальной длины и будет контролировать

использование этого идентификатора в разделе исполняемых операторов. Например, если в этом разделе встретится выражение

2*S-1

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

После первого присваивания (:=) S будет занимать участок памяти длиной 15 байт - по одному байту на каждый символ значения. [На самом деле переменная строкового типа всегда имеет длину 4 байта, которые используются для указания на область памяти, в которой помещается сама строка символов.] Переменность размера области памяти, выделяемой для размещения строки символов, - характерная особенность типа string.

Над строковым типом определена операция сцепления (+):

S := 'Object'+' Pascal';// S содержит “Object Pascal”

Целые типы используются для хранения и преобразования целых чисел. В Object Pascal предусмотрено несколько целочисленных типов, отличающихся диапазоном возможных значений. Пока будем использовать тип Integer, занимающий в памяти 4 смежных байта и предназначенный для хранения целых чисел в диапазоне от -2147483648 до +2147483647.

Над целыми числами определены следующие математические операции: +, –, *, div (деление с отбрасыванием остатка), mod (получение остатка от деления).

Спецификой деления является то обстоятельство, что результат может иметь дробный вид. Для хранения дробных чисел в Object Pascal используются вещественные типы, например тип Real (диапазон значений 5,0*10-324…1,7*10308), вот почему в языке имеются целых две операции деления (div и mod):

var

X,Y: Integer; begin

X := 5 div 2; // X содержит 2

Y := 5 mod 2; // Y содержит 1

end;

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

Метки - это имена операторов программы. Метки используются очень редко и только для того, чтобы программист смог указать компилятору, какой оператор программы должен выполнятся следующим. Метки, как и переменные, всегда объявляются в программе. Разделу объявлений меток предшествует зарезервированное слово Label (метка). Например:

label

Loop; begin

Goto Loop;

//Программист требует передать управление

//оператору, помеченному меткой Loop.

.....

//Эти операторы будут пропущены

Loор:

//Оператору, идущему за этой меткой,

//будет передано управление

.....

end;

Подпрограммы - это специальным образом оформленные фрагменты программы. Замечательной особенностью подпрограмм является их значительная независимость от остального текста программы. Говорят, что свойства подпрограммы локализуются в ее теле. Это означает, что, если программист чтолибо изменит в подпрограмме, ему, как правило, не понадобится в связи с этим изменять что-либо вне подпрограммы. Таким образом, подпрограммы являются средством структурирования программ, т. е. расчленения программ на ряд во многом независимых фрагментов. Структурирование неизбежно для крупных программных проектов, поэтому подпрограммы используются в Delphi-программах очень часто.

В Object Pascal есть два сорта подпрограмм: процедуры и функции. Функция отличается от процедуры только тем, что ее идентификатор можно наряду с константами и переменными использовать в выражениях, т. к. функция имеет выходной результат определенного типа (об этом позже). Имя процедуры нельзя использовать в выражении, т. к. процедура не имеет связанного с нею результата.

Чтобы заставить Delphi самостоятельно сделать заготовку для процедуры обработчика события OnClick, дважды подряд без заметной паузы щелкните мышью по вновь вставленному компоненту (например, кнопке). В ответ Delphi активизирует окно кода, и вы увидите в нем, например, такой текстовый фрагмент:

procedure TForm1.Button1Click(Sender: TObject); begin

end;

Слово procedure извещает компилятор о начале подпрограммы-процедуры. За ним следует имя процедуры TForm1.Button1Click. Это имя - составное: оно состоит из имени класса TForm1 и собственно имени процедуры Button1Click (вторая часть имени). Если Delphi автоматически формирует заготовку для обработчика, то вторая часть имени представляет собой объединение имени компонента и имени события без предлога On.

За именем процедуры TForm1.Button1Click в круглых скобках следует описание параметра вызова Sender: TObject (параметр с именем Sender принадлежит классу TObject). Как мы увидим дальше, процедуры могут иметь не один, а несколько параметров вызова или не иметь их вовсе. Параметры вызова (если они есть) служат для настройки реализованного в процедуре алгоритма на выполнение конкретной работы. Параметр Sender вставлен Delphi “на всякий случай”: с его помощью подпрограмма Button1Click может при желании определить, какой именно компонент создал событие OnClick.

Вся строка в целом

procedure TForm1.Button1Click(Sender: TObject);

называется заголовком процедуры. Две следующие строки определяют тело процедуры. Слово begin (начало) сигнализирует компилятору о начале последовательности предложений, описывающих алгоритм работы процедуры, а слово end (конец) - о конце этой последовательности. В нашем случае тело

процедуры пока еще не содержит описания каких-либо действий: Delphi лишь создала заготовку для процедуры, но она ничего “не знает” о том, для чего эта процедура предназначена. Наполнить тело нужными предложениями - задача программиста. Каждый раз при нажатии кнопки Button1 управление будет передаваться в тело процедуры, значит между словами begin и end можно написать фрагмент программы, который будет выполняться в ответ на это событие. Например:

procedure TForm1.Button1Click(Sender: TObject); begin

ShowMessage(‘Обработчик события’); end;

Вставленная строка реализует обращение к стандартной процедуре, которая отображает окно сообщения с кнопкой ОК.

Пример программы

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

Подготовим форму Form1, имеющую две строки ввода Edit1 и Edit2 (для вводимых чисел), одну кнопку Button1 (для запуска программы) и метку Label1 (для вывода результата).

Теперь все готово к кодированию программы.

Дважды щелкните по кнопке Button1 и введите такой код для обработчика события OnClick этой кнопки:

procedure TForm1.Button1Click(Sender: TObject); var

x,y: Integer; begin

//Преобразуем текст из Edit1 в целое число x := StrToInt(Trim(Edit1.Text));

//Преобразуем текст из Edit2 в целое число y := StrToInt(Trim(Edit2.Text));

//Показываем результат вычисления произведения

Label1.Caption := 'Произведение ’ + Edit1.Text + ’и‘ + Edit2.Text + ‘равно’ +IntToStr(x*y);

end;

Комментарий к программе

Обработчик события OnClick содержит оператор присваивания, в правой части которого располагается выражение

StrToInt(Trim(edit1{2}.Text))

Это выражение состоит из вызова стандартных для Object Pascal функций: сначала вызывается функция Trim, которая возвращает строку-аргумент (в нашем случае Edit1{2}.Text) без обрамляющих ее (т. е. ведущих и ведомых) пробелов; затем с помощью вызова StrToInt строка символов преобразуется к целому числу.

Функция преобразования StrToInt очень чувствительна к возможным ошибкам символьного представления целого числа. Большую часть возможных ошибок можно блокировать фильтрующими возможностями редактора MaskEdit (использовать его вместо компоненты Edit) и функцией Trim. Иначе программа

аварийно завершится, например, если при щелчке по кнопке Button1 поля ввода не содержат текста.

Выражения

Спомощью знаков операций и скобок из констант, переменных и обращений

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

Частным случаем выражения может быть просто одиночный элемент, т. е. константа, переменная или обращение к функции. Значение такого выражения имеет, естественно, тот же тип, что и сам элемент. В более общем случае выражение состоит из нескольких элементов (операндов) и знаков операций, а тип его значения определяется типом операндов и видом примененных к ним операций.

Примеры выражений:

у

(а + b) * с sin(t)

а > 2

NOT Flag AND (a = b)

В Object Pascal определены следующие операции:

унарные NOT, @ ;

мультипликативные *, /, DIV, MOD, AND, SHI, SHR; аддитивные +, -, OR, XOR;

отношения =, <>, <, >, <=, >=, IN.

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

Унарная операция @ применяется к операнду любого типа и возвращает результат типа pointer, в котором содержится адрес операнда. Если операция @ применяется к процедуре, функции или методу в объекте, ее результатом будет адрес точки входа в эту процедуру (функцию, метод). Этот адрес можно использовать только в подпрограмме, написанной на Ассемблере, или во фрагментах INLINE.

В Object Pascal определены следующие логические операции: NOT - логическое НЕ; AND - логическое И; OR - логическое ИЛИ; XOR - исключительное ИЛИ.

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

К логическим же в Object Pascal обычно относятся и две сдвиговые операции над целыми числами:

i SHL j - сдвиг содержимого / на j разрядов влево; освободившиеся младшие разряды заполняются нулями;

i SHR j - сдвиг содержимого i на j разрядов вправо; освободившиеся старшие разряды заполняются нулями.

o ОПЕРАТОРЫ ЯЗЫКА

Оператор присваивания

Составной оператор и пустой оператор

Условный оператор

Операторы повторений

Оператор выбора

Метки и операторы перехода

Операторы являются важнейшим инструментом языка программирования. Они, выполняя роль инструкций, задаваемых для ЭВМ, указывают, какие операции надо выполнить, в какой последовательности, над какими данными и т.д. Программа

– это последовательность операторов, реализующих алгоритм задачи.

По составу операторы могут быть простые, не содержащие в себе других операторов, и структурные, объединяющие один или несколько операторов. К простым операторам относятся оператор присваивания, перехода, процедуры, а к структурным – условный, выбора, цикла, составной оператор.

Оператор присваивания

Оператор присваивания служит для вычисления значения выражения и присваивания этого значения переменной.

Общий вид записи оператора: v:=<Выражение>;

где v – идентификатор переменной.

Запишем оператор присваивания для вычисления выражения X + 3 Y :

z:=Abs(x)+3*y;

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

Составной оператор и пустой оператор

Составной оператор - это последовательность произвольных операторов программы, заключенная в операторные скобки - зарезервированные слова begin

... end. Составные операторы - важный инструмент Object Pascal, дающий возможность писать программы по современной технологии структурного программирования (без операторов перехода goto).

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

Поскольку зарезервированное слово end является закрывающей операторной скобкой, оно одновременно указывает и конец предыдущего оператора, поэтому ставить перед ним символ “;” необязательно. Наличие точки с запятой перед end означает, что между последним оператором и операторной скобкой end располагается пустой оператор. Пустой оператор не содержит никаких действий, просто в программу добавляется лишняя точка с запятой. В основном пустой оператор используется для передачи управления в конец составного оператора: как и любой другой, пустой оператор может быть помечен, и ему можно передать управление.

Условный оператор

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

Структура условного оператора имеет следующий вид:

if <условие> then <оператор1> else <оператор2>;

где if/ then/ else - зарезервированные слова (если, то, иначе); <условие> - произвольное выражение логического типа; <оператор1>, <оператор2> - любые операторы языка Object Pascal.

Условный оператор работает по следующему алгоритму. Вначале вычисляется условное выражение <условие>. Если результат есть True (истина), то выполняется <оператор1>, а <оператор2> пропускается; если результат есть False (ложь), наоборот, <оператор1> пропускается, а выполняется <оператор2>. Например:

var

X, Y, Max: Integer; begin .

if X > Max then

Y := Max else Y := X;

….

end;

При выполнении этого фрагмента переменная y получит значение переменной х, если только это значение не превышает мах, в противном случае y станет равно мах.

Условными называются выражения, имеющие одно из двух возможных значений: истина или ложь. Такие выражения чаще всего получаются при сравнении переменных с помощью операций отношения =, <>, >, >=, <, <=. Сложные логические выражения составляются с использованием логических операций and, or, xor и not. Например:

if (а > b) and (b <> 0) then ...

Часть else <оператор2> условного оператора может быть опущена. Тогда при значении True условного выражения выполняется <оператор1>, в противном случае этот оператор пропускается.

Поскольку любой из операторов <оператор1> и <оператор2> может быть любого типа, в том числе и условным, а в то же время не каждый из “вложенных” условных операторов может иметь часть else, то возникает неоднозначность трактовки условий. Эта неоднозначность в Object Pascal решается следующим образом: любая встретившаяся часть else соответствует ближайшей к ней сверху по тексту программы части then условного оператора. Например:

If b1 Then a1 Else If b2 Then a2 Else a3;

Если выражение b1 имеет значение True, то выполняется оператор a1, в противном случае проверяется условие b2. Если выражение b2 имеет значение True, то выполняется оператор a2, в противном случае – оператор a3.

Операторы повторений

В языке Object Pascal имеются три различных оператора, с помощью которых можно запрограммировать повторяющиеся фрагменты программ.

Счетный оператор цикла FOR имеет такую структуру:

for <параметр_цикла> := <нач_знач> to <кон_знач> do <оператор>;

Здесь for, to, do - зарезервированные слова (для, до, выполнить); <параметр_цикла> - переменная типа Integer (точнее, любого порядкового типа); <нач_знач> - начальное значение - выражение того же типа; <кон_знач> - конечное значение - выражение того же типа; <оператор> - произвольный оператор Object Pascal.

При выполнении оператора for вначале вычисляется выражение <нач_знач> и осуществляется присваивание <параметр_цикла> := <нач_знач>. После этого циклически повторяется:

проверка условия <параметр_цикла> <= <кон_знач>; если условие не выполнено, оператор for завершает свою работу;

выполнение оператора <оператор>;

наращивание переменной <параметр_цикла> на единицу.

Таким образом, шаг наращивания параметра цикла строго постоянен и равен

(+1).

Существует другая форма оператора:

for <пар_цик>:= <нач_знач> downto <кон_знач> do <оператор>;

Замена зарезервированного слова to на downto означает, что шаг наращивания параметра цикла равен (-1), а управляющее условие приобретает вид <параметр_цикла> >= <кон_знач>.

Пример. В качестве иллюстрации применения оператора for рассмотрим программу, осуществляющую ввод произвольного целого числа N и вычисление суммы всех целых чисел от 1 до N (подсчет любых сумм - положительных и отрицательных).

На форму помещены текстовое поле Edit1 (ввод целого числа N), кнопка Button1 (выполнение вычислений) и метка Label1 (вывод результата).

Создайте такой обработчик Button1Сlick:

procedure TForm1.Button1Click(Sender: TObject); var

i,N,Sum : Integer; begin

try // Преобразуем ввод с контролем правильности

N := StrToInt(Edit1.Text);

except //Следующие операторы выполняются, если есть ошибка

ShowMessage('Ошибка ввода целого числа'); Exit // Завершаем работу обработчика

end;

Sum := 0; // Начальное значение суммы if N >= 0 then

for i := 1 to N do Sum := Sum + i

else

for i := -1 downto N do Sum := Sum + i ; Label1.Caption:='Сумма всех целых чисел в диапазоне 1...' +IntToStr(N)+' равна '+IntToStr(Sum);

end;

Комментарий к программе

С помощью зарезервированных слов try (попробовать), except (исключение) и end реализуется так называемый защищенный блок. Такими блоками программист может защитить программу от краха при выполнении потенциально опасного участка. Если текст в однострочном редактируемом

текстовом поле Edit1 не содержит правильное представление целого числа, попытка выполнить оператор

N := StrToInt(Edit1.Text);

в обычной программе привела бы к аварийному завершению программы. Чтобы этого не произошло, защищаем этот оператор, расположив его за try и перед except. Если ошибки нет, все операторы, стоящие за except и до end, пропускаются и обработчик нормально срабатывает. Если обнаружена ошибка, возникает так называемая исключительная ситуация (исключение) и управление автоматически передается оператору, стоящему за except, - начинается обработка исключения. Вначале с помощью стандартной процедуры ShowMessage сообщается пользователю об ошибке, затем с помощью вызова стандартной процедуры Exit аварийно завершается работа обработчика (но не программы!).

Замечание. Если вы запустите программу из среды Delphi, исключение будет сначала перехвачено средой и на экране появится сообщение на английском языке о характере и месте возникновения ошибки. В этом случае надо закрыть окно с сообщением и продолжить работу программы, тогда можно будет увидеть окно процедуры ShowMessage.

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

Оператор цикла WHILE с предпроверкой условия: while <условие> do <оператор>;

Здесь while, do - зарезервированные слова (пока [выполняется условие], делать),

<условие> - выражение логического типа; <оператор> - произвольный оператор

Object Pascal.

Если выражение <условие> имеет значение True, то выполняется <оператор>, после чего вычисление выражения <условие> и его проверка повторяются. Если <условие> имеет значение False, оператор while прекращает свою работу.

Для вычисления суммы всех целых чисел от 1 до N (N – положительное) можно записать следующий оператор цикла с предусловием:

Sum := 0; i := 1;

while i <= N do begin

Sum := Sum + i; i := i + 1;

end;

Оператор цикла REPEAT... UNTIL с постпроверкой условия: repeat <тело_цикла> Until <условие>;

Здесь repeat, until - зарезервированные слова (повторять [до тех пор], пока [не будет выполнено условие]); <тело_цикла> - произвольная последовательность операторов Object Pascal; <условие> - выражение логического типа.

Операторы <тело_цикла> выполняются хотя бы один раз, после чего вычисляется выражение <условие>: если его значение есть False, операторы <тело_цикла> повторяются, в противном случае оператор repeat…until завершает свою работу.