Оператор цикла с постусловием



Конспект лекций

 

по дисциплине « Алгоритмизация и языки про­граммирования» __

 

 

 

Оглавление

Тема 1. ОСНОВЫ АЛГОРИТМИЗАЦИИ ЗАДАЧ. 4
Тема 2. ПРОГРАММИРОВАНИЕ НА БАЗОВОМ ПРОЦЕДУРНО-ОРИЕНТИРОВАННОМ АЛГОРИТМИЧЕСКОМ ЗЫКЕ. ОПЕРАТОР ПРИСВАИВАНИЯ. КОНТРОЛЬНЫЕ ВОПРОСЫ 6   8
Тема 3 АРИФМЕТИЧЕСКИЕ И ЛОГИЧЕСКИЕ ВЫРАЖЕНИЯ.ОРГАНИЗАЦИЯ ВВОДА-ВЫВОДА ДАННЫХ. КОНТРОЛЬНЫЕ ВОПРОСЫ 10     12
Тема 4. ОПИСАНИЕ ЛИНЕЙ­НЫХ И РАЗВЕТВЛЯЮЩИХСЯ СТРУКТУР АЛГОРИТМОВ. ПРОГРАММИРОВАНИЕ РАЗВЕТВЛЯЮЩИХСЯ СТРУКТУР. ПРИМЕРЫ РЕШЕНИЯ ЗАДАЧ 17     20
Тема 5. ОРГАНИЗАЦИЯ ВЫПОЛНЕНИЯ ПРОГРАММ НА ПК. ПРИМЕРЫ РЕШЕНИЯ ЗАДАЧ 22   25
Тема 6. СТРУКТУРЫ ДАННЫХ: МАССИВЫ, МНОЖЕСТВА, ЗАПИСИ.  ОРГАНИЗАЦИЯ ВВОДА-ВЫВОДА МАССИВОВ.     25
Тема 7. ОРГА­НИЗАЦИЯ АЛГОРИТМОВ ЦИКЛИЧЕСКОЙ СТРУКТУРЫ. ПРИМЕРЫ РЕШЕНИЯ ЗАДАЧ КОНТРОЛЬНЫЕ ВОПРОСЫ 28   31 33
Тема 8. ПРОГРАММИРОВАНИЕ ВВОДА-ВЫВОДА МАССИВОВ. СТРОКОВЫЕ ДАННЫЕ. ПРИМЕРЫ РЕШЕНИЯ ЗАДАЧ 39   43
Тема 9. ПОДПРОГРАММЫ. ОБРАЩЕНИЕ К ПОДПРОГРАММАМ. ПРИМЕРЫ РЕШЕНИЯ ЗАДАЧ 45   47
Тема 10. АЛГОРИТМЫ ПОИСКА И СОРТИРОВКИ. ПРИМЕРЫ РЕШЕНИЯ ЗАДАЧ 48 51
Тема 11. ПРОГРАММИРОВАНИЕ В СРЕДЕ DELPHI. ПРИМЕРЫ РЕШЕНИЯ ЗАДАЧ 60 62
Тема 12. РАБОТА С ФАЙ­ЛАМИ. ПРИМЕРЫ РАБОТЫ С ФАЙЛАМИ. 63
Тема 11. ДИНАМИЧЕСКИЕ СТРУКТУРЫ ДАННЫХ. УКАЗАТЕЛИ. РАБОТА С ОЧЕРЕДЯМИ И СТЕ­КОМ. (2 часа) 38
Тема 12. МАШИННАЯ ГРАФИКА.ПРИМЕРЫ ПРОГРАММ С РАЗЛИЧНОЙ СТРУКТУРНОЙ ОРГАНИЗАЦИЕЙ. (1 часа) 44
   
   
   
Приложение А. 47
Литература 51

Тема 1. ПРОГРАММНЫЕ СРЕДСТВА ПК. ОСНОВЫ АЛГОРИТМИЗАЦИИ ЗАДАЧ.

(1 часа)

План лекции 1:

1.  Определение алгоритма.

2. Способы описания алгоритмов

3.  Правила оформ­ления схем алгоритмов.

4. Разновидности структур алгоритмов

 

Алгоритм – это заданная определенным образом последовательность действий, приводящая за конечное число шагов к достижению поставленной цели (к решению поставленной задачи).

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

действие ≡ инструкция ≡ оператор.

Действия (инструкции, операторы) выполняются некоторым исполнителем. Для нас

исполнитель ≡ процессор.

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

1) действия должны быть понятны исполнителю;

2) разные исполнители должны одинаково понимать одни и те же действия.

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

 

Рассмотрим эти конструкции на примерах алгоритмов для вычислений по формулам.

 

Х = А2-1. вход – А,                                                                                            выход – Х

Тогда словесная запись алгоритма будет следующей.

1. Задать значение для А.

2. Умножить А на А, запомнить результат.

3. Из результата п.2 вычесть 1, запомнить результат в переменной Х.

Здесь у нас появилось важное действие – запоминание. Будем называть его присваиванием. Это фундаментальное понятие. Оно связано с понятием память.

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

Этот пример определяет нам первую базовую конструкцию структурного программирования – следование: если в записи алгоритма друг за другом написаны несколько действий, то они будут выполняться последовательно.

Последовательный алгоритм – такой, в котором действия выполняются в том порядке, в каком они написаны (в естественном порядке).

Рассмотрим следующий пример.

 

                         0, x ≤ 0                                      вход - x,

        f =                                                                 выход – f.

                         x2, x > 0

 

Записать алгоритм вычисления f можно следующим образом.

1. Задать значение х.

2. Если х ≤ 0

то   2.1. задать f = 0

иначе 2.2. задать f = x * x.

Получили новую конструкцию, которая задает разветвление в порядке выполнения действий. Такая конструкция называется условной (соответственно алгоритм – условным) или конструкцией ЕСЛИ – ТО – ИНАЧЕ, по-английски IF – THEN – ELSE. Запись в общем виде:

ЕСЛИ условие

ТО последовательность действий 1

ИНАЧЕ последовательность действий 2.

 

Упрощенная или усеченная форма:

ЕСЛИ условие

ТО последовательность действий.

 

Пример . Подсчитать сумму нечетных чисел от 1 до 25.

 

вход – пустой,

выход – S.

 

Алгоритм вычисления S .

Задать S равным 0.

Задать n равным 0.

Пока n ≤ 12 выполнять

3.1. к S добавить 2*n + 1

3.2. увеличить n на 1

 Алгоритм будет работать до тех пор, пока выполняется условие п.3.

