Главная страница

программирование на паскале2. Учебное пособие по курсу Высокоуровневые методы информатики и программирования для студентов Гуманитарноприкладного института


Скачать 0.89 Mb.
НазваниеУчебное пособие по курсу Высокоуровневые методы информатики и программирования для студентов Гуманитарноприкладного института
Анкорпрограммирование на паскале2.doc
Дата25.05.2018
Размер0.89 Mb.
Формат файлаdoc
Имя файлапрограммирование на паскале2.doc
ТипУчебное пособие
#19648
страница3 из 10
1   2   3   4   5   6   7   8   9   10

1.3. Операторы преобразования данных

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


Оператор присваивания осуществляет преобразование внутренних данных. Он имеет вид

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

Оператор присваивания означает, что вычисляется выражение, стоящее справа от знака присваивания (:=), и вычисленное значение присваивается переменной, стоящей слева от знака присваивания. Переменная может иметь индексы.

Переменная и выражение должны иметь одинаковый тип; имеются два исключения из этого правила:

  • можно использовать вещественные или целые типы разной мощности (например, integer – shortint), при этом значение результата должно принадлежать диапазону допустимых значений для типа переменной – см. таблицы 1-4;

  • переменой вещественного типа можно присваивать выражение целого типа (но не наоборот!).

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

Примеры

k:=k+1;{увеличение значение k на единицу}

S:=S+a; {значение переменной S увеличивается на a}

p:=p*i; {значение переменной р увеличивается в i раз}

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

1.3.2. Понятие ввода и вывода


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

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

Последовательность значений на входном (или выходном) устройстве часто называют потоком.

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

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

1.3.3. Оператор вывода


Оператор вывода имеет вид:

WRITE(V1,V2,...,VN)

и означает вывод на экран монитора значений выражений V1,V2,...,VN (без перехода к следующей строке по окончании вывода). Последовательность V1,V2,...,VN называется списком вывода. В частности, элементом списка вывода Vi, i=1,...,M, может являться переменная (простая или с индексом11) или константа.

Оператор WRITELN означает переход к новой строке (т.е. вывод символа конца строки).

Оператор WRITELN(V1,V2,...,VN) эквивалентен двум операторам

WRITE(V1,V2,...,VN); WRITELN

Вместо Vi (i=1,2,...,N) может стоять группа:

Vi:Li:Mi,

где Li - минимальная длина поля значения переменной (если длина поля избыточна, то поле слева заполняется пробелами; если недостаточна, то транслятор автоматически увеличивает длину); если Li не указано, то используется стандартное для данной среды программирования значение.

Mi - длина дробной части, указывается только для вещественных чисел; если параметр Мi указан, то вещественное число выводится в формате с фиксированной точкой, иначе - в экспоненциальном формате, причем используется стандартный для данной среды программирования вид экспоненциального формата.

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

Пример.

Var s:real; a,b:integer;

begin…

writeln(‘a=’,a, ‘ b=’,b);

writeln(‘ s=’, s:4:1);…

end.

На экран будет выведена информация в виде:

a= b=

s=

Здесь конструкция <имя переменной> означает значение этой переменной. Заметим, что следующие значения будут выводиться с новой строки, так как для вывода s использовался оператор writeln. Такое схематичное изображение выводимой (или вводимой) информации называется формой вывода (ввода).

Если a=-2, b=93, s=3.22, то на экране получим:

a=-2 b= 93

s= 3.2

Примеры оператора WRITELN также представлены на рис.1.

1.3.4. Оператор ввода


Оператор

READ(V1,V2,...,VN)

означает ввод значений переменных V1,V2,..., VN. Переменные могут иметь индексы. Константы и выражения в списке ввода недопустимы, так как не подлежат изменению.

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

Приведенный выше оператор эквивалентен последовательности операторов:

READ(V1);READ(V2);...;READ(VN)

Оператор READLN предусматривает пропуск вводимых символов до нажатия клавиши Enter, т. е. до ввода символа конца строки (END OF LINE).

Оператор READLN(V1,V2,...,VN) эквивалентен двум операторам

