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

Самоучитель игры на Паскале. АВС и немного Турбо

.pdf
Скачиваний:
0
Добавлен:
07.09.2026
Размер:
1 Мб
Скачать
var
a : array[1..5] of integer; i : integer;
begin
{ тут вводим} Writeln(‘Input’); Writeln; for i:=1 to 5 do begin Write(‘a[‘,I,’] = ’); Readln(a[i]); end; Writeln;
{ тут делаем что-нибудь полезное}
{ тут выводим} Writeln(‘Output’); Writeln; for i:=1 to 5 do Writeln(a[i]); end.
После запуска получим вот такую картинку:
81
Мешанина кавычек и запятых в строке Write(‘a[‘,I,’] = ’); призвана обеспечить более приятное и удобное приглашение для ввода элементов массива. Если что-то непонятно, придётся просто заучить наизусть. Все наши ближайшие программы подразумеваются имеющими в точности такой же объявленный массив и в точности такой же ввод и вывод. Возвращаемся к проблеме трижды встречающейся в тексте программы пятерки. Это, безусл Будем пр
облему решать, раз и навсегда.
овно, нехорошо, по причинам объясненным ранее.
Что такое константа? Да почти то же самое, что и переменная, только в отличие от переменной получает своё значение раз и навсегда. Ну и по мелочи:
переменная объявляется в секции var, константа в секции const;
после име
ни переменной следует двоеточие, после имени константы
знак равенства;
после разделителя у пе
82
ременной тип, у константы значение;
в одной строке можно объявить много переменных, а константы объявляются строго по одной. Ну, можно, конечно, много констант в одной строке. Имелось с виду, что через запятую нельзя. Вот так выглядит объявление необходимой нам константы:
const
N = 5;
Секция констант по традиции предшествует секции переменных. Во­первых, по традиции и для единообразия. Во-вторых, как в нашем случае,
ругому нельзя по причине ис
по д переменных. У нас константа N служит верхней границей в объявлении массива. Теперь каждый идентификатор N в нашей программе будет эквивалентен числу пять, и, в случае, если размер массива изменится, достаточно будет внести исправление только в одно место нашей программы. А программа наша тем временем приобрела во
program Arr_2; uses
Crt; const N = 5;
var
a : array[1..N] of integer; i :
begin
{ тут вводим} Writeln(‘Input’); Writeln; for i:=1 to N do begin Write(‘a[‘,I,’] = ’); Readln(a[i]); end; Writeln;
{ тут делаем что-нибудь полезное}
integer;
пользования констант в объявлении
т такой вид:
83
{ тут выводим} Writeln(‘Output’); Writeln; for i:=1 to N do Writeln(a[i]); end.
А можно вообще без констант? Можно. Почти. Вообще константы можно было бы заменить переменными, присвоить им один раз значение, а с программиста взять честное слово, что он не будет эти значения менять. К сожалению, на честное слово программиста надежда небольшая, лучше ограничить программиста компилятором. В Delphi появились константы, значение которых можно менять. Лично мне каже случае были неправы. А почему нельзя совсем без констант? А потому что в Паскале начальный и конечный диапазоны в объявлении массива не могут быть переменными.
тся, что разработчи
ки языка в данном
И ещё на что нужно обратить внимание – одно имя может быть дано в программе только один раз. Имя можно дать переменной. Имя можно дать константе. Можно никому не давать. Но нельзя одним и тем же именем назвать и константу и переменную.
Опыты
Несколько стандартных задач при работе с массивами. Встречаться они будут не часто, а очень часто. Ничего изобретать тут не надо, ду
мать тоже ничего не надо – программист должен это писать, не думая абсолютно и на полном автопилоте. У
нас всё тот же массив от одного до N. Все появившееся неупомянутые
ранее переменные – целые.
1. Заполнить массив одним и тем же значением, чаще всего нулем:
for i:=1 to N do a[i]:=0;
2. Заполнить массив сл
учайными значениями в диапазоне от 0 до 99:
for i:=1 to N do a[i]:=Random(100);
3. Поместить в каждый элемент массива его индекс:
for i:=1 to N do a[i]:=i;
4. Увеличить каждый элемент массива на единицу:
for i:=1 to N do
84
a[i]:=a[i] + 1;
5. Определить сумму элементов массива:
sum:=0; for i:=1 to N do sum:=sum + a[i];
6. Определить среднее элементов массива (результат - дробный)
sum:=0; for i:=1 to N do sum:=sum + a[i]; result:=sum/N;
7. Найти минимальный элемент массива и его индекс:
min:=a[1]; index:=1; for i:=2 to N do begin if a[i] < min then begin min:=a[i]; index:=I; end; end;
8. Определить количество отрицательных и неотрицательных элементов массива: numNeg:=0; numNonNeg:=0; for i:= 1 to N do begin if a[i] then numNeg:=numNeg + 1 else numNonNeg:=numNonNeg + 1; end;
9. Вставить нулевой элемен
количество элементов массива не меньше пяти). При этом все элементы, начиная с бывшего пятого должны сдвинуться на одну позицию вправо:
for i:=N downto 6 do a[i]:=a[i-1]; a[5]:=0;
10. Сдвинуть все элементы, начиная с четвертого налево на три. Хвост заполнить нулями.
< 0
т в пятую позицию (доверчиво считаем, что
85
for i:=1 to N-3 do a[i]:=a[i+3]; for i:=N-2 to N do a[i]:=0; Вариант альтернативный, но допустимый: for i:=1 to N do if i <= N-3 then a[i]:=a[i+3] else a[i]:=0;
11. Определить индекс первого чётного элемента массива: indexEven:=0; for i:=1 to N do begin if ((a[i] mod 2) = 0) and (indexEven=0)
then indexEven:=i; end;
Здесь вторая проверка добавлена, чтобы вернуть номер только и только первого чётного элемента. Если этой проверки не будет, вс случиться совсем по-друго
му. В случае нечётности всех элементов
ё может
массива мы должны вернуть в качестве ответа ноль. Это общепринятая практика – если ответа нет, возвращать некоторое невозможное значение. Если ноль является допустимым ответом, обычно возвращают минус единицу. Скобки вокруг a[i] mod 2 поставлены исключительно для наглядности и выразительности – по синтаксису они не нужны.
По хорошему, вторая проверка вообще не нужна – Вам поможет волшебное слово Break – и на гигантском массиве программа заработает чуть-чуть быстрее (тот, кого это волнует – не очень хороший программист). Поскольку оно (Break) противоречит принципам структурного программирования, о Break, возможно вспомним потом. О структурном программировании, тоже, возможно, потом – или в совсем другой книге. Впрочем, все приведённые
рограммы
п
от заветов структурного программирования пока не отступили ни на шаг.
Ещё опыты
То, что мы делали в предыдущем разделе, мы делали с одним массивом. Несколько типовых задач, в которых участвуют два массива сразу. Первый массив зовут A, второй массив B. Оба массива содержат одинаковое число элементов – N.
1. Проще не бывает. Присвоить все элементы одного массива
другому.
86
Вопрос на самом деле не такой уж простой. Потому что можно и так: b:=a; Но только при условии, что массивы объявлены где-то так a,b : array[1..N] of integer; А если вот так a : array[1..N] of integer; b : array[1..N] of integer; то уже ничего не выйдет. Точнее, ничего не выйдет в Turbo Pascal, что неважно. Но ничего не выйдет и в Delp очень важно. Дальше нам надо плавно перейти к будем.
обсуждению определенных пользователем типов. Но мы пока не
hi, что
for i:=1 to N do
b[i]:=a[i];
2. Посчитать поэлементно сумму массивов и отправить в первый
массив:
for i:=1 to N do
a[i]:=a[i] + b[i];
3. Положительные элементы из первого массива отправить во
второй, но чтобы во втором они шли без пропусков в начале массива. То есть, было в первом массиве [1,2,3,-5,1,-7,2]. Во втором должно образоваться [1,2,3,1,2]
ind:=0; for i:=1 to N do begin if a[i]
>0 then begin ind:=ind + 1; b[ind]:=a[i]; end; end;
4. В первом массиве для нас представляют интерес только первые N1 эл
ементов, во втором массиве, соответственно, N2. Объединить N1 и N2 первых элементов их двух массивов, записав их в первый массив. Искренне верим, что N1+N2 <= N.
for i:=1 to N2 do a[N1+i]:=b[i]; N1:=N1 + N2;
5. Переписать элементы первого массива во второй, но в обратном порядке
for i:=1 to N do b[N-i+1]:=a[i]
87
А теперь как будто мы вернулись в предыдущий раздел. Перепишите элементы массива в обратном порядке, не используя второго массива. То есть, внутри него самого. Как поменять два элемента местами? Обычно делают так (wrk – целая переменная, исключительно для вспомогательных целей):
wrk:=a[i]; a[i]:=a[i+1] a[i+1]:=wrk;
Самый главный опыт
Из всех упражнений, которые приходится проделывать над мас наиважнейшим для нас является, бесспорно, сортировка. Что делает сортировка? Сортировка, ну,
На входе:
[10, 22, 11, 50, 30]
На выходе [10, 11, 22, 30, 50]
Методов сортировки огромное количество. Главный критерий их оценки – быстродействие. Математическую сторону, как и везде в этой книге, мы беспощадно упрощаем, уплощаем и опошляем. Одни методы сортируют быстрее, другие ещё быстрее, а совсем другие –
сем наоборот.
сов Большинство программистов используют самы методов – пузырьковую сортировку. Такова традиция. Программист, который не может её запрограммировать за пять минут – неполноценен во всех отношениях. Даже если освоил все остальные методы. Мы в неполноценные не хотим, поэтому сейчас будем программировать пузырьковую сортировку. Почему она пузырьковая? Запрограммируйте, включите воображение и поймёте. В чём идея? Сравниваем первый и второй элем второго (или равен второму), то всё хорошо и ничего делать не надо. Если первый больше второго, то это пло
в общем, сортирует…
й худший из худших
енты. Если первый меньше
хо, поэтому меняем первый элемент со
сивами,
88
вторым местами. Потом сравниваем второй элемент с третьим, реагируем аналогично. И так доходим до сравнения предпоследнего элемента с последним. А затем начинаем всё сначала. Если за время всего прохода по массиву мы никого не поменяли местами, то всё хорошо и можно заканчивать. Что видно сразу? Внешний, главный цикл прямо-таки напрашивается быть запрограммированным как repeat-until – повторять до тех пор, по не станет всё хорошо. Внутренний цикл обычный, и повторяться он будет очевидн Ну и конечно, объявим специальную переменную по имени Ok. Как только она – да, то мы – всё. Получаем вот такой эскиз программы:
const N = 5;
var
a Ok : integer; i : integer; ……………………………………………
repeat
for i:=1 to N-1 do begin if a[i] > a[i+1] then begin {поменять местами} end; end; until ok=1;
Мы просто записали на Паскале то, что раньше сказали словами. Что осталось неясным? Судьба переменной Ok. Договоримся, что если Ok=1, то всё хорошо, то есть о’кей, а если ok=0, то, наоборот, всё плохо, не о’кей, в смы уже решили, что основной цикл выполняет записали это. Очевидно, перед началом сортировки у нас не всё Ok – а иначе, зачем сортировать? Значит, перед циклом переменная устанавливается в ноль. Опять-таки, если пришлось поменять элементы местами, значит у нас опять всё плохо – и опять переменной присваиваем ноль. Но когда-то же должна она стать единицей, цикл ведь должен
о N-1 раз. N – как всегда, количество элементов в массиве.
: array[1..N] of integer;
ся до тех пор, пока не Ok – и
ка
сле. Мы
89
закончиться? Стандартная технология для таких случаев – перед циклом предполагаем, что всё хорошо. Если внутри цикла хоть раз что-то оказалось не так – переменная получает значение ноль. Вторая, даже не проблема, а так. Поменять элементы местами. Вводим вспомогательную переменную того же (целого) типа и меняем через неё. Затем думаем, как это можно сделать без использ переменной. Подсказка – это можно сделать для числен
ования вспомогательной
ных переменных,
для строковых номер не пройдёт.
Примечание. Тот, кто попробует сделать это для real, немедленно будет лишён премии. Маньяки могут поменять и для строковых переменных. Но таких премией не возьмёшь.
И, наконец, наша программа приобретает законченный вид:
const N = 5;
var
a : array[1..N] of integer; Ok : integer; wrk : integer; i : integer; …………………………………………… Ok:=0;
repeat
ok:=1; for i:=1 to N-1 do begin if a[i] > a[i+1] then begin Ok:=0; {поменять местами} wrk:=a[i]; a[i]:=a[i+1]; a[i+1]:=a[i]; end; end; until Ok=1;
Прикрутите заполнение массива случайными числами, вывод до и вывод после и любуйтесь результатом.
90
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]