Здесь мы получили третью базовую конструкцию – циклическую. Она означает следующее: пока истинно некоторое условие, – делай то-то и то-то. Называется она конструкцией ПОКА – ДЕЛАЙ, по-английски WHILE – DO. Соответствующий алгоритм называется циклическим алгоритмом. Он задает многократное выполнение одних и тех же действий. Запись в общем виде:

ПОКА условие ВЫПОЛНИТЬ

последовательность действий.

Последовательность может выполняться 0,1,…,∞ раз.

Этих трех конструкций (трех типов алгоритмов) достаточно для написания алгоритмов любой сложности.

 

Рассмотрим алгоритм еще с одной точки зрения. Если не вдаваться в его структуру, то любой алгоритм можно представить в виде “черного ящика”:

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

Выход – совокупность переменных и значений, которые получены после вычислений.

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

Семантика – смысловая часть описания языка. Она определяет, как понимать (человеку) и выполнять (машине) алгоритмы.

Синтаксис – набор формальных правил написания алгоритмов на алгоритмическом языке.

 

 

Тема 2. ПРОГРАММИРОВАНИЕ НА БАЗОВОМ ПРОЦЕДУРНО-ОРИЕНТИРОВАННОМ АЛГОРИТМИЧЕСКОМ ЗЫКЕ. КЛАССИФИКАЦИЯ ОПЕРАТОРОВ АЛГОРИТМИЧЕСКОГО ЯЗЫКА. ОПЕРАТОР ПРИСВАИВАНИЯ. ОПЕРАТОРЫ УПРАВЛЕНИЯ. (2 часа)

План лекции 2:

1. Цели и задачи дисциплины "Алгоритмизация и технология программи­рования".

2. Алфавит языка.

3.  Правила записи основных объектов языка.

4. Типы данных. Константы.

5.  Переменные. Метки.

 

Использованный ранее неформальный способ описания алгоритмов отличается следующими недостатками:

· громоздкость и излишняя многословность;

· неоднозначность понимания.

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

Запись алгоритма на языке программирования называется программой. Pascal – разработан в 1968–1971 годах Никлаусом Виртом в Цюрихском Институте Информатики (Швейцария).

Цель-овладеть инструментом для обучения программированию как систематической дисциплине. Обнаружилась чрезвычайная эффективность при применении и надежность программирования.

При конструировании алгоритмического языка необходимо:

· исходить из некоторого набора вычислительных структур (структур данных);

· вводить как составные операции, так и составные (структурированные) объекты;

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

Три составляющие (любого) языка: алфавит, синтаксис и семантика.

Алфавит – набор основных символов, «букв алфавита», никакие другие символы в предложениях языка не допускаются.

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

 

<лексема>::= <буква>|<цифра>|<спецсимвол>

<буква>::= a|b|...|z|A|B|...|Z|_

<цифра>::= 1|2|3|4|5|6|7|8|9|0

<спецсимвол>::= <знак арифметической операции>|

               <знак операции сравнение>|

               <разделитель>|

               <служебное слово>

<знак арифметической операции>::= *| /| +| –

<знак операции сравнения>::= =| <>| <| >| <=| >=

<разделитель>::= .| ,| ;| :| (| )|{| }|{| }| ^| '| #| $| @

Служебные слова – «зарезервированные» слова – служат для определенных целей.

<служебные слова>::= begin| end| var| const| if| then| else| function| for|......

 

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

Пример определения конструкций произвольной длины:

 

Другой вариант определения:

 

 

В общем случае рекурсии не избежать. Для примера опишем конструкции следующего вида (t), ((t)), (((t))), ((((t)))),... .

 

 <слово> ::= (t) | (<слово>)

Правильное определение:

 

С любым элементом данных, используемым в алгоритмическом языке, связано такое понятие языка как переменная. Любая переменная имеет имя (обозначение) и значение.

Имя переменной в Паскале синтаксически описывается с помощью идентификаторов:

<идентификатор>::= <буква>{<цифра>|<буква>}

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

Пример описания переменных:

var

a:integer;

x,y,z:real;

Sinus:real;

Пример описания констант:

const

One=1;

HighLimit=1000;

pi=3.14159265358;

Тип константы определяется по ее значению.

Схема программы:

const

<описания констант>

var

<описания переменных>

begin

<операторы>

end.

 

План лекции 3:

1.  Выражения. Арифметические и логические выражения.

2. Оператор присваивания. Операторы управления.

3. Организация ввода-вывода данных. Структура программы.

4. Переход от схемы алгоритма к схеме программы.

 

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

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

Операнды представляют собой «элементарные» значения; ими могут быть переменные, константы, вызовы функций.

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

a+b+c*2

a/b/c

7-a*(sin(x)+2)

a=b

(2>3)=(7<>10)

pred('x')<x

(not(2>3))or(1=1)

true<=false

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

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

Примеры неправильных выражений:

  2**3

e==3

(2+1))

true+false

not (a) - недопустимо, если a не булевского типа.

 

 

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

 

Это ограничение также связано с тем, что машина может “читать” только последовательность знаков.

X := SIN (A), а также использовать   любую из стандартных функций: COS (X), LN (X), SQRT (X), EXP (X), ABS (X) и т.д. При этом

 

F := (1 – SQRT(X)) / (SIN (2 * X) – COS (X / 2)).

 

 

В результате выполнения оператора присваивания переменная получает значение выражения.

<оператор присваивания> ::= <переменная>:=<выражение>

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

const

pi=3.14159;

var   

 sym,alpha,beta:char;

x,a,b,c,r:real;

i:integer;

begin

.........

x:=0;

i:=i+1; {пример использования предыдущего значения переменной}

c:=sqrt(a*a+b*b);

sym:='+';

alpha:=sym;

 

Идентификатор Описание типа Множество допустимых значений
Shortint 8-битный целый со знаком –128…127
Longint 32-битный целый со знаком –2147483648...2147483647
Byte 8-битный целый без знака 0…255
Word 16-битный целый без знака 0…65535

DIV – деление нацело с отбрасыванием остатка (нахождение целой части результата);

MOD – нахождение остатка от деления.

Для выполнения операций ввода-вывода служат четыре процедуры: read, readln, write, writeln.

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

Вызов процедуры:  read(X1,X2,...,XN);

где X1,X2,...,XN – переменные допустимых типов данных. 

Используя служебные слова begin и end, можно из последовательности операторов сделать составной оператор:

begin

S1;

S2;

.....

SN

end

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

Пример.

PROGRAM P (INPUT, OUTPUT);

VAR A, B, X: REAL;

BEGIN

         WRITE (‘Введи A’);

         READ (A);

         WRITE (‘Введи B’);

         READ (B);

         X := A*B-A;

         WRITE (‘X=’,X);

END.

Значения выводятся в той форме, в какой они описаны, например,

