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



         

Адресная арифметика


Если p является указателем, то каков бы ни был сорт объекта, на который он указывает, операция p++ увеличивает p так, что он указывает на следующий элемент набора этих объектов, а операция p +=i увеличивает p так, чтобы он указывал на элемент, отстоящий на i элементов от текущего элемента. Эти и аналогичные конструкции представляют собой самые простые и самые распространенные формы арифметики указателей или адресной арифметики.

Язык "C" последователен и постоянен в своем подходе к адресной арифметике; объединение в одно целое указателей, массивов и адресной арифметики является одной из наиболее сильных сторон языка. Давайте проиллюстрируем некоторые из соответствующих возможностей языка на примере элементарной (но полезной, несмотря на свою простоту) программы распределения памяти. Имеются две функции: функция alloc(n) возвращает в качестве своего значения указатель p, который указывает на первую из n последовательных символьных позиций, которые могут быть использованы вызывающей функцию alloc программой для хранения символов; функция free(p) освобождает приобретенную таким образом память, так что ее в дальнейшем можно снова использовать. программа является "элементарной", потому что обращения к free должны производиться в порядке, обратном тому, в котором производились обращения к alloc. Таким образом, управляемая функциями alloc и free память является стеком или списком, в котором последний вводимый элемент извлекается первым. Стандартная библиотека языка "C" содержит аналогичные функции, не имеющие таких ограничений, и, кроме того, в лекции №8 мы приведем улучшенные варианты. Между тем, однако, для многих приложений нужна только тривиальная функция alloc для распределения небольших участков памяти неизвестных заранее размеров в непредсказуемые моменты времени.

Простейшая реализация состоит в том, чтобы функция раздавала отрезки большого символьного массива, которому мы присвоили имя allocbuf. Этот массив является собственностью функций alloc и free. Так как они работают с указателями, а не с индексами массива, никакой другой функции не нужно знать имя этого массива. Он может быть описан как внешний статический, т.е. он будет локальным по отношению к исходному файлу, содержащему alloc и free, и невидимым за его пределами. При практической реализации этот массив может даже не иметь имени; вместо этого он может быть получен в результате запроса к операционной системе на указатель некоторого неименованного блока памяти.

Другой необходимой информацией является то, какая часть массива allocbuf уже использована. Мы пользуемся указателем первого свободного элемента, названным allocp. Когда к функции alloc обращаются за выделением n символов, то она проверяет, достаточно ли осталось для этого места в allocbuf. Если достаточно, то alloc возвращает текущее значение allocp (т.е. начало свободного блока), затем увеличивает его на n, с тем чтобы он указывал на следующую свободную область. функция free(p) просто полагает allocp равным p при условии, что p указывает на позицию внутри allocbuf.




Содержание  Назад  Вперед