Константы, массивы и цикл FOR
06.05.2025 42 Программируем на Паскале Ваш комментарий pascal, паскальТемой сегодняшнего урока, а вернее темами — у нас сегодня несколько тем — являются константы, массивы и цикл FOR. До сих пор в рамках нашего курса мы имели дело только с переменными, массивы мы затрагивали на прошлом уроке, когда работали со строковым типом данных String, а перебирать элементы массива удобнее всего в цикле и сегодняшний цикл FOR прекрасно подходит для этой цели.
Начнём мы с констант, но для этого сначала вспомним о переменных. Мы можем сравнить константы с переменными как в том аспекте, чем они друг на друга похожи, так и в том, какие у них имеются отличия.
Любая программа и не только на Паскале, обычно работает с данными. Это могут быть числа, строки, те же массивы. Мы можем их получать из файлов или с клавиатуры, но всё это многообразие требуется где-то хранить. Для этого в оперативке компьютера выделяются ячейки памяти, куда мы и складываем нужные нам для работы данные. Паскаль является языком программирования с жёсткой типизацией, с частью встроенных в традиционный Паскаль типов данных мы уже познакомились, остальные — впереди.
Сейчас нам важно помнить, что для хранения данных того или иного типа требуется различное количество байтов памяти. Когда мы объявляем переменную определённого типа, по сути, даём Паскалю команду, а тот переводит её в машинный язык, чтобы процессор выделил нужное количество памяти, сохранил туда наши данные, и позволил обращаться к ним по придуманным нами именам, а не адресам ячеек памяти. Так делают все языки программирования высокого уровня.
Итак, переменная (от английского variable — изменяемая) может хранить данные какого-то одного типа в Паскале. Объявив переменную и задав её тип, мы указываем данные какого типа — он на протяжении всей программы будет у переменной один — собираемся хранить. А вот значения могут по ходу программы меняться.
Константы
Константа (от латинского constant — постоянная) задаётся только один раз и её значение по ходу программы может использоваться в разных местах, но менять её мы не можем. Похожесть на переменные заключается в том, что константам также даётся имя, которое мы и будем указывать, когда нам понадобятся эти неизменяемые на протяжении всей программы данные.
Можно было бы обойтись без констант одними переменными? — Пожалуй да, но порой нам надо задать какое-то значение, которое гарантированно нигде в программе не будет меняться, а переменную мы можем изменить. С константой такого просто не получится.
Я часто в рамках данного курса повторяю, что традиционный Паскаль является языком структурированным. Это значит, что всякому куску программы в нём обычно отведено жёсткое место. Константы — не исключение. Если они нам нужны, то блок констант начинается с ключевого слова const и этот блок в программе идёт самым первым после инструкции program…
На практике это выглядит так:
Листинг 1.
program ConstantsArraysFor; const N = 5; S = 'Строковое значение';
Расположение в самом верху программы, позволяет нам легко и быстро находить уже объявленные константы. Чтобы контролировать их значения или объявлять новые, нам не придётся искать их по всему тексту программы. Кроме того, из примера видно, что объявляя константу, мы задаём ей имя и присваиваем значение. Констант в блоке объявления может быть столько, сколько нам потребуется, Тип данных в этом случае не указывается явно, а определяется Паскалем «из контекста». Для задания значения константам используется обычный знак равенства «=», а не привычный нам знак присваивания «:=».
Массивы
Например, вам не придёт в голову умножать строки или делать что-то такое же бессмысленное. Даже если вы попытаетесь, Паскаль выдаст сообщение об ошибке с указанием строки программы. Как поведут себя другие языки программирования из-за неявного преобразования типов — я судить не берусь.
Объявление массивов происходит в разделе var — к этому моменту в программе уже объявлены константы и пользовательские типы данных, если они нам нужны. Объявление массива происходит так:
Листинг 2.
var mas: array[1..10] of Integer;
mas — имя переменной, слово array и переводится собственно как «массив», далее в квадратных скобках через две точки подряд задают два числа. По сути это даже не количество элементов в массиве. Таким образом задают номера первого и последнего элемента массива. Это целые числа и часто элементы массива нумеруются от нуля, если мы не указали другое число, в нашем примере — единица. И обращаться к элементам массива можно будет по их номерам. Например: mas[1] или mas[4]. Так элементам массива можно будет присвоить какие-то значения или использовать хранящиеся.
Никто не мешает нам нумеровать элементы массива при его объявлении, например, от 13 до 18. Это накладывает на программиста необходимость, не обращаться к элементам массива с другими номерами, иначе мы получим сообщение об ошибке (что-нибудь вроде: «Индекс находился вне границ массива.»). И важно также помнить, что в этом случае в массиве будет не 18 элементов, а 6. В общем случае количество элементов массива вычисляется по формуле:
В нашем последнем примере 18 — 13 + 1 = 6. Из примера выше следует, что у массива с индексами 1 и 10 — возможно присвоить и считывать значения десяти элементов массива. Как итог, через индексы элементов массива в Паскале опосредованно задаётся количество его элементов. Часто последний индекс элементов массива задают константой.
Листинг 3.
program ConstantsArraysFor; const N = 5; var mas: array[1..N] of Integer;
Не трудно догадаться, что задавая различные значения константы N, тем самым мы будем указывать количество элементов нашего массива. А могли бы мы с вами в качестве первого или последнего индекса массива использовать переменные? Вероятно, да. Вот только переменные так и называются, потому что по ходу программы их значения могут меняться. А в случае, когда над программой работают несколько программистов, было бы попросту невозможно гарантировать, какое у переменной будет значение, когда нам понадобится присвоить или считать какие-то значения из массива.
Массив объявлен, давайте присвоим его элементам конкретные значения. Листинг программы на текущий момент выглядит так:
Листинг 4.
program ConstantsArraysFor; const N = 5; var mas: array[1..N] of Integer; BEGIN mas[1] := -10; mas[2] := 6; mas[3] := 3; mas[4] := 8; mas[5] := 13; END.
Уже на этом месте легко заметить: если в массиве будет много элементов, мы замучаемся писать большие куски однообразного кода. Поэтому, обращаясь к элементам массива, в качестве индекса часто используют переменные. Кроме того, присваивать значения элементам массива не обязательно подряд — индексы можно указывать в любом порядке или вовсе без порядка, важно только не выходить за границы индексов.
Вывести значения массива на экран можно передав процедуре writeln имя нашего массива. В этом случае, он будет напечатан целиком и значения будут следовать по порядку индексов от меньшего к большему.
На этом месте я хотел бы обратить ваше внимание на одну неоднозначную деталь. Предположим, мы не зададим какой-то из элементов массива, давайте закомментируем какую-то строку и выведем наш массив на экран:
Листинг 5.
program ConstantsArraysFor; const N = 5; var mas: array[1..N] of Integer; BEGIN mas[1] := -10; mas[2] := 6; //mas[3] := 3; mas[4] := 8; mas[5] := 13; writeln( mas ); readln; END.
В этом случае мы увидим в окне вывода строку: «[-10, 6, 0, 8, 13]». Ошибок Паскаль не выдаст, а не указанный нами третий элемент массива заменит нулём. Проще говоря, Паскаль заполнит не заданные нами элементы массива «значениями по-умолчанию». Для интеджера это «0», для строкового массива получили бы пустые строки. А ведь подобные значения могли бы быть и явно присвоены нашему массиву. Следует помнить об этом неявном присвоении значений элементам массива.
Кроме того, можно печатать и отдельные элементы массива. Для этого достаточно после имени массива в квадратных скобках передать индекс нужного нам элемента.
Вспомним прошлый урок и тип данных String — он очень похож на массив. Во всяком случае, к отдельным символам строки мы можем обращаться по их индексам. Программа может выглядеть так:
Листинг 6.
program Constants; var s: String; BEGIN s := ‘Привет, мир!’; writeln( s[5] ); readln; END.
Получаем букву «е».
Пересечение с темой прошлого урока (строковый тип данных String) на этом закончим.
Цикл FOR
Настало время поговорить о циклах. В традиционном паскале их имеется как минимум три типа. Сегодня познакомимся с циклом FOR. Общим местом применения циклов является то обстоятельство, что в реальных программах имеется не пять элементов массива, а значительно больше. По ходу выполнения программы их может потребоваться менять много раз. Задавать, менять или выводить на экран элементы массива по одному — очень неудобно. Помимо неудобства мы также получим большие куски повторяющихся строчек кода — взгляните на листинги 4 и 5. Искать нужные места программ будет всё неудобнее, будет также расти и вес готовой программы. И хотя в современных компьютерах мы имеем почти неограниченное количество оперативной памяти, я являюсь сторонником той точки зрения, что память надо поберечь.
Цикл — кусок программы, который будет многократно выполнять однотипные действия. Циклу FOR для работы необходим счётчик, посредством которого будет задаваться количество повторений — итераций. Задаётся такой счётчик как переменная любого из перечисляемых типов. Чаще всего это переменная целочисленного типа Integer, но в зависимости от задачи, это может быть, например, тип Byte. Условимся использовать Integer, если в задаче не сказано иное. Объявим целочисленную переменную i и в цикле зададим значения элементам нашего массива. Теперь листинг программы будет выглядеть так:
Листинг 7.
program ConstantsArraysFor; const N = 5; var mas: array[1..N] of Integer; i: Integer; BEGIN writeln( ‘Вам необходимо ввести с клавиатуры’, N, ‘ целых чисел.’ ); for i := 1 to N do begin write( i, ‘: ’ ); readln( mas[i] ); end; writeln( mas ); readln; END.
Понимать нашу программу следует так. Вначале, через константу N мы задаём количество элементов массива, а за одно и верхний предел для счётчика цикла FOR. Затем как и ранее объявляем массив целых чисел. И переменную i. В нашем примере N равно пяти, но если бы нам понадобилось другое число элементов массива, то задавали бы его один раз в самом начале программы. Перед запуском цикла мы выводим пользователю, который запустит нашу программу, каких действий мы от него ждём. Мы просим ввести с клавиатуры 5 целых чисел.
Далее в цикле мы задаём через переменную i первое и последнее значение нашему счётчику цикла. Слово «to» означает, что значения будут меняться в заданных пределах, увеличиваясь каждый раз на единицу. Вообще же, можно было проходить элементы массива от элемента с самым большим индексом, до самого меньшего. В этом случае мы использовали бы слово «downto». Кроме того, можно было бы задать ещё и шаг, с которым будет изменяться наш счётчик.
for i := 1 to N step k
Или
for i := N downto 1 step k
Следует помнить, что оба значения и шаг, с которым может меняться счётчик итераций цикла, можно задавать при помощи переменных, констант или явно — числом. Так же, значение счётчика может начинаться или заканчиваться нулём. Если step k не задано, то счётчик будет увеличиваться (to) или уменьшаться (downto) на единицу.
В нашем примере в листинге 7 счётчик цикла будет меняться от единицы до N (заданной через константу), увеличиваясь каждый шаг цикла на единицу.
Так как в цикле мы выполняем несколько действий (операторов), мы обособляем их ключевыми словами begin — end. Мы будем выводить номер итерации цикла — он совпадает с индексами элементов массива. И далее, через процедуру readln будем присваивать значение числа в очередной элемент массива.
Когда цикл выполнится целиком, пользователь гарантированно введёт с клавиатуры все элементы массива и мы распечатаем весь массив.
Хочется напомнить, что элементами массива в Паскале могут быть не только числа, это могут быть символы, строки, логические значения и так далее. Главное также помнить, что Паскаль является языком программирования с жёсткой типизацией и мы не сможем в обычном массиве объединить значения разных типов. Как быть в этом случае, мы разберёмся на одном из будущих уроков.
Для тех, кто дочитал статью до конца — бонус, «кино» на заданную тему. В ролике с определённого момента рассказано, как запускать программу в Pascal ABC.net в пошаговом режиме, чтобы отслеживать по ходу, чему равны те или иные переменные.
Репозиторий листингов программ.
https://www.youtube.com/watch?v=NZx0kZqB4ig
https://vk.com/video-207954158_456239020
https://rutube.ru/video/5e46fd8ea47b4250ad0ca590dc7cc7f6/