- 2.300000Е+05 - для вещественных чисел.

Для удобства чтения можно указать формат выводимых данных:

WRITE (X:2);          - для целых,

WRITE (Y:10:2);      - для вещественных (10 – общее количество цифр, 2 – количество цифр в дробной части).

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

WRITELN (<список вывода>);

Оператор осуществляет переход к новой строке после печати значений списка.

 

 

Тема 3. ОПИСАНИЕ ЛИНЕЙ­НЫХ И РАЗВЕТВЛЯЮЩИХСЯ СТРУКТУР АЛГОРИТМОВ. ПРОГРАММИРОВАНИЕ РАЗВЕТВЛЯЮЩИХСЯ СТРУКТУР.(1 часа)

План лекции 4:

1. Линей­ные структуры алгоритмов.

2. разветвляющиеся структуры алгоритмов.

3. Классификация операторов алгоритмического языка.

 

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

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

Все метки, используемые в программе (блоке), должны быть описаны в специальном разделе label. Метка представляет собой идентификатор или целое число от 1 до 9999.

Пример:

label

m,1,metka,56;

Оператор, помеченный меткой, имеет вид

<метка>:<оператор>;

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

 

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

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

Условный оператор if C then S1 else S2 выражается с помощью следующей блок-схемы, изображенной на рис. 1

 

 

           Рис. 1

Операторы присваивания (и вызовы подпрограмм) записываются в прямоугольниках. Булевские выражения, управляющие потоком, записываются в ромбах.

Последовательной композиции S1;S2 соответствует соединение блок-схем для S1 и соответственно для S2 с помощью стрелки от S1 до S2 (рис.2).

 

 

                  Рис. 2

Оператору цикла while B do S соответствует блок-схема рисунка 3.

 

 

 

 

 

 

       Рис. 3

 

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

 

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

Пример:

Для того чтобы z стало равным наибольшему из двух чисел x и y, необходимо выполнить присвоение z:=x либо z:=y.

Две формы условного оператора: полная и сокращенная.

<полный условный оператор>::=

if <логическое выражение> then <оператор>

                         else <оператор>                         

Примеры:

if x>y then z:=x

       else z:=y;

if x<0 then begin

               x:=x+h;

               y:=y-h;

               d:= not d

               end

     else begin

            x:=0;

            y:=0

            end;

if x>0 then sgn:=1

       else if x=0 then sgn:=0 else sgn:=-1;

<сокращенный условный оператор>::=

if <логическое выражение> then <оператор>;

Например, оператор x:=abs(x) эквивалентен if x<0 then x:=-x.

Поменять местами значения переменных x и y так, чтобы в x было большее значение:

  if y>x then begin

              t:=x;

              x:=y;

              y:=t

              end;

Ветви then и else могут снова содержать условные операторы, например:

if x>0 then sgn:=1

       else if x=0 then sgn:=0 else sgn:=-1;

Неоднозначность в условном операторе следующего вида:

if B1 then if B2 then S1 else S2

Возможные истолкования

a)  if B1 then begin

          if B2 then S1 else S2

          end;

b)  if B1 then begin if B2 then S1 end

     else S2;

В Паскале используется вариант a).

Вводится последовательность целых чисел, 0 – конец последовательности. Найти два наименьших числа.

Переменные:

x – очередное число;

min1 – первое наименьшее число;

min2 – второе наименьшее число (min2>=min1).

Алгоритм решения задачи:

1) устанавливаем начальные значения min1 и min2 по двум первым числам;

2) последовательно считываем числа и, если очередное число x меньше или равно min1 (min1<min2), то переприсваиваем значение min1 и min2;

3) если x попадает в интервал от min1 до min2, то переприсваиваем только min2;

4) выводим результат.

var x,min1,min2:integer;

begin

  write('Введите x=');

  readln(x);

  min1:=x;

  write('Введите x=');

  readln(x);

  min2:=x ;

                                                                               {min1<=min2}

  repeat

        if x<=min1 then

                            begin

                                 min2:=min1;

                                 min1:=x;

                            end

                           else

                                 if (min1<x) and (x<min2) then min2:=x;

        write('Введите x=');

        readln(x);

until (x=0);

writeln( 'Два наименьших числа равны', min1, 'и', min2);

end.

 

Тема 4. ОРГАНИЗАЦИЯ ВЫПОЛНЕНИЯ ПРОГРАММ НА ПК. СТРУКТУРЫ ДАННЫХ: МАССИВЫ. МНОЖЕСТВА. ЗАПИСИ. (2 часа)

План лекции 5:

1Работа с инструментальными интегрированными турбосистемами.

2 реализация этапов трансля­ции, редактирования и выполнения программ.

3Запись выражений, операторов присваивания.

4Запись программ линей­ных структур алгоритмов на языке Паскаль.

 

Отладка – деятельность, направленная на установление точной природы известной ошибки, а затем на исправление этой ошибки.

Результаты тестирования являются исходными данными для отладки. Последовательность событий:

симптом (ошибки) ® причина (ошибки) ® исправление (ошибки).

 

Как искать ошибку?

1. Поймите ошибку. Какие данные правильные, какие – неправильные?

2. Постройте гипотезу о причине ошибки.

3. Проверьте гипотезу (для этого пропустите новый тест).

4. При подтверждении гипотезы следует внести исправление, а потом повторить все тесты (не внесли ли вы новую ошибку – вероятность этого от 0,2 до 0,5).

Можно пользоваться автоматизированными средствами отладки: в интегрированной среде Паскаля имеется отладчик debug, который предлагает средства отслеживания и трассировки программы (в том числе печать переменных, счетчиков, критических значений).

Парадоксы программной ошибки:

· ошибка - не всегда результат недостатков;

· ошибка не всегда может быть выявлена;

· выявленная ошибка не всегда может быть описана;

· описанная ошибка не всегда может быть понята;

· понятая ошибка не всегда может быть исправлена;

· исправленная ошибка не всегда может улучшить качество программы.

Известна некоторая статистика о программных ошибках.

· Язык C++ дает на 25 % больше ошибок, чем традиционные Си или Паскаль.

· Исправление ошибок в объектно-ориентированных программах на C++ требует в 2-3 раза большего времени. Наследование порождает в 6 раз больше ошибок, чем его отсутствие.

· 33% всех ошибок случаются реже, чем 1 раз за 5000 лет работы системы.

· Каждый Кбайт кода содержит 0,5-2 ошибки.

 

План лекции 6:

1. Структуры данных: Массивы.

2. Множества. Записи.

3. Организация ввода-вывода массивов.  

4. Печать заголовков таблиц с разделением на графы, нумерацией строк, столбцов.

 

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

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

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