READ(V1,V2,...,VN); READLN

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

READ(V1);READ(V2);...;READ(VN);READLN

Оператор ввода с клавиатуры всегда предваряется выводом фразы, приглашающей к вводу. Иначе пользователь может только догадываться, по какой причине программа находится в состоянии ожидания; такая ситуация является необъяснимым остановом и может интерпретироваться как “зависание” компьютера.

Пример.

Var i:integer; a:real;

begin

writeln(‘Введите i и a’); { вывод приглашения к вводу }

readln(i, a);...{оператор ввода}

Форма ввода:

Введите i и a


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

1.4. Разработка простейших программ

1.4.1. Понятие о качестве программы и основные технологические принципы разработки программ


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

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

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

На получение качественных программ направлены положения структурного программирования, которые в основном сводятся к следующим моментам:

  1. Использование точно обозначенных управляющих структур алгоритмов, имеющих один вход и один выход. Такие структуры называются базовыми (см. п.1.4.4).

  2. Разработка алгоритма методом нисходящего проектирования. Этот метод состоит в разбиении алгоритма на части (подалгоритмы) и установлении между ними связей. Каждый подалгоритм должен иметь один вход и один выход, связь между подалгоритмами устанавливается посредством базовых алгоритмических структур. Каждый подалгоритм в свою очередь разбивается на части, и процесс повторяется. Таким образом, получаем иерархическую последовательную разработку алгоритма от сложного к простому.

  3. Независимость подалгоритмов друг от друга на каждом этапе нисходящего проектирования. Следствием этого требования является ограниченное использование глобальных переменных подпрограммами.

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

Грамотное проектирование качественных программ состоит из следующихэтапов:

  1. Анализ задачи и разработка внешней спецификации программы. Во внешнюю спецификацию входит описание входных и выходных данных программы, форм ввода и вывода (см. п.1.3), а также описание методов решения задачи, способов апробации программы, сведения о разработчике программы.

  2. Проектирование структур данных и алгоритма.

  3. Написание (кодирование) программы на алгоритмическом языке.

  4. Отладка программы.

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

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

Лучшим способом уменьшения числа ошибок является тщательное выполнение этапов 1 и 2.

Грамотный и аккуратный программист каждый из рассмотренных этапов документирует.

1.4.2. Алгоритм и способы его записи.


Алгоритм – это представление процесса решения некоторой задачи в виде совокупности конечного числа элементарных действий. Слово "алгоритм" произошло от латинского перевода имени выдающегося ученого-энциклопедиста Мухаммеда Аль Хорезми (780-850), которые впервые описал правила (т. е. алгоритмы) десятичной арифметики.

Строгое определение алгоритма дается в теории алгоритмов. Здесь лишь стоит отметить, что алгоритм должен обладать следующими свойствами:

  1. Универсальность (массовость) - это возможность решения с помощью алгоритма класса задач (не одной задачи). Класс задач определяется областью возможных значений исходных данных.

  2. Конечность (результативность) - обязательное получение результата за конечное число действий.

  3. Определенность означает, что при многократном выполнении алгоритма с одними и теми же исходными данными мы получим одинаковые результаты; другими словами, определенность - это отсутствие случайности.

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

Разработчик программы перед записью ее на алгоритмическом языке обычно обдумывает ее "по шагам". Такое обдумывание очень удобно систематизировать в виде блок-схемы. Написание программы на алгоритмическом языке по готовому алгоритму называется кодированием.

1.4.3. Изображение алгоритмов в виде блок-схем


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

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

  2. Блок ввода или вывода. Изображается как параллелограмм (см. рис.2,б). Внутри записывается пояснение, например, "ввод а,b" или "вывод суммы". Имеет один вход и один выход, также как и вычислительный блок.

  3. Условный блок. Изображается ромбом (рис.2,в), внутри которого записывается некоторое условие (соотношение или более сложное логическое условие). Имеет один вход и два выхода. Один из выходов (его обозначают "да", или "истина", или "+") соответствует пути алгоритма, где условие выполняется. Другой выход ("нет", "ложь", " ") соответствует невыполнению условия.

  4. Блок начала алгоритма (рис 2, г). Имеет только выход, входа нет.

  5. Блок конца алгоритма (рис. 2, д). Имеет только вход.

