- •Предисловие
- •Основы программирования
- •Понятие алгоритма.
- •Алгоритм Евклида.
- •Задача о поездах и мухе
- •Вместо лирического отступления
- •Этапы подготовки задачи для решения на компьютере
- •Примеры разработки алгоритмов
- •Решение квадратного уравнения.
- •Вычисление интегралов
- •Обработка результатов эксперимента
- •Решение системы линейных алгебраических уравнений
- •Введение в язык программирования Pascal
- •Основные элементы языка
- •Переменные. Стандартные типы.
- •Операции отношения
- •Раздел описаний переменных
- •Выражения. Порядок выполнения операций.
- •Константы
- •Комментарии в программе
- •Операторы
- •2.1.7.1. Оператор присваивания
- •2.1.7.2. Операторы ввода/вывода
- •2.1.7.3. Операторы инкремента и декремента
- •Среда разработки Lazarus
- •Русский язык в консольных приложениях
- •Первая программа
- •Открытие существующего проекта
- •Другие способы создания консольных приложений
- •Типовой пустой проект
- •Операции с целыми числами
- •Вместо лирического отступления 2
- •Стандартные функции с целыми аргументами
- •Операции с вещественными числами (тип real).
- •Форматирование вывода
- •Одновременное использование вещественных и целых чисел.
- •Другие стандартные функции с вещественными аргументами
- •Булевы переменные
- •Условные операторы.
- •2.1.22.1 Оператор if …. then
- •2.1.22.2. Оператор if …then ... else
- •Операторы цикла
- •2.1.23.1. Оператор цикла с предусловием
- •2.1.23.2. Оператор цикла с постусловием
- •2.1.23.3. Оператор цикла с параметром.
- •2.1.23.4. Второй вариант оператора цикла с параметром
- •Оператор выбора case
- •Организация простейшего контроля ввода данных.
- •Вычисление сумм сходящихся рядов
- •Реализация некоторых алгоритмов главы 1.
- •Программа решения задачи о поездах и мухе
- •Программа вычисления определенного интеграла
- •Более сложные элементы языка
- •Общая структура Паскаль – программы
- •Процедуры и функции
- •3.1.1.1 Структура процедуры
- •3.1.1.2. Структура функции
- •3.1.1.3 Глобальные и локальные переменные
- •3.1.1.4 Способы передачи параметров
- •3.1.1.5 Процедуры завершения
- •Еще раз о типах данных
- •Классификация типов данных
- •3.2.1.1 Целый тип
- •3.2.1.2. Интервальный тип
- •3.2.1.3. Перечислимый тип
- •3.2.1.4. Множества
- •3.2.1.5. Логический тип
- •3.2.1.6. Вещественный тип
- •3.2.1.7. Указатели
- •Обработка символьной информации в Паскале
- •Символьные и строковые типы данных.
- •3.3.1.1. Тип Char
- •3.3.1.2. Функции для работы с символами
- •3.3.1.3. Тип String
- •3.3.1.4. Строковые процедуры и функции
- •Массивы
- •Динамические массивы
- •Программа решения системы линейных алгебраических уравнений методом Гаусса
- •3.4.1.1. Вариант 1 – с goto
- •3.4.1.2. Вариант 2 – без goto
- •3.4.1.3. Вариант 3 – наилучшая реализация
- •Модули в Паскале
- •Структура модуля
- •Системные модули
- •3.5.2.1. Модуль CRT
- •Файлы
- •Тип данных – запись
- •Файловые типы
- •Процедуры для работы с файлами
- •3.6.3.1. Общие процедуры для работы с файлами всех типов
- •3.6.3.2. Процедуры для работы с текстовыми файлами
- •3.6.3.3. Процедуры для работы с типизированными файлами
- •3.6.3.4. Процедуры для работы с нетипизированными файлами
- •3.6.3.5. Организация контроля ввода/вывода при работе файлами
- •3.6.3.6. Создание простой базы данных с типизированными файлами.
- •Алгоритмы сортировки
- •Обменная сортировка (метод "пузырька")
- •Сортировка выбором
- •Сортировка вставками
- •Метод быстрой сортировки
- •Алгоритмы поиска
- •Поиск в массивах
- •Вставка и удаление элементов в упорядоченном массиве
- •Динамические структуры данных
- •Представление в памяти компьютера динамических структур.
- •Реализация стека с помощью массивов
- •Указатели
- •Стандартные операции с линейными списками
- •Реализация динамических структур линейными списками
- •4.3.6.1. Реализация стека
- •4.3.6.2. Реализация очереди с помощью линейного списка
- •4.3.6.3. Реализация двоичного дерева с помощью линейного списка
- •Сортировка и поиск с помощью двоичного дерева
- •Три источника и три составные части ООП.
- •Классы и объекты.
- •Обращение к членам класса.
- •Инкапсуляция
- •Спецификаторы доступа.
- •Свойства.
- •Наследование
- •Полиморфизм
- •Раннее связывание.
- •Позднее связывание.
- •Конструкторы и деструкторы.
- •Элементы графического интерфейса
- •Различия между консольными и графическими приложениями
- •Визуальное программирование в среде Lazarus
- •Создание графического приложения
- •Форма и ее основные свойства
- •Компоненты
- •Обработчики событий
- •Простейшие компоненты
- •6.3.5.1. Компонент TLabel
- •6.3.5.2. Кнопки TButton, TBitBtn и TSpeedButton
- •6.3.6.1. Компонент TEdit
- •6.3.6.2. Компонент TLabeledEdit
- •6.3.7.1. Компонент TMaskEdit
- •Специальные компоненты для ввода чисел
- •Тестирование и отладка программы
- •Компоненты отображения и выбора данных
- •6.3.10.1. Компонент TMemo
- •6.3.10.2. Компонент TStringGrid
- •6.3.10.3. Компоненты выбора
- •Компонент TListBox
- •Компонент TComboBox
- •Компоненты выбора – переключатели
- •6.3.10.4. Компоненты отображения структурированных данных
- •Компонент TTreeView
- •Компонент TListView
- •Организация меню. Механизм действий - Actions
- •6.3.11.1. Компонент TMainMenu
- •6.3.11.2. Компонент TToolBar
- •6.3.11.3. Компонент TActionList
- •6.3.11.4. Создание приложений с изменяемыми размерами окон
- •Послесловие
- •Литература
- •Алфавитный указатель
3.4 Массивы
____________________________________________________________________
readln(phone);
if (not find_data(name, tel, phone)) and (phone <>
'***') then
writeln(UTF8ToConsole('Абонента с таким номером нет'));
end;
end.
Как вы думаете, есть ли в программе еще недостатки? Вообще говоря,
можно, конечно, придраться и к столбу, но, справедливости ради, отмечу, что в программе есть еще существенные недостатки.
Во-первых, что будет, если при вводе будут введены одинаковые фамилии и/или телефоны? Будут выведены та фамилия и/или тот телефон, которые были введены первыми. Но в массиве дублирующие данные останутся. Значит,
предварительно необходимо просмотреть уже сформированный массив и толь-
ко, если фамилия и/или телефон не совпадают, лишь тогда добавлять очередно-
го абонента в массив. Второй значительный недостаток – при вводе телефона не осуществляется никакого контроля. В номере телефона могут быть только цифры, ну, может быть еще знак тире.
Однако разбор этой программы занимает уже чуть ли не половину книги.
Поэтому попробуйте сами покопаться. Идеи я вам подкинул. Уверен, что вы справитесь с этой задачей!
3.4.2Программа решения системы линейных алгебраических уравнений методом Гаусса
Напишем программу, реализующую алгоритм Гаусса с выбором главного элемента для решения системы линейных алгебраических уравнений. Сам ал-
горитм был нами рассмотрен в 1.3.4.
Как уже повелось у нас с вами, прежде чем смотреть программу, напишите его сами по блок схеме, приведенной в разделе 1.3.4. Используя массивы, реа-
202
Глава 3 Более сложные элементы языка
____________________________________________________________________
лизовать этот алгоритм для вас не составит труда. И лишь после этого сопос-
тавьте свою программу с приведенной в книге. Думайте, анализируйте, сравни-
вайте коды, ищите лучшие решения, нещадно критикуйте меня! Вполне воз-
можно, что вы напишете программу лучше. Лучше не в смысле получаемых ре-
зультатов (они должны совпадать!), а с точки зрения реализации. Может быть,
вы напишете более эффективную программу или реализуете отдельные фраг-
менты алгоритма более просто, ну и т.д. И имейте в виду, что и сами алгорит-
мы, решающие одну и ту же задачу, можно составлять по-разному! Так что по-
пробуйте и алгоритм придумать свой.
Для сравнения я приведу три варианта программы, написанных тремя моими студентами. Первый, назовем его "плохим программистом", реализовал алгоритм, как говорится в "лоб". Как записано в блок-схеме, так и реализовано в программе. На защите своей программы он признался мне, что так и не смог написать эту программу без оператора goto. Кроме того, его программа не умела определять существует решение или нет, а также не был организован ввод коэффициентов расширенной матрицы. Его программа умела решать только систему из трех уравнений с тремя неизвестными.
Второй студент, назовем его "средним программистом", сумел написать программу без goto, но также действовал в "лоб". Правда его программа уже
"умела" вводить коэффициенты расширенной матрицы.
И, наконец, третий студент, назовем его "хорошим программистом", сумел написать очень изящную по реализации программу. Его программа оказалась намного короче по количеству операторов в тексте программы. В программе он использовал динамические массивы, что позволило реализовать алгоритм ме-
тода Гаусса для любого числа уравнений. Кроме того, часть кода, где непосред-
ственно реализуется алгоритм метода Гаусса, организовал в виде процедуры.
В качестве модельного примера выбрана система:
203
3.4 Массивы
____________________________________________________________________
2x1 |
6x2 |
x3 |
12 |
x1 |
3; |
5x1 |
x2 |
2x3 |
29 |
ее решением является x2 |
2; |
3x1 |
4x2 |
x3 |
5 |
x3 |
6 |
3.4.1.1. Вариант 1 – с goto
program Gauss_console_app; {$mode objfpc}{$H+}
uses
CRT, FileUtil; label
L1, L2, L3, L4, L5, L6, L7; var
a:array[1..3, 1..3] of real;
b:array[1..3] of real;
x: array[1..3] of real; i, j, k, p, n: integer; m, S, t: real;
begin
{Определение коэффициентов расширенной матрицы} n:= 3;
a[1,1]:= 2; a[1,2]:= 6; a[1,3]:=-1; b[1]:=-12; a[2,1]:= 5; a[2,2]:=-1; a[2,3]:= 2; b[2]:=29; a[3,1]:=-3; a[3,2]:=-4; a[3,3]:= 1; b[3]:=5;
{Основная часть программы} k:= 1;
L1: i:= k + 1;
if (a[k, k] = 0) then begin
{перестановка уравнений}
p:= k; // в алгоритме используется буква l, но она похожа на 1
// Поэтому используем идентификатор p
L6: if abs(a[i, k]) > abs(a[p, k]) then p:= i; if not( i = n) then
begin
i:= i + 1; goto L6;
end;
if p = k then i:= k + 1
204
Глава 3 Более сложные элементы языка
____________________________________________________________________
else begin
j:= k;
L7: t:= a[k, j]; a[k, j]:= a[p, j]; a[p, j]:= t;
if not(j = n) then begin
j:= j + 1; goto L7;
end;
t:= b[k]; b[k]:= b[p]; b[p]:= t;
end;
end; // конец блока перестановки уравнений
L2: m:= a[i, k] / a[k, k]; a[i, k]:= 0;
j:= k + 1;
L3: a[i, j]:= a[i, j] - m * a[k, j]; if not(j = n) then
begin
j:= j + 1; goto L3;
end;
b[i]:= b[i] - m * b[k]; if not(i = n) then begin
i:= i + 1; goto L2;
end;
if not( k= n - 1) then begin
k:= k + 1; goto L1;
end;
x[n]:= b[n] / a[n, n]; i:= n - 1;
L4: j:= i + 1; S:= 0;
L5: S:= S - a[i, j] * x[j]; if not(j = n) then
begin
j:= j + 1;
205