· тип элементов массива,

· количество и «способ нумерации» элементов.

type

<идентификатор - тип массива>= array[T1] of T2;

T1 - тип индекса:(ограниченный, литерный,

    перечислимый);

T2 - тип элементов массива (любой тип).

Примеры:

const n=20;

type    vector=array[1..100] of real;

           m=array[char] of boolean;

       matrix=array[1..n] of array[1..n] of integer;

var    v:vector;

         SymTab:m;

       arr1,arr2:matrix;

     s:array['a'..'z'] of boolean;

Мы можем «нумеровать» элементы массива не только целыми числами, но и значениями произвольного дискретного типа (типа, на котором действуют функции ord, succ, pred).

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

Следующие два определения эквивалентны:

v:array[1..10] of array[1..20] of integer;

v:array[1..10,1..20] of integer;

Число индексов (размерность массива) не ограничена.

 

Синтаксис:

<регулярный тип>::=

 

---->array-->[----><тип индекса>--->]--->of--><тип>--->

            |               |

             <---------,---<---

 

Единственное возможное действие над массивом в целом - это присваивание:       v1:=v2;

Типы обоих массивов в данном случае должны совпадать.

Доступ к элементам массива:

<идентификатор массива>[<индекс>]

или

<идентификатор массива>[<список индексов через запятую>]

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

Примеры:    v[1]

      v[(i+2)*6]

Пусть

v2:array[1..10] of array[5..20] of integer

 – двухмерный массив, тогда v2[k] - k-ый массив в группе из 10 массивов целых чисел, v2[k][5] – 5-ый элемент этого массива, тот же элемент получаем и так v[k,5].

Элемент массива считается переменной:

· он может получать значения (например, в операторе присваивания);

· он может участвовать в выражениях там, где может присутствовать переменная данного типа.

Ассортимент операций над элементами массива полностью определяется типом этих элементов.

Примеры:

v2[i,j]:=v2[i,j-1]+1;

SymTab['z']:=not SymTab['a'];

Ошибки в работе с массивами:

Выход индекса за допустимые пределы

var   v:array[0..10] of real;

....

v[11]:=0.5; <==== транслятор обнаружит ошибку

i:=11;

v[i]:=0.5; <==== эта ошибка может быть обнаружена только во время исполнения и то, если осуществляется контроль диапазона, иначе это может привести к          непредсказуемым последствиям

Множественный тип задается с помощью двух служебных слов – set и of – и следующего за ним базового типа. Например:

type digits = set of 1..5;

var s:digits;

Переменная s в качестве значений может принимать следующие множества целых чисел:пустое множество, {1}, …, {5}, {1,2}, …, {4,5}, {1,3,5}, …, {4,5,3,2}, …, {1,2,3,4,5} (всего 32 различных множества).

Обратите внимание:

· Все значения базового типа в множестве должны быть различными.

· Порядок «расположения» элементов в множестве никак не фиксируется.

Базовый тип множества может быть:

символьным, перечислимым, ограниченным.

Базовый тип должен содержать не более 256 значений.Если базовый тип – ограниченный целый, то значения должны быть в диапазоне от 0 до 255.

Пример:

type

elemColor =(red,yellow,blue);

color = set of elemColor;

Задача. Ввести последовательность из n чисел и распечатать ее с конца. var

i:integer;

s:array[1..100] of integer;

begin

writeln('Введите количество чисел');

readln(n);

writeln('Введите ',n,' чисел');

for i:=1 to n do  read(s[i]); {ввод потоком}

writeln; writeln('Вывод:');

for i:=n downto 1 do write(s[i],' ') end.

В отличие от массивов, компоненты записи обозначаются идентификаторами.

type     person = record

        name,secondName,surName:string;

        sex :(male,female);

        speciality:integer

        end;

Элементы записи называются полями. Каждое описание поля выглядит как описание простой переменной.

Структура записи:

· фиксированное число полей;

· каждое поле имеет имя (уникальное в пределах записи, но может совпадать с любым идентификатором вне этой записи);

· каждое поле имеет произвольный тип.

Описание переменных комбинированного типа:

 var    Sasha,Masha:person;

Доступ к полям записи осуществляется с помощью селектора записи – конструкции вида

<переменная типа записи>.<идентификатор поля>

Использование:

Sasha.name:='Александр';

Masha.name:='Мария'; Masha.Speciality:=Sasha.Speciality;

Тема 5. ОРГА­НИЗАЦИЯ АЛГОРИТМОВ ЦИКЛИЧЕСКОЙ СТРУКТУРЫ. АЛГОРИТМИЧЕСКОЕ ОПИСА­НИЕ ВЛОЖЕННЫХ ЦИКЛИЧЕСКИХ СТРУКТУР. (1 часа)

План лекции 7:

1. Циклические структуры с за­данным числом повторений.

2. Итерационные циклы.

3. Вложенные циклические структуры

 

Оператор цикла с параметром

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

Оператора цикла определяет:

· диапазон изменения значений управляющей переменной и, одновременно, число повторений оператора, содержащегося в теле цикла;

· направление изменения значения переменной (возрастание или убывание);

· собственно действия, выполняемые на каждой итерации (оператор тела цикла).

<оператор цикла с параметром>::=

  for <переменная> := <диапазон> do <оператор>

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

   <выражение> <направление> <выражение>

<направление>::= to | downto

На использование управляющей переменной (параметра) налагаются следующие ограничения:

1. Управляющая переменная должна иметь дискретный тип (целый, символьный, булевский, перечислимый).

2. Начальные и конечные значения диапазона должны иметь тот же тип, что и параметр.

3. В теле цикла запрещается явное изменение значения управляющей переменной (например, оператором присваивания).

4. После завершения оператора значение параметра становится неопределенным.

Семантику данного оператора цикла можно представить следующим образом. Оператор  

for V := Expr1 to Expr2 do Body;

эквивалентен оператору:

begin

Temp1:=Expr1;

Temp2:=Expr2;

if Temp1 <= Temp2 then

   begin

   V:=Temp1;

   Body;

   while V <> Temp2 do

     begin

     V:=succ(V);

     Body

     end

   end

end

Примеры:

{y=x^n}

y:=1;

for i:=1 to n do y:=y*x;

{печать латинского алфавита с конца}

for c:='z' downto 'a' do write(c);

 

while <логическое выражение> do | заголовок цикла

             <оператор>    | тело цикла

Оператор цикла с предусловием.

Тело цикла повторяется, пока истинно предусловие.

Примеры:

   {s=сумма целых чисел от 1 до n}

   s:=0;i:=1;

   while i<=n do

       begin

       s:=s+i;

       i:=i+1

       end

{x1=наибольший общий делитель x и y}