1.4.4. Базовые структуры алгоритмов и их кодирование
на Паскале


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

1. Следование

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

2. Ветвление (развилка)

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

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

if условие then

оператор 1

else

оператор 2

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

Возможна ситуация, когда ветвь “Нет ” не содержит операторов В этом случае в условном операторе слово else и оператор 2 отсутствуют.

Если операторы 1 или 2 состоят из нескольких операторов (являются составными), то входящие в них операторы окаймляются операторными скобками begin-end:

if условие then

begin

оператор 1_1;

оператор 1_2;



оператор 1_N

end

else

begin

оператор 2_1;

оператор 2_2;



оператор 2_M

end

Таким образом, операторные скобки begin-end позволяют объединить несколько операторов в один составной.
3. Цикл

Ц

.

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

цикл-пока

цикл-до

while условие do

тело цикла

Repeat

тело цикла

until условие

Тело цикла должно представлять собой один оператор – простой или составной.

Замечания

  1. Каждая из трех рассмотренных базовых структур имеет один вход и один выход. Это очень важно, так как любой прямоугольник на рисунках 3 – 5 может представлять собой одну из базовых структур.

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

Кроме того, в программировании широко используется еще одна базовая структура (избыточная), которая называется параметрическим циклом (см. рис.6). Этот цикл управляется переменной (так называемым параметром цикла, на блок-схеме для него выбрано имя i), которая меняется от начального значения до конечного с заданным шагом (в Паскале шаг равен единице). Разработчиками компилятора параметрический цикл может быть реализован и как цикл с предусловием, и как цикл с постусловием. Учитывая практику последнего времени, мы считаем, что параметрический цикл реализован как цикл с предусловием.

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

for i:=нач_значtoкон_значdo

тело цикла;

Существует также вариант оператора for, в котором параметр изменяется с шагом –1:

for i:=нач_значdowntoкон_значdo

тело цикла;

Как и для предыдущих операторов, тело цикла – один оператор, простой или составной.

1.4.5. Примеры разработки программ


Пример 1. Программа решения квадратного уравнения

ax2 + bx + c=0

Исходные данные: a, b, c - коэффициенты уравнения, вещественные переменные.

Выходные данные: х1, х2 - значения двух корней уравнения, если дискриминант неотрицателен, и значения вещественной и мнимой частей комплексно-сопряженных корней, если дискриминант отрицателен; это также вещественные переменные.

Промежуточные данные: d - дискриминант уравнения, вещественная переменная.

Блок-схема алгоритма представлена на рис.7. Алгоритм должен разделяться на две ветви в зависимости от знака дискриминанта, поэтому он использует базовую структуру ветвление. Ввод исходных данных,вычисление и анализ d соединены последовательно (используется базовая структура следование).

По этой блок-схеме написана программа:

Program kv_ur;

Var a,b,c,x1,x2,d:real;

Begin

Writeln ('введите коэффициенты уравнения');

Readln(a,b,c);

d:=sqr(b)-4*a*c;

if d>=0 then

begin

x1:=(-b-sqrt(d))/2/a;

x2:=(-b+sqrt(d))/2/a;

writeln('действ. корни уравнения х1=', x1, ' x2=',x2)

end

else

begin

x1:=-b/2/a;

x2:=sqrt(-d)/2/a;

writeln(‘уравнение имеет комплексно-сопряженные корни’);

writeln('мнимая часть компл. корней х2=',x2);

writeln('действит. часть компл. корней х1=',x1)

end;

Readln;{для задержки экрана с результатами}

End.





Пример 2. Составить программу решения следующей задачи.

На начало первого из рассматриваемых месяцев вклад клиента в банке был равен a руб. В течение каждого следующего месяца со счета снимается b руб.; в конце каждого месяца на остаток вклада начисляется р%. Вывести величину вклада на начало 1, 2,...n месяца.

