Delphi 7. Занятие 1_5.
Содержание
Общие замечания
Во втором занятии мы рассмотрели несколько типов переменных: char, string, integer и double. Для решения простых задач этого уже достаточно. Но на практике требуется значительно большее разнообразие типов переменных.
Рассмотрим ещё один тип данных — массив. Собственно, в delphi 7 массив это даже не отдельный тип данных, а просто способ хранения некоторого количества данных одного типа.
Данные в массиве хранятся в последовательной цепочке байт. Адрес первого байта записывают в переменную, называемую именем массива.
Элементы массива пронумерованы. Эти номера называются индексом элемента. Если, например, имя массива будет vArr и массив хранит 10 элементов, то обращение к восьмому элементу будет иметь вид: vArr[7].
Как происходит обращение к элементу массива? Мы сказали, что адрес первого байта массива хранится в переменной массива. Если, например, массив хранит элементы целого типа integer, то под каждый элемент отводится 4 байта.
Почему индекс равен 7, а не 8? Это происходит из-за того, что первый элемент массива всегда имеет номер 0.
Очевидно, что для массива мощностью 10 элементов допустимые номера индекса от 0 до 9.
Если ввести другое значение индекса, то компилятор Delphi выдаст ошибку.
Посмотрим, как вычисляется адрес элемента массива с номером i.
Если адрес первого байта массива равен n, то адрес элемента с индексом i будет равен n+i*4. При i:=0 мы попадаем в начала массива, при i:=1 сдвигаемся на 4 байта и попадаем в начало первого элемента, и так далее.
Типы массивов в delphi
Не во всех языках программирования строго требуется, чтобы все элементы массива были одного типа.
Поэтому особо подчёркивается, что в delphi массивы являются «типизированными». В ряде случаев нетипизированные массивы более удобны и позволяют решать задачу более элегантно. Но одновременно они наряду с дополнительными удобствами привносит и свои трудности. Нетипизированные массивы могут быть источниками трудно определяемых ошибок.
Массивы подразделяют на одномерные и многомерные.
Например, для хранения данных из таблицы применяют в delphi двумерный массив. Обращение к элементу двумерного массива будет выглядеть, например, следующим образом: vArr[2,7].
Или в общем виде vArr[i,j]. Индекс i ассоциируют с номером столбца, а j — с номером строки.
Аналогично определяются массивы трёх и более измерений.
Наконец, имеется особый вид массива, называемый динамическим. Своё название он получил в силу того, что в процессе работы программы можно изменять размерность массива.
Надо ли Вам будет использовать динамические массивы — Вы решите сами по мере усложнения поставленных задач.
Элементы массива целого типа
Значения, хранящиеся в массиве, называются элементами массива.
Рассмотрим пример. Пусть нам надо хранить десять целых чисел. Можно поступить так: объявить десять переменных типа Integer. А если их сто, тысяча, миллион?
Имеется более элегантная возможность. Значения располагают в памяти одно за другим. Запоминают адрес первого числа, а потом указывают, на каком месте последовательности стоит то число, которое надо прочитать.
В терминах delphi это выглядит так. Объявляется тип данных array с помощью ключевого слова type :
type TArray=array[1..15] of integer;
Далее объявляется переменная типа TArray следующим образом:
var massiv:TArray;
Можно объявить переменную-массив и обычным образом:
var massiv:array[1..15] of integer;
Однако первый способ предпочтительнее.
Объявляя переменную «massiv» типа array, мы тем самым декларировали, что будем хранить цепочку из пятнадцати целых чисел.
Выше мы говорили, что обратится к конкретному элементу массива можно по его индексу.
Например, если «у» является переменной целого типа, то справедливо выражение:
Обмен данными между массивами
Обменяться данными между переменными очень просто. Достаточно поставить оператор равенства между переменными. Например, x:=y; (оператор равенства — выражение «:=»).
Так же можно поступить и с массивами, но при соблюдении определённых условий. Если мы объявим массив одним из двух способов:
type Tarray=array[1..3] of integer;
var
x: Tarray;
y: Tarray;
или
var x,y:array[1..3] of integer;
То справедливо будет написать:
x:=y;
Но ситуацию:
компилятор воспримет как ошибочную.
Это надо запомнить!
Индекс массива
Мы уже использовали в качестве индекса массива целые числа.
Но в качестве индекса можно использовать переменную целого типа. Это исключительно удобно при обработке массива в цикле.
Пример программы работы с массивом
В качестве примера работы с массивом часто решают следующую задачу.
Пусть есть массив целых, например чётных, чисел. Надо вычислить сумму всех элементов этого массива. Предположим, что мощность массива четыре элемента.
Начнём с самого примитивного варианта.
Type TArr=array[1..4] of integer;
Обратите внимание, что имя типа, как и имя переменной, программист назначает произвольно (какие символы можно использовать в идентификаторах переменных смотри в справочной литературе!).
Объявим переменные и заполним значениями элементы массива.
Var ar: Tarr;
sum:integer;
begin
ar[1]:=2;
ar[2]:=4;
ar[3]:=6;
ar[4]:=8;
end;
Далее вычислим сумму значений, хранящихся в массиве.
Var ar: Tarr;
sum:integer;
begin
ar[1]:=2;
ar[2]:=4;
ar[3]:=6;
ar[4]:=8;
sum:=ar[1]+ar[2]+ar[3]+ar[4];
end;
Но, с расчётом на будущее, лучше вычисление суммы представить в виде следующего алгоритма:
Var ar: Tarr;
sum:integer;
begin
sum:=ar[1];
sum:=sum+ar[2];
sum:=sum+ar[3];
sum:=sum+ar[4];
end;
Вычисление суммы происходит следующим образом.
Берётся значение переменной sum, к нему прибавляется значение из ar[2], результат записывается в sum, затирая старое значение. Таким образом на втором шаге мы получаем сумму значений из первого и второго элементов массива. И так далее.
Выше мы говорили, что в качестве индекса можно использовать переменную целого типа. Используя этот факт, приведём классическое решение.
Мы уже неоднократно применяли один из операторов — оператор присваивания «:=» Теперь рассмотрим ещё один оператор — оператор цикла for. Напишем код и рассмотрим, как работает оператор for.
Предварительно введём вспомогательную переменную целого типа:
var i:integer;
Далее:
for i:=1 to 4 do
begin
ВЫРАЖЕНИЯ (тело цикла)
end;
Оператор for организует цикл, который повторяется заданное число раз.
Начиная своё выполнение, оператор for проверяет значение переменной i.
В нашем примере её начальное значение равно «1» . А в принципе оно может быть задано любым числом.
Также и нижняя граница цикла может быть целочисленной переменной.
Например, i:=n, где n – целочисленная переменная.
Если значение i меньше значения, указанного после ключевого слова to (в нашем случае это 4), то начинается выполняться тело цикла.
Выполнив все строки кода и дойдя до оператора end, управление передаётся оператору for и он увеличит переменную цикла i на единицу.
Потом сравнит её со значением, указанным после to. Если i меньше этого значения, то вновь выполнится тело цикла.
И так до тех пор, пока i не станет больше значения, стоящего после to. Тогда тело цикла больше выполняться не будет, а управление перейдет к выражению, записанному после оператора end; .
Теперь, когда все части решения задачи у нас в руках, продолжим её разработку.
Напишем тело цикла, выполняющего решение поставленной задачи.
for i:=1 to 4 do
begin
ar[i]:=i*2;
end;
Здесь i, пробегая значения от 1 до 4, записывает в элементы массива чётные значения. В итоге будет сформирован массив, элементы которого будут содержать чётные целые числа.
Теперь вычислим суммы всех элементов массива. Запишем:
sum:=0;
// так как в момент объявления переменной delphi не
// задаёт ей начального значения (не инициирует её), то оно
// может быть любым. Поэтому присваиваем переменной sum
// начальное значение ноль.
for i:=1 to 4 do
begin
sum:=sum + ar[i];
end;
Замечание. Всё, что написано после «//», является комментарием и не воспринимается delphi как код.
Обратите внимание на очень простое, но очень нужное выражение: sum:=0;
Этим выражение мы задаём начальное значение переменной!
Дело в том, что объявляя переменную, delphi не задаёт её какого-либо начального значения. Поэтому пока мы явно не присвоим ей значения, в ней может содержаться всё, что угодно!
Видео. Работа с одномерным массивом
Теперь создадим программу с простейшим интерфейсом.
В ней мы рассмотрим:
- объявление статического одномерного массива
- заполнение элементов массива значениями
- оператор цикла for
программа
Заключение
Мы рассмотрели:
- как объявить одномерный массив и работать с его элементами.
- Как пользоваться циклом for.
- Как использовать комментарии в тексте программы.
- По каким правилам можно обмениваться данными между массивами, не передавая данные поэлементно.