x1:=x;y1:=y;

while x1<>y1 do

   if x1>y1 then x1:=x1-y1

            else y1:=y1-x1;

 

{Для данного M>0 требуется найти наименьшее целое число k>=0, такое что 3^k > M}

y:=1;k:=0;

while y<=M do

   begin

   k:=k+1;

   y:=y*3;

   end;

Оператор цикла с постусловием

Число повторений заранее неизвестно, но известно условие, при выполнении которого цикл должен завершиться.

repeat {<оператор>} until <логическое выражение>

Цикл с постусловием всегда выполняется, по крайней мере, один раз!

Пример. Вычислить наименьшее n, для которого y=1+1/2+1/3+...+1/n ³ 5.

y:=0;n:=0;

repeat

n:=n+1;

y:=y+1/n;

until y>=5;

Примеры бесконечных циклов

y:=0;i:=1;

while i<=n do y:=y+1/i;i:=i+1;

while true do <оператор>

{Вычислить площадь под параболой f(x)=x2 от a=0 до b=10 по формуле трапеции S=h*[f(a)/2+f(a+h)+f(a+2*h)+...+f(b-h)+f(b)/2],где h=(b-a)/n }

 

h:=(b-a)/n;

S:=h*(a*a+b*b)/2;

x:=a;

repeat

x:=x+h;

S:=S+x*x*h

until x=b-h; {Нужно x>=b-h, иначе равенство может и не выполниться}

 

Тема 6. ПРОГРАММИРОВАНИЕ ВВОДА-ВЫВОДА МАССИВОВ. СТРОКОВЫЕ ДАННЫЕ. БИБЛИОТЕКА СТАНДАРТНЫХ ПОДПРОГРАММ. (1 часа)

План лекции 8:

1. Программирование обработки числовых массивов

2. Задачи упорядочения компонент массивов.

3. Ввода-вывод строковых данных.

4. Программирование задач обработки сим­вольных данных.

5. Использование библиотеки подпрограмм для решения задач.

 

Элемент массива считается переменной:

· он может получать значения (например, в операторе присваивания);

· он может участвовать в выражениях там, где может присутствовать переменная данного типа.

Напечатать матрицу построчно.

for i:=1 to n do

  begin

  for j:=1 to m do

               write(s[i,j],' ');

  writeln

  end;

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

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

<описание строкового типа>::=

              string | string[<максимальная длина строки>]

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

Пример:

  type

line=string[80];

var

myLine:line;

myLineShort:string[10];

Описание

Var St: string[80];

резервирует для St 81 байт памяти. Если учесть, что на каждый символ отводится один байт, возникает естественный вопрос, а откуда взялся еще один байт, 81-й, а точнее, нулевой байт? Дело в том, что после того как переменной St присвоено какое-то значение, нулевой байт содержит фактическую длину строки St. Длина строки в байтах при этом равна значению кода символа, находящегося в St[0].

Например, присваивание

St := ‘abcdefgh’;

дает такой результат:

 

St[0] = Chr(8).

St[1] = ‘a’.

St[8] = ‘h’.

Фактическая длина строковой переменной St равна Ord(St[0]). Значение 255 для верхнего предела длины строки объясняется тем, что одиночный байт может принимать 256 различных значений от 0 до 255.

Символьный массив, в отличие от строки, может быть очень большим!

Операция конкатенации (сцепления) применяется для соединения (сцепления) нескольких строк в одну результирующую строкуНапример, выражение 'Т ' + 'у' + 'р' + +'бо' + 'паскаль' дает 'Турбо паскаль'.

Пример:

myLine:='Короткая строка'; {длина 15}

myLine:=MyLine+' стала длинее'; {длина 28}

myLine:=''; {длина 0}

Операции сравнения =,<>,>,<,>=,<=

При сравнении строк используется лексикографический порядок:

а) сравнение строк производится с первых символов (слева направо) до первого несовпадающего символа, и та строка считается больше, в которой первый несовпадающий символ больше;

б) если строки имеют различную длину и одна строка полностью входит во вторую, то более короткая строка меньше, чем более длинная.

Пример:

'abcd'>='abc'

'abcde'>'aacde'>'aacdd'

Элементы строки нумеруются целыми числами, начиная с 1.

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

a:string[6] a:='группа 1';   'группа'

a:string[8] a:='группа 1';   'группа 1'

a:string[2] a:='группа 1';   'гр'

Стандартная функция Length(<выражение строкового типа>). Значение функции есть текущая длина строки – фактического параметра.

Пример:

var myLine:string;

   i:integer;

  .....

for i:=1 to Length(myLine) do

   myLine[i]:=chr(ord(myline[i])+1);

 

Нет полной идентичности между строковыми типами и символьными массивами, поэтому возможна ошибка при работе с элементами строки без учета ее текущей длины.

Пример:

var

str:string[26];

i:integer;

begin

str:='A';

for i:=1 to 26 do

str[i]:=chr(ord('A')+i-1);

writeln(str)

end.

Предполагается, что данная программа сформирует строку из 26 букв латинского алфавита, но печать writeln(str) дает просто A! Объяснение: присваивание значений элементам строки не влияет на ее текущую длину (здесь текущая длина = 1).

Правильная программа:

var

str:string[26];

i:integer;

begin

str:='';

for i:=1 to 26 do

str:=str+chr(ord('A')+i-1);

writeln(str)

end.

Стандартные процедуры и функции для работы со строковыми типами

Процедура

delete(var St:string;Poz:integer;N:integer)

производит удаление N символов строки St, начиная с позиции Poz. Если Poz>255, то осуществляется программное прерывание.

St:='abcdef';

delete(St,4,2);

writeln(St); ====> abcf

St:='река Волга';

delete(St,1,5);

writeln(St); ====> Волга

Процедура

insert(Source:string;var S:string;Index:integer)

осуществляет вставку строки Source в строку S, начиная с позиции Index.

S:='Золотойключик';

insert(' ',S,8);

writeln(S); =====> Золотой ключик

Функция copy(S:string;Index:integer;Count:integer):string

Функция выделяет из строки S подстроку длиной Count символов, начиная с позиции Index.

Если Index > length(S), то возвращается пустая строка.

Если Count+Index > length(S), то возвращается конец строки.

Если Index > 255, то диагностируется ошибка при выполнении.

copy('abcdefg',2,3)='bcd'

copy('abcdefg',4,10)='defg'

Функция

concat(S1,S2,...,SN:string):string

производит соединение последовательности строк, эта функция равносильна операции конкатенации +.

Функция  

pos(Substr:string;S:string):integer

обнаруживает первое появление в строке S подстроки Substr. Результат равен номеру той позиции, где начинается подстрока Substr. Если подстроки нет, то результат равен 0.