Исходные данные: a, b, p - вещественные переменные, n - целая переменная.

Выходные данные: i - номер месяца, v - величина вклада на начало месяца.

Блок-схема алгоритма приведена на рис. 8.
Program primer2;

Var a,b,p,v:real; n,i:integer;

Begin

Writeln('Введите a,b,p,n');

Readln(a,b,p,n);

If a
writeln('a,b недопустимы')

else

begin

v:=a;

i:=1;

while (i<=n) and (v>=b) do

begin

writeln(i:7, v);

v:=v-b;

v:=v*(1+p/100);

i:=i+1

end

end;

Readln;

End.

Обратите внимание, что при v

1.5. Массивы

1.5.1. Понятие массива.
Основные правила работы с массивами в Паскале


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

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

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

Упорядоченность компонент массива означает, что они пронумерованы. "Достать" компоненту можно указав ее номер (индекс) или номера, потому что у одной компоненты может быть несколько номеров; например, оценка в сводной ведомости успеваемости студентов характеризуется двумя номерами - номером студента и номером предмета. В Паскале индексы указываются в квадратных скобках.

Количество индексов у элементов массива называется размерностью массива. Массив размерности 1 называется также одномерным, размерности 2 - двумерным, и т. д. Двумерные массивы также называются матрицами.

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

В Паскале начальное значение каждого индекса может быть любым целым значением, как положительным, так отрицательным или нулевым. В примерах этого пособия поддерживается естественная нумерация элементов, начиная с единицы. Так, одномерный массив а из двадцати элементов имеет элементы а[1], a[2],...,a[20]. Элементы двумерного массива (матрицы) b с размерами 3 и 5 можно представить в виде таблицы из 3 строк и 5 столбцов. Принято считать, что первый индекс является номером строки, а второй - номером столбца таблицы:

b[1][1] b[1][2] ... b[1][5]

b[2][1] b[2][2] ... b[2][5]

b[3][1] b[3][2] ... b[3][5]

При описании массивов необходимо указать начальное и конечное значение всех его индексов. Описание M-массива имеет вид:

имя: array[нач_знач1..кон_знач1] ...[ нач_значM..кон_значM] of тип;

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

Например,

Var a: array[1..20] of integer; {одномерный массив – вектор - из 20 элементов целого типа}

b: array[1..3,1..5] of real;{двумерный массив – матрица - из 3 строк и 5 столбцов – вещественного типа}

c:array [1..N] of integer; { одномерный массив из N элементов целого типа, описание допустимо только в том случае, если N- константа, определенная в разделе констант}

a1:array[0..19] of real;{одномерный массив из 20 элементов}

a2:array[-9..10] of real; { одномерный массив из 20 элементов }

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

AR1=ARRAY [1..10,1..10] OF REAL

Такое задание типа массив должно находиться в разделе типов Паскаль-программы. Раздел типов начинается с ключевого слова Type и предназначен для определения нестандартных (т. е. не встроенных в алгоритмический язык) типов. Другие примеры нестандартных типов (кроме типа массив) будут рассмотрены ниже. Поскольку при описании типов могут потребоваться константы, а сами типы нужны при объявлении переменных, разумным12 является следующий порядок следования разделов: констант, типов, переменных.

Для описания переменных Х, У этого типа в разделе переменных может присутствовать инструкция :

Х: AR1; У: AR1; {эквивалентно Х, У: AR1; }

Двумерные массивы располагаются в памяти по строкам, многомерные - так, что чаще меняются правые индексы.

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

1.5.2. Примеры программ с массивами


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

Таблица 6. Состав данных примера 1.

Имя

Смысл

Тип13

Структура

Исходные данные

а

заданный массив

вещественный

одномерный массив из 20 элементов

Выходные данные

s

сумма положительных элементов массива

вещественный

простая переменная

k

количество неположительных элементов

целый

простая переменная

Промежуточные данные

i

счетчик элементов массива

целый

простая переменная

