logo search
Языки программирования

5.2. Массивы

Массив — это запись, все поля которой имеют один и тот же тип. Кроме того, поля (называемые элементами или компонентами) задаются не именами, а по­зицией внутри массива. Преимуществом этого типа данных является возмож­ность эффективного доступа к элементу по индексу. Поскольку все элементы имеют один и тот же тип, можно вычислить положение отдельного элемента, умножая индекс на размер элемента. Используя индексы, легко найти отдель­ный элемент массива, отсортировать или как-то иначе реорганизовать эле­менты.

Индекс в языке Ada может иметь произвольный дискретный тип, т.е. лю­бой тип, на котором допустим «счет». Таковыми являются целочисленные ти­пы и типы перечисления (включая Character и Boolean):

Ada

type Heat is (Off, Low, Medium, High);

type Temperatures is array(Heat) of Float;

Temp: Temperatures;

Язык С ограничивает индексный тип целыми числами; вы указываете, сколь­ко компонентов вам необходимо:

C

#define Max 4

float temp[Max];

а индексы неявно изменяются от 0 до числа компонентов без единицы, в дан­ном случае от 0 до 3. Язык C++ разрешает использовать любое константное выражение для задания числа элементов массива, что улучшает читаемость программы:

C++


const int last = 3;

float temp [last+ 1];

Компоненты массива могут быть любого типа:

C


typedef struct {... } Car_Data;

Car_Data database [100];

В языке Ada (но не в С) на массивах можно выполнять операции присваива­ния и проверки на равенство:

type A_Type is array(0..9) of Integer;

Ada

А, В, С: AJype;

if A = В then A := C; end if;

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

Ada

А := (1,2,3,4,5,6,7,8,9,10);

А := (0..4 => 1 , 5..9 => 2); -- Половина единиц, половина двоек

А := (others => 0); -- Все нули

В языке С использование агрегатов массивов ограничено заданием начальных значений.

Наиболее важная операция над массивом — индексация, с помощью кото­рой выбирается элемент массива. Индекс, который может быть произволь­ным выражением индексного типа, пишется после имени массива:

type Char_Array is array(Character range 'a'.. 'z') of Boolean;

Ada

A: Char_Array := (others => False);

C: Character:= 'z';

A(C):=A('a')andA('b');

Другой способ интерпретации массивов состоит в том, чтобы рассматривать их как функцию, преобразующую индексный тип в тип элемента. Язык Ada (подобно языку Fortran, но в отличие от языков Pascal и С) поощряет такую точку зрения, используя одинаковый синтаксис для обращений к функции и для индексации массива. То есть, не посмотрев на объявление, нельзя сказать, является А(1) обращением к функции или операцией индексации массива. Преимущество общего синтаксиса в том, что структура данных может быть первоначально реализована как массив, а позже, если понадобится более сложная структура данных, массив может быть заменен функцией без измене­ния формы обращения. Квадратные скобки вместо круглых в языках Pascal и С применяются в основном для облегчения работы компилятора.

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

typedef int A[1 0]; /* Тип массив */

C

typedef struct { /* Тип запись */

А а; /* Массив внутри записи */

char b;

} Rec;

Rec r[10]; /* Массив записей с массивами типа int внутри */

int i,j,k;

k = r[i+l].a[j-1]; /* Индексация, затем выбор поля,затем индексация */

/* Конечный результат — целочисленное значение */

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

C

г Массив записей, содержащих массивы целых чисел

r[i] Запись, содержащая массив целых чисел

r[i].a Массив целых чисел

r[i].a[j] Целое

и эти значения могут использоваться в операторах присваивания и т.п.