pos('de','abcdef')=4

pos('z','abcdef')=0

Имеются две процедуры преобразования числовых значений в строковые и наоборот: Str и Val. Процедура Str при обращени к ней вида

Str(num, strnum);

где num – значение числового типа, а strnum – переменная строкового типа, присваивает переменной strnum строковое значение. Процедура Val выполняет обратное преобразование. Обращение к ней имеет вид:

Val(strnum, num, errcode);

Третий параметр в этой процедуре равен нулю при успешном выполнении преобразования. В том случае, когда первый параметр содержит символы, недопустимые при записи числа, значение параметра errcode равно номеру позиции с ошибочно заданным символом.

Пример использования процедур Str и Val дается ниже:

var

i, errcode: Integer;

S: String;

begin

Str(2000,S);

Writeln('Строковое значение ',S);

Readln;

Val(S, i, errcode);

  If errcode <> 0 then

  Writeln('Ошибка ввода в позиции: ', errcode)

else

  Writeln('Числовое значение = ', i);

Readln;

End. 

В этом примере вначале выполняется преобразование целочисленного значения 2000 в строковое (обращение к процедуре Str), а затем, наоборот, строка символов «2000» преобразуется в значение типа Integer (процедура Val).

 

 

Тема 7. ПОДПРОГРАММЫ, ИХ КЛАССИФИКАЦИЯ. (1 часа)

План лекции 9:

1. Способы оформления подпрограмм.

2.  Обращение к подпрограммам.

3. Передача фактических параметров.

 

Интерфейс подпрограммы или, иными словами, та информация, которая «представляет» подпрограмму и достаточна для корректного ее вызова, сосредоточена в заголовке.

Синтаксически любая программа выглядит следующим образом

<необязательный заголовок программы><блок>.

<необязательный заголовок программы>::=

     program <идентификатор>;

<блок>::=

<описания типов, переменных, подпрограмм и т.п.>

begin <операторы> end

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

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

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

Синтаксические диаграммы Пример:

Выходной параметр S у процедуры str4 имеет вещественный тип, поэтому лучшим решением является использование не процедуры, а функции.

var AB,BC,CD,AD,BD:real;

function str4(a,b,c:real):real;

  {функция вычисляет площадь треугольника со                    сторонами a, b и c} var p:real;

begin p:=(a+b+c)/2;

S:=sqrt(p*(p-a)*(p-b)*(p-c)) end;

begin read(AB,BC,CD,AD,BD);

 writeln('площадь=',str4(AB,AD,BD)+str4(BC,CD,BD));end.

Имеются два различных способа передачи фактических параметров в подпрограммы. Если в описании формального параметра ему предшествует var, то этот способ называется передачей параметра по ссылке, а сам параметр называется параметром-переменной. Если var отсутствует, то такой параметр называется параметром-значением, а способ – передачей параметра по значению.

Параметры-значения

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

Пример:    var a,b:integer;

procedure h(x:integer;var y:integer);

begin   x:=x+1; y:=y+1;

  writeln(x,' ',y); end;

begin a:=0;b:=0;

h(a,b);          =====> печать: 1 1

writeln(a,' ',b) =====> печать: 0 1 end.

Тема 8. АЛГОРИТМЫ ПОИСКА И СОРТИРОВКИ. (1 часа)

План лекции 10:

1. Алгоритмы поиска: линейный поиск

2. Алгоритмы поиска: поиск с барьером

3. Алгоритмы сортировки: сортировка выбором

4. Алгоритмы сортировки: сортировка обменом (методом "пузырька")

 

Задача поиска состоит в отыскании в последовательности элемента (или нескольких элементов) с заданными свойствами его значения. Например, найти элемент с наибольшим (наименьшим) значением или найти элемент с заданным значением.

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

1. Инициализация цикла.

2. Пока есть элементы делай

Начало

2.1. Сравнить эталон с очередным элементом последовательности

2.2. Перейти к следующему элементу.

Конец.

Анализируем п.1. Нужно задать номер того элемента, с которого начнется сравнение, и определить эталон. Если в качестве эталонной переменной MIN выберем x 1, то можно начать цикл с элемента номер 2. Тогда

1. I:=2; MIN:=X[1];

Условие п.2. означает, что текущий номер элемента I не превысил заданную длину последовательности: I≤N.

Шаг 2.1. – условный оператор. Его особенность – в отсутствии действий после иначе, поэтому можем записать укороченную форму оператора

2.1. IF X[I]<MIN

THEN MIN:=X[I];

Шаг 2.2. – в увеличении индекса I на 1:

2.2. I:=I+1;

Объединяя шаги детализации, получим алгоритм:

Ввод (последовательность Х);

I:=2; MIN:=X[1];

WHILE I<=N DO

BEGIN

 IF X[I]<MIN

 THEN MIN:=X[I];

 I:=I+1;

END;

Вывод (MIN);

Простой выбор

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

Идея метода такова. Найдем в последовательности элемент с наименьшим значением и поменяем его местами с первым элементом. Затем проделаем те же действия с оставшимися N-1 элементами, затем с N-2 и так далее до тех пор, пока не останется один элемент – последний. Он будет наибольшим.

Проиллюстрируем процесс (табл.2.4).

 

Таблица 2.4 – Пример сортировки простым выбором

Номер элемента 1 2 3 4 5 6 7 8
Исходная последовательность 72 14 6 98 17 51 25 33
После выбора среди 8 элементов 6 14 72 98 17 51 25 33
7 элементов 6 14 72 98 17 51 25 33
6 элементов 6 14 17 98 72 51 25 33
5 элементов 6 14 17 25 72 51 98 33
4 элементов 6 14 17 25 33 51 98 72
3 элементов 6 14 17 25 33 51 98 72
                               2 элементов 6 14 17 25 33 51 72 98
Упорядоченная последовательность 6 14 17 25 33 51 72 98

Для составления алгоритма снова воспользуемся методом пошаговой детализации. Отметим, что для получения результата нам нужно N-1 раз находить минимальное значение в последовательности, длина которой каждый раз уменьшается. Кроме того, так как минимальный элемент нужно менять местами с определенным элементом последовательности, то номер минимального элемента нужно запоминать.

Обобщенно наш алгоритм можно записать так.

1. I:=1;

2. Пока I ≤ N-1

Начало

2.1. найти минимальный элемент и его номер в последовательности AI, …, AN.

2.2. поменять местами AI и минимальный элемент.

2.3. I:=I+1;

Конец

Алгоритм поиска минимального элемента и его номера мы рассмотрели ранее, поэтому

2.1.

K:=I;

X:=A[I];

J:=I+1;