Алгоритм состоит из ввода исходных данных, цикла, в котором накапливаются s и k, и вывода результатов. Цикл управляется переменной i, которая изменяется от 0 до 19. Перед циклом накапливаемым переменным присваиваются начальные значения (нулевые, так как прибавление нуля не изменяет сумму). Основной частью тела цикла является ветвление. Блок-схема алгоритма приведена на рис. 9. Далее приведена Паскаль-программа.





program primer_1_5_2;

Var a:array[1..20] of real; s:real; k,i:integer;

Begin

writeln('Введите массив из 20 элементов');

{Далее цикл для поэлементного ввода массива}

for i:=1 to 20 do

read(a[i]);

readln; {Далее алгоритм по блок-схеме}

s:=0; k:=0;

for i:=1 to 20 do

if a[i]>0 then

s:=s+a[i]

else

k:=k+1;

writeln(' s=',s,' k=',k);

readln{задержка экрана с результатами до нажатия ENTER}

End.

Пример 2. Дан массив а из N элементов (N10). Вычислить произведение элементов массива, меньших заданного значения с.

Таблица 7. Состав данных примера 2.

Имя

Смысл

Тип

Структура

Исходные данные

с

заданное значение

веществ.

простая переменная

N

число элементов массива

целый

простая переменная

а

заданный массив

веществ.

одномерный массив из 10 элементов

Выходные данные

р

произведение элементов массива, удовлетворяющих условию

веществ.

простая переменная

Промежуточные данные

i

счетчик элементов массива

целый

простая переменная

k

количество элементов, удовлетворяющих условию

целый

простая переменная

Обратите внимание, что структура массива а предполагает отведение под а десяти ячеек памяти. В программе описывается массив а из десяти элементов, a используются лишь первые N них. Пользователь данной программы должен помнить, что вводимое значение числа элементов массива должно находиться в интервале 1N10. Проверка корректности введенного значения N, несомненно, улучшила бы надежность программы; с целью упрощения программы мы не делаем такой проверки. Для устранения необходимости распределения памяти под массив «по максимуму» в любом алгоритмическом языке , требующем компиляции, следует использовать операторы динамического распределения памяти, но этот материал выходит за границы данного пособия.

Блок-схема алгоритма приведена на рис. 10. Алгоритм не сильно отличается от рассмотренного в примере 1. Остановимся на различиях. Для накапливания произведения необходимо перед циклом переменной р присвоить начальное значение 1 (умножение на 1 не изменяет произведение). Переменная k нужна для выявления ситуации отсутствия элементов, меньших заданного значения; развилка после цикла позволяет обнаружить эту ситуацию.

Далее приведена программа.

program primer2_1_5_2;

Type mas=array[1..10] of real;

Var a:mas;{можно обойтись без раздела типов,

используя описание a:array[1..10] of real}

c,p:real; N,k,i:integer;

Begin

writeln ( 'Введите c, N'); readln(c,N);

writeln ( 'Введите массив из ', N, ' элементов');

for i:=1 to N do

read(a[i]); readln;

p:=1; k:=0;

for i:=1 to N do

if a[i]
begin

p:=p*a[i]; k:=k+1

end;{begin-end ограничивают ветвь "да"}

if k=0 then

writeln ('таких элементов нет')

else

writeln(' p=',p);

readln{задержка экрана с результатами до нажатия ENTER}

End.





Пример 3. Дан массив а из N элементов (N10). Найти минимальное значение среди элементов массива и номер элемента с таким значением.

Таблица 7. Состав данных примера 3.

Имя

Смысл

Тип

Структура

Исходные данные

N

число элементов массива

целый

простая переменная

а

заданный массив

вещественный

одномерный массив из 10 элементов

Выходные данные

min

минимальный элемент массива

вещественный

простая переменная

k

номер минимального элемента

целый

простая переменная

Промежуточные данные

i

счетчик элементов массива

целый

простая переменная

Блок-схема алгоритма приведена на рис. 11. В начале каждого выполнения цикла min – это минимальное значение среди (i-1) первых элементов массива. Это значение min сравнивается с а[i] и в результате определяется минимум из первых i элементов массива; при изменении текущего минимального значения запоминается номер элемента, на котором достигается текущий минимум (оператор k:=i).

