Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Комплект Информатика / Курс лекций.doc
Скачиваний:
128
Добавлен:
22.05.2015
Размер:
4.8 Mб
Скачать

Контрольные вопросы

1. Какие типы данных включает в себя понятие «структуры данных»?

2. Для чего нужна абстракция в программировании?

3. Покажите на примере, что такое статическая структура?

4. Покажите на примере, что такое динамическая структура?

5. Какова роль указателей в языках программирования?

Лекция № 23 Массивы и списки

Цель лекции

Изучить массивы и списки как способы организации данных в языках программирования высокого уровня.

План лекции

1. Массивы.

2. Списки.

1 Массивы

Многие языки высокого уровня позволяют программисту разрабатывать алгоритм так, как если бы необходимые данные хранились в прямоугольной структуре, называемой однородным массивом, где термин «однородный» означает, что все элементы массива принадлежат одному типу. В этом разделе мы изучим, как же на самом деле организованы такие массивы, и как транслятор преобразует массив, найденный в исходной программе, в термины ячеек памяти и адресов.

Представьте, что алгоритм для обработки суточных замеров температуры написан на языке высокого уровня. Программисту удобно представлять эти показания в виде одномерного массива с названием Readings, ссылки на элементы которого зависят от их положения в списке. Тогда к первому показателю можно обращаться как к Readings[l], ко второму — как к Readings[2] и т. д. (В языках программирования С, C++, С# и Java эти обращения будут выглядеть как Readings [0] и Readings [1], но нам удобнее нумеровать элементы массива, начиная с единицы. Это преобразование выполняется однозначно. В языках программирования С, С++ и Java индексы массивов начинаются с 0, а не с 1. Поэтому элемент в первой строке и четвертом столбце массива с именем Array будет обозначаться как Array[0][3]. В таком случае, какой адресный полином необходимо применять транслятору для преобразования запросов в форме Array[i][j] в адреса памяти?

Переход от этого одномерного массива к фактической организации данных в памяти машины очень прост, так как данные могут храниться в 24 последовательных ячейках памяти в том же порядке, в каком видит элементы массива программист. Зная адрес первой ячейки последовательности, транслятор может преобразовывать такие ссылки, как Readings [4], в соответствующие термины памяти. Он просто вычитает единицу из индекса нужного элемента и прибавляет результат к адресу ячейки памяти, содержащей первое значение температуры. Если первый показатель находится по адресу х (рис. 1), четвертый будет найден по адресу х + (4 - 1).

Рисунок 1 – Массив элементов Readings, записанный в памяти. начиная с адреса х

Теперь представим, что программист планирует написать программу для обработки продаж отдела сбыта компании за неделю. Эти данные можно представить в виде таблицы, где в левом столбце перечислены имена сотрудников отдела, а в верхней строке — дни недели. Следовательно, программисту удобно представить данные в программе как двумерный массив, каждая строка которого обозначает продажи, осуществленные определенным сотрудником, а значения в столбце — это все продажи, сделанные в один день.

Память машины организована не как таблица, а скорее как цепочка ячеек с последовательными адресами. Поэтому требуемую прямоугольную структуру массива придется имитировать. Чтобы сделать это, представим, что массив статичен, то есть его размер не изменяется по мере внесения изменений в данные. Теперь подсчитаем объем памяти, необходимый для всего массива, и зарезервируем непрерывный блок ячеек памяти полученного размера. Начиная с первой ячейки этого блока, последовательно в каждую ячейку записываем значения из первой строки массива; после первой строки таким же образом записываем вторую, третью и т. д. (рис. 3). Такая система хранения называется построчной (row major order), в отличие от постолбцовой (column major order), где один за другим записываются все столбцы массива.

Давайте теперь подумаем, как найти ячейку памяти, содержащую значение на пересечении третьей строки и четвертого столбца массива, если данные организованы подобным образом. Представим себя на месте первой ячейки зарезервированного блока машинной памяти. Начиная с этого положения, можно найти данные первой строки массива, за ней второй, третьей и т. д. Для получения данных третьей строки необходимо пройти первую и вторую строки. Так как в каждой строке содержится по пять элементов (по одному на каждый день с понедельника по пятницу), мы пройдем 10 ячеек и окажемся на первом элементе третьей строки. С этого места нам придется пропустить еще три элемента, чтобы попасть на четвертый столбец массива. Итого, для достижения элемента из третьей строки и четвертого столбца мы проходим 13 элементов от начала блока.

Рисунок 2 – Двумерный массив из четырех строк и пяти столбцов, записанный построчно

Упомянутые ранее расчеты можно обобщить на случай процесса, при помощи которого транслятор преобразует ссылки в терминах положения в строке и столбце в фактические адреса памяти. В частности, пусть с представляет количество столбцов в массиве (то есть количество элементов в каждой строке), тогда адрес элемента на пересечении i-й строки j-го столбца:

где х — адрес ячейки, содержащей элемент на пересечении первой строки и первого столбца. Таким образом, для достижения i-й строки нам нужно пропустить i - 1 строк, в каждой из которых с элементов, а затем для достижения j-гo элемента в этой строке — еще j — 1 элементов. В предыдущем примере с = 5, i = 3 и j = 4, поэтому, если первый элемент массива находится по адресу х, элемент из третьей строки и четвертого столбца будет находиться по адресу

(Выражение (с х (i - 1)) + (j - 1) иногда называют адресным полиномом (address polynomial)).

Зная этот алгоритм, можно написать приложение для преобразования запросов в виде номеров строк и столбцов в адреса внутри блока памяти, содержащего массив. Например, транслятор при помощи этой техники преобразует запросы вида Sales[2.4] в фактические адреса памяти. А программист тем временем может представлять данные в табличной форме (абстрактная структура), даже если на самом деле они хранятся в одной строке (фактическая структура).