WHILE J<=N DO

BEGIN

         IF A[J]<X

         THEN BEGIN

                     X:=A[J];

                     K:=J;

         END;

         J:=J+1;

END;

В результате значением Х будет значение минимального элемента среди АI, ... AN, а значением К - номер этого элемента. Поэтому п. 2.2. можно записать конкретнее:

2.2. поменять местами элементы Ai и Ak

Это можно сделать так:

2.2. C:=A[I]; А[I]:=A[K]; A[K]:=C;

Однако в нашей ситуации дополнительная переменная С не нужна, так как ее роль играет Х из п. 2.1. Поэтому запишем:

2.2. A[K]:=A[I]; A[I]:=X;

Мы сэкономили на одном присваивании, а так как действие выполняется в цикле, то это немало.

Теперь запишем полностью алгоритм сортировки простым выбором.

Ввод (последовательность А);

I:=1;

WHILE I<=N-1 DO

BEGIN

  K:=I;

  X:=A[I];

J:=I+1;

       WHILE J<=N DO

         BEGIN

                     IF A[J]<X

                     THEN

                     BEGIN

                              X:=A[J];

                                 K:=J;

                     END;

                     J:=J+1;

         END;

  A[K]:=A[I];

  A[I]:=X;

I:=I+1;

END;

                                     

Тема 9. ПРОГРАММИРОВАНИЕ В СРЕДЕ DELPHI. (1 часа)

План лекции 11:

1. Обзор интегрированной среды разработки

2. Классы компонентов

3. Свойства элементов

 

Для знакомства со средой программирования Delphi потребуется рассказать о составе первой страницы Палитры Компонент.

    На первой странице Палитры Компонент размещены 14 объектов

(рис.1) определенно важных для использования. Мало кто обойдется длительное время без кнопок, списков, окон ввода и т.д. Все эти объекты такая же часть Windows, как мышь или окно.

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

Рис.1: Компоненты, расположенные на первой странице Палитры.

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

TMainMenu позволяет Вам поместить главное меню в программу. При помещении TMainMenu на форму это выглядит, как просто иконка. Иконки данного типа называют "невидимыми компонентом", поскольку они невидимы во время выполнения программы. Создание меню включает три шага: (1) помещение TMainMenu на форму, (2) вызов Дизайнера Меню через свойство Items в Инспекторе Объектов, (3) определение пунктов меню в Дизайнере Меню.

TPopupMenu позволяет создавать всплывающие меню. Этот тип меню появляется по щелчку правой кнопки мыши.

TEdit - стандартный управляющий элемент Windows для ввода. Он может быть использован для отображения короткого фрагмента текста и позволяет пользователю вводить текст во время выполнения программы.

TMemo - иная форма TEdit. Подразумевает работу с большими текстами. TButton позволяет выполнить какие-либо действия при нажатии кнопки во время выполнения программы. Нужно заполнить заготовку кодом (подчеркнуто то, что нужно написать вручную):

procedure TForm1.Button1Click(Sender: TObject);

begin

MessageDlg('Are you there?',mtConfirmation,mbYesNoCancel,0);

end;

TCheckBox отображает строку текста с маленьким окошком рядом. В окошке можно поставить отметку, которая означает, что что-то выбрано. Например, если посмотреть окно диалога настроек компилятора (пункт меню Options | Project, страница Compiler), то можно увидеть, что оно состоит преимущественно из CheckBox’ов.

TRadioButton позволяет выбрать только одну опцию из нескольких. Если Вы опять откроете диалог Options | Project и выберете страницу Linker Options, то Вы можете видеть, что секции Map file и Link buffer file состоят из наборов RadioButton.

TListBox нужен для показа прокручиваемого списка. Классический пример ListBox’а в среде Windows - выбор файла из списка в пункте меню File | Open многих приложений. Названия файлов или директорий и находятся в ListBox’е.

TComboBox во многом напоминает ListBox, за исключением того, что позволяет водить информацию в маленьком поле ввода сверху ListBox. Есть несколько типов ComboBox, но наиболее популярен выпадающий вниз (drop-down combo box), который можно видеть внизу окна диалога выбора файла.

TScrollbar - полоса прокрутки, появляется автоматически в объектах редактирования, ListBox’ах при необходимости прокрутки текста для просмотра.

TGroupBox используется для визуальных целей и для указания Windows, каков порядок перемещения по компонентам на форме (при нажатии клавиши TAB).

TPanel - управляющий элемент, похожий на TGroupBox, используется в декоративных целях. Чтобы использовать TPanel, просто поместите его на форму и затем положите другие компоненты на него. Теперь при перемещении TPanel будут передвигаться и эти компоненты. TPanel используется также для создания линейки инструментов и окна статуса.

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

    Это полный список объектов на первой странице Палитры Компонент. Если Вам нужна дополнительная информация, то выберите на Палитре объект и нажмите клавишу F1 - появится Справочник с полным описанием данного объекта.

Инспектор Объектов состоит из двух страниц, каждую из которых можно использовать для определения поведения данного компонента. Первая страница - это список свойств, вторая - список событий. Если нужно изменить что-нибудь, связанное с определенным компонентом, то Вы обычно делаете это в Инспекторе Объектов. К примеру, Вы можете изменить имя и размер компонента TLabel изменяя свойства Caption, Left, Top, Height, и Width.

Тема 10. РАБОТА С ФАЙ­ЛАМИ. РАЗЛИЧНЫЕ ТИПЫ ФАЙЛОВ.

(1 часа)

План лекции 12:

1. Переменные файловых типов

2. Установочные и завершающие операции над файлами

3. Примеры работы с файлами

 

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

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

<файловый тип>::= file of <тип>

Тип элементов может быть любым, за исключением файлового.

Пример:    type sequence=file of char;

    var F1,F2:sequence; inputData:file of real;

Стандартные процедуры: assign, reset, rewrite, close. Процедура assignпредназначена для установления связи между конкретным физическим файлом на магнитном носителе и переменной файлового типа, которая будет являться представителем этого файла в программе.

assign(<идентификатор – файловая переменная>,<строковое выражение>);

Значение второго параметра – литеральное имя файла. Имя файла строится по правилам, принятым в операционной системе MS-DOS для именования файлов.

Пример:

assign(f,'d:\mydir\myfile.dta');

После выполнения данного вызова файловая переменная f будет связана с файлом myfile.dta в каталоге mydir диска d.

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

· con - консоль, т.е. для случая вывода информация помещается на экране дисплея, а в случае ввода информация воспринимается с клавиатуры;

· prn - вывод на принтер;

· kbd - ввод с клавиатуры без «эха»;