Если минимальное (одинаковое) значение имеют несколько элементов массива, то предложенный алгоритм выдаст наименьший из их индексов; при нестрогом неравенстве (a[i]min) будет выдаваться наибольший номер. В ситуации, когда надо определить номера всех элементов, имеющих минимальное значение, алгоритм должен иметь два цикла обработки: в первом цикле должен определяться минимум, а во втором по сравнению min=a[i] находиться номера элементов.





program primer3_1_5_2;

Var a:array[1..10] of real;

min:real; N,k,i:integer;

Begin

writeln ( 'Введите число элементов массива, N<=10 ');

readln(N);

writeln ( 'Введите массив из ', N, ' элементов');

for i:=1 to N do

read(a[i]);

readln; {Закончен ввод, далее алгоритм по блок-схеме}

min:=a[1]; k:=1;

for i:=2 to N do

if a[i]
begin

min:=a[i];

k:=i

end;{begin-end ограничивают ветвь "да"}

writeln(' min=',min, ' k=', k);

readln{задержка экрана с результатами до нажатия ENTER}

End.
Пример 4. Дана матрица а из N строк и M столбцов (N5, M5). Для каждой строки матрицы найти сумму элементов и определить число строк, для которых эта сумма положительна.

Таблица 8. Состав данных примера 4.

Имя

Смысл

Тип

Структура

Исходные данные

N

число строк матрицы

целый

простая переменная

М

число столбцов

целый

простая переменная

а

заданная матрица

вещественный

двумерный массив размером 5*5

Выходные данные

i

счетчик строк матрицы

целый

простая переменная

s

сумма элементов i-ой строки

вещественный

простая переменная

k

число строк с положи­тельной суммой эле­ментов

целый

простая переменная

Промежуточные данные

j

счетчик столбцов матрицы

целый

простая переменная

Обратим внимание, что считая s простой переменной мы предполагаем, что значения сумм всех строк должны последовательно записываться в одну ячейку памяти. В этом случае в одном цикле по строкам мы должны вычислить сумму элементов строки s, вывести s и сравнить ее с нулем для вычисления k. Можно было объявить s как одномерный массив (число его элементов равно числу строк матрицы); тогда алгоритм обработки мог бы состоять из двух последовательных циклов по строкам: в первом из них вычислялись бы все элементы массива s и накапливалось значение k, а во втором производился бы вывод значений элементов массива s.

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

  1. выбор структуры данных (простая переменная или массив) может быть неоднозначен;

  2. выбор структуры данных влияет на алгоритм.

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

Разработанный алгоритм имеет кратный (вложенный) цикл: тело цикла, управляемого параметром i - этот цикл называется внешним, - содержит цикл, управляемый параметром j, внутренний цикл. Представленная конструкция также называется циклом кратности (вложенности) 2. Заметим, что внешний цикл (с параметром i) обеспечивает переход от строки к строке матрицы, внутренний цикл (с параметром j) обеспечивает движение по строке (т. е. переход от столбца к столбцу при фиксированном значении i).





да



нет



Рис. 12,б. Детализация блока 6.






Программа, написанная по блок-схема рис.12,в приведена ниже.

program primer4_1_5_2;

Var a:array[1..5,1..5] of real;

s:real; N,M,k,i,j:integer;

Begin

writeln ( 'Введите число строк матрицы, N<=5 ');

readln(N);

writeln ( 'Введите число столбцов матрицы, М<=5 ');

readln(M);

writeln ( 'Введите матрицу размером', N, '* ', M);

for i:=1 to N do

for j:=1 to M do

read(a[i,j]);

readln; {Закончен ввод, далее алгоритм по блок-схеме}

k:=0;

writeln(' i',' s');{вывод заголовков столбцов i,s }

for i:=1 to N do

begin

s:=0;

for j:=1 to M do

s:=s+a[i,j];

if s>0 then

k:=k+1;

writeln(i:2, s);

