::Главная страница :: С++/Си :: Статьи

Как на самом деле происходит работа с массивами в Си и С++

Прежде всего рассмотрим способ расположения массива в памяти.
В зависимости от размерности массива он может размещаться в памяти по разному. Тоисть цепочки значений по разному физически занимают память. Мало того разные компиляторы по разному их размещают.
Для начала рассмотрим самый простой случай когда все компиляторы работают почти одинакова. Это для случая одномерного массива.
Имя массива указывает на кокой то адрес памяти по которому располагается первый (0) элемент массива. За ним через некоторый промежуток размещается следующий элемент массива и так до последнего элемента - 0 - символом конца массива. Промежуток определяется размером типа элементов этого массива.
Как работает компилятор. Когда вы объявляете массив на самом деле вы объявляете только указатель на него которому соответствует имя этого массива. И все обращения к массиву идут через указатель на него, даже если вы конкретно указали количество элементов. К примеру когда вам нужен 20 элемент компилятор берет указатель и прибавляет к нему размер_типа в байтах умноженному на 20 тоисть номер индекса. Когда идет работа с указателями то все гораздо проще идет просто обращение к участку памяти по указателю.
С двухмерными массивами компиляторы работают по разному. Рассмотрим несколько случаев. Первый - в памяти в ряд располагаться все ряды массива. Тоисть получается один большой одномерный массив составленный из рядов двух мерног массива. Обращение идет просто адрес элемента вычисляется следующим образом. Он равен = смещение + индекс. Тоисть смещение это количество байт которые занимает целый ряд, а индекс это просто обращение к конкретному элемента как в одномерном массиве. Хочу обратить внимание, что отсчет смещение идет от нуля. Этот способ размещение имеет свои минусы так как требует довольно большой непрерывный участок памяти и несет большую нагрузку на процессор так как постоянно приходиться вычислять адрес ячейки массива. Этот способ кстати используется в Паскале.
Есть второй способ размещение массива. Для размещение используются указатели. Тоисть составляется одномерный массив из указателей на кучу тоже одномерных массивов в которых уже хранятся данные. Правда никто не мешает и этим ячейкам куда либо указывать но это уже получиться не двухмерный массив а трех …. массив. Работа с ними идет как с указателями разве, что программист не может вмешаться в эту работу.
Массивы в Си можно использовать для прямого доступа в память причем в любую ее часть. Это сделать просто. Си не проверяет корректность размера массива за этим должен следить программист, что дает ему возможность попасть куда угодно. Один из способов найти конкретное число в памяти. К примеру Вам нужно найти число десять типа int все просто. От указателя на массив используя адресную арифметику отнимаем нужное количество байт и проходим к самому началу памяти. Потом берем значение элемента и смотрим чему оно равняется. Десять все подсчитываем количество байт которые мы прошли. Не десять прибавляем 1 байт (именно один так как мы не знаем разбивку памяти) и все заново опять проверка. Но это очень муторный способ и который сопровождается большими глюками.
Вот такой механизм работы компилятора с массивами. Довольно просто не правда ли.

Автор Софронов Павел

Тематические ссылки
Ваша ссылка Ваша ссылка

Обмен кнопками, ведение статистики, реклама.