· nul - фиктивное (несуществующее) устройство. Может использоваться для вывода информации «в никуда», когда в программе почему-либо нужно указать имя выходного файла, а информация, записываемая в него, не требуется.

Процедуры reset и rewrite имеют один параметр – файловую переменную и предназначены для открытия файлов. При этом файловая переменная, указываемая в качестве параметра, должна быть уже связана с конкретным дисковым файлом с помощью процедуры assign. Rewrite используется, и когда файл еще не существует, а если существует, то он очищается. Процедура close имеет один параметр – файловую переменную и завершает действия с файлом – ликвидируются внутренние буферы, образованные при открытии этого файла.

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

Процедуры write и read, в отличие от многих других процедур, могут вызываться с различным числом параметров, и эти параметры могут иметь различные типы.

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

Если указатель файла указывает на «конец файла», то чтение невозможно. Функция eof(<файловая переменная>) – булевская функция, равна истине, если имеется ситуация «конец файла».

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

Порядок выполнения процедуры write:

· Значение очередной переменной будет помещено в файл в место, отмеченное текущим указателем.

· После этого текущий указатель будет передвинут на одну позицию и действия повторяются для следующей переменной из списка параметров.

var s:string[126];

    f:text;

begin

  assign(f,'name.pas');

  reset(f);

  while not eof(f) do

    begin readln(f,s); write(s) end;

  close(f)

end.

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

var

textInf:text;

Структура текстовых файлов отличается от структуры обычных файлов (линейная последовательность элементов одного типа) тем, что содержимое текстового файла рассматривается как последовательность символьных строк переменной длины, разделенных специальной комбинацией, называемой «конец строки». Как правило, эта комбинация строится из управляющего кода «перевод каретки» (символ #13), за которым, возможно, следует управляющий код «перевод строки»(символ #10). Текстовый файл завершается специальным кодом «конец файла» (символ #26).

Открытие текстового файла для чтения выполняет процедура reset. Открытие текстового файла для записи выполняет процедура rewrite.

Логическая функция eoln(<файловая переменная>) возвращает true, если текущая строка исчерпана, и false в противном случае.

 

 

Тема 11. ДИНАМИЧЕСКИЕ СТРУКТУРЫ ДАННЫХ. УКАЗАТЕЛИ. РАБОТА С ОЧЕРЕДЯМИ И СТЕ­КОМ. (2 часа)

План лекции 13:

1. Ссылочный тип

2. Статические, динамические переменные

 

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

Ссылочный тип определяется в следующем виде:

type

<имя ссылочного типа>=^<имя базового типа>;

Примеры:

type

mas=array[1..10] of integer;

Ptr= ^integer;

link = ^mas;

linkchar = ^char;

tie = ^real;

Описание переменных ссылочного типа:

var

p:ptr;

v:link;

a:^real;

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

Указатель nil считается константой, принадлежащей любому ссылочному типу. Иными словами, это значение можно присваивать любому указательному типу.

· Сравнение на равенство (=), сравнение на неравенство (<>)

– ссылаются ли два указателя на одно и то же место в памяти?

Примеры: var p1,p2:ptr;

......

sign:=p1=p2;

if p1<>nil then ....

 

Для того чтобы по указателю на переменную получить доступ к самой этой переменной, необходимо после переменной-указателя поставить знак '^'; p1^ есть «переменная», на которую ссылается p1. Такая конструкция может находиться в любом контексте, в котором допустимо нахождение самой указываемой переменной. Если p1 имеет тип ^integer, то p1^ имеет тип integer.

Разыменование некорректно, если ссылочная переменная имеет значение nil.

Поэтому    p1:=nil;

      p1^:=2;

некорректно и приводит к трудно распознаваемым ошибкам.

Пример:    var p1,p2:^integer;

Пусть переменные p1^ и p2^ уже имеют значения 1 и 2 соответственно (как это сделать - смотрите ниже). Тогда различные результаты следующих присваиваний изображены на рис. 1.

p1:=p2;

p1^:=p2^;       

Исходное состояние:

 

 


После присваивания p1:=p2

 


После присваивания p1^:=p2^

 

 


Рис.1 Различия в присваиваниях

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

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

 

Процедура new(<переменная ссылочного типа>) предназначена для создания динамической переменной:

· в динамической области памяти отводится место для хранения переменной, тип которой совпадает с базовым типом указателя-переменной;

· переменной, переданной в параметре, присваивается указатель на отведенную область памяти.

Пример:   type

 mas=array[1..10] of integer; link=^mas;

var t:link;

........

new(t);

Отводится память, достаточная для хранения массива типа mas. Переменной t присваивается адрес этой памяти. Теперь возможен доступ к элементам массива, например:

t^[i]:=0;

t^[i]:=t^[j];

Переменная t является статической, место в памяти для ее значения выделено при трансляции. Переменная t^ – динамическая, она появляется только при выполнении процедуры new(t).

Процедура dispose(<переменная ссылочного типа>) служит для освобождения памяти, отведенной с помощью процедуры new с той же переменной.

Рис. 2 иллюстрирует применение процедур new и dispose (переменные p1 и p2 имеют тип ^integer):

 


new(p1);new(p2);   


p1^:=1; p2^:=2;    

 


p1:=p2;          

 


dispose(p2);     

 

 

Рис. 2 - Результат выполнения фрагмента

 

План лекции 14:

1. Линейный список

2. Циклически связанный список

 

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

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

type

link = ^node;

node = record

          info:string;

          next:link

        end;

var     s,p:link;

Мы можем создать с помощью этого типа список, изображенный на рис. 5:

 


Рис. 1 - Список элементов типа link

Переменная – ссылка s - указывает на первую компоненту списка. По-видимому, самое простое действие, которое можно выполнить со списком, показанным на рисунке 1, это вставить в его начало некоторый элемент (рис. 2).

new(p);        

p^.info:='Петров';

p^.next:=s;

s:=p;

 

 

Рис. 2 - Вставить элемент в начало списка

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

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

s:=nil; {начали с пустого списка}

while n>0 do

begin

   new(p); p^.next:=s;

   read(p^.info);

   s:=p;n:=n-1  end;

Добавление в конец списка

procedure add (var s:link; m:string);

{s указывает на голову списка}

var t,p:link;

begin

if s=nil then begin

              new(s);

              s^.info:=m;

              s^.next:=nil

              end

else begin

    t:=s;

    while t^.next <> nil do t:=t^.next;

    new(p);

    t^.next:=p;

    p^.info:=m;

    p^.next:=nil;

    end;

end;

var

s:link; m:string; i:integer;

begin

s:=nil;

for i:=1 to 10 do begin

                read(m);

                add(s,m)

                end;

end.

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


Дата добавления: 2020-12-12; просмотров: 78; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!