end;{begin-end ограничивают тело внешнего цикла}

writeln(' k=', k);

readln{задержка экрана с результатами до нажатия ENTER}

End.

1.614. Структура паскаль-программы


В этом разделе дано более строгое и подробное (по сравнению с предыдущими разделами) описание структуры паскаль-программы.

Программа состоит из заголовка и блока. Общий вид заголовка:

program Имя_программы;

Имя программы должно являться идентификатором (см. §1.2.1)

Блок программы состоит из следующих разделов:

раздел меток (LABEL);

раздел констант (CONST);

раздел типов (TYPE);

раздел переменных (VAR);

раздел процедур (PROCEDURE) и функций (FUNCTION);

раздел действий.

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

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

Далее дается краткая характеристика каждого из разделов.

Раздел меток

Любой исполняемый оператор может быть снабжен меткой. В стандартном Паскале метка - это целая положительная константа. Метка отделяется от оператора двоеточием. Все используемые в блоке метки должны быть описаны в разделе LABEL. На помеченные операторы можно перейти с помощью оператора безусловного перехода go to. Структурное программирование ограничивает использование меток и операторов безусловного перехода, поэтому в данном пособии они не рассматриваются.

Раздел констант

Громоздкие, часто встречающиеся константы могут быть обозначены в разделе констант - см. также §1.2.4. Общий вид описания констант:

имя_константы=значение_константы

Раздел типов

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

Имя_типа=описание_типа

Пример:

CONST N=20;

TYPE

MAS1=ARRAY[1..N,1..7] OF REAL;

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

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

Имя_типа=(значение_1, значение_2,...,значение_N);

Каждое значение именуется некоторым идентификатором. Значения считаются упорядоченными:

значение_1 < значение_2 < ...< значение_N.

Примеры перечисляемых типов: DAY=(SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURDAY,FRIDAY,SATURDAY);

COLOR=(BLACK,BROWN,GREEN,YELLOW,WHITE).

Переменные этих типов должны быть описаны в разделе VAR обычным образом:

DATE:DAY; PAINTER:COLOR.

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

В дальнейшем нам понадобится термин "порядковый тип". Порядковый тип - это тип, для которого все допустимые значения могут быть некоторым образом упорядочены (перенумерованы). Типы integer, char, boolean, перечисления являются порядковыми. Заметим, что тип real не считается порядковым, хотя, принимая во внимание ограниченное число разрядов, отводимое на представление вещественного числа в памяти ЭВМ, значения типа REAL можно упорядочить.

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

Общий вид описания ограниченного типа:

Имя_типа=нижняя_граница..верхняя_граница

Нижняя граница не должна превышать верхнюю. Базовый тип определяется типом границ.

Пример описания ограниченных типов:

ktype=1..20;

workday=MONDAY..FRIDAY;

color1=BROWN..YELLOW;

Для типа ktype базовый тип - INTEGER, для типа workday - DAY, для типа color1 - COLOR.

Пример описания переменных ограниченных типов:

К:ktype; N,N1,N2:workday; col:color1;

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

Задание ограниченного типа и типа перечисления может производиться не в разделе TYPE, а непосредственно при описании переменных. Например,

i: 1..100; color10: (blue,red yellow, green);

Раздел переменных

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

VAR

<список1 имен переменных>:<тип1>;

<список2 имен переменных>:<тип2>;

. . .

<списокN имен переменных>:<типN>;

Пример.

CONST N=10;

TYPE color=(white,grey,blue,black,red);

MAS1=ARRAY[1..N,1..3];

VAR i,j:INTEGER; A:BOOLEAN; B,C:MAS1; L:color; M:1..N;

Q:ARRAY[1..50] OF INTEGER;

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

Раздел действий

Этот раздел имеет вид:

BEGIN

операторы

END.

Напомним (см. §1.1), что операторы - это выполняемые инструкции языка, т.е. инструкции, которые переводятся в одну или несколько машинных команд. Операторы отделяются друг от друга символом ";".

1   2   3   4   5   6   7   8   9   10


написать администратору сайта