русс | укр

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

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

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


Дата добавления: 2015-01-16; просмотров: 558; Нарушение авторских прав


Если 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. DEFINE NULL 0 /* POINTER VALUE FOR ERROR REPORT */DEFINE ALLOCSIZE 1000 /* SIZE OF AVAILABLE SPACE */ TATIC CHAR ALLOCBUF[ALLOCSIZE];/* STORAGE FOR ALLOC */TATIC CHAR *ALLOCP = ALLOCBUF; /* NEXT FREE POSITION */ HAR *ALLOC(N) /* RETURN POINTER TO N CHARACTERS */INT N;( IF (ALLOCP + N <= ALLOCBUF + ALLOCSIZE) { ALLOCP += N; RETURN(ALLOCP - N); /* OLD P */} ELSE /* NOT ENOUGH ROOM */ RETURN(NULL);) REE(P) /* FREE STORAGE POINTED BY P */HAR *P;( IF (P >= ALLOCBUF && P < ALLOCBUF + ALLOCSIZE) ALLOCP = P;) Дадим некоторые пояснения. Вообще говоря, указатель мо-жет быть инициализирован точно так же, как и любая другаяпеременная, хотя обычно единственными осмысленными значения-ми являются NULL (это обсуждается ниже) или выражение, вклю-чающее адреса ранее определенных данных соответствующего ти-па. Описание STATIC CHAR *ALLOCP = ALLOCBUF; определяет ALLOCP как указатель на символы и инициализируетего так, чтобы он указывал на ALLOCBUF, т.е. На первую сво-бодную позицию при начале работы программы. Так как имя мас-сива является адресом его нулевого элемента, то это можнобыло бы записать в виде STATIC CHAR *ALLOCP = &ALLOCBUF[0]; используйте ту запись, которая вам кажется более естествен-ной. С помощью проверки IF (ALLOCP + N <= ALLOCBUF + ALLOCSIZE) выясняется, осталось ли достаточно места, чтобы удовлетво-рить запрос на N символов. Если достаточно, то новое значе-ние ALLOCP не будет указывать дальше, чем на последнюю пози-цию ALLOCBUF. Если запрос может быть удовлетворен, то ALLOCвозвращает обычный указатель (обратите внимание на описаниесамой функции). Если же нет, то ALLOC должна вернуть некото-рый признак, говорящий о том, что больше места не осталось.В языке "C" гарантируется, что ни один правильный указательданных не может иметь значение нуль, так что возвращение ну-ля может служить в качестве сигнала о ненормальном событии,в данном случае об отсутствии места. Мы, однако, вместо нуляпишем NULL, с тем чтобы более ясно показать, что это специ-альное значение указателя. Вообще говоря, целые не могут ос-мысленно присваиваться указателям, а нуль - это особый слу-чай. Проверки вида IF (ALLOCP + N <= ALLOCBUF + ALOOCSIZE)и IF (P >= ALLOCBUF && P < ALLOCBUF + ALLOCSIZE) демонстрируют несколько важных аспектов арифметики указате-лей. Во-первых , при определенных условиях указатели можносравнивать. Если P и Q указывают на элементы одного и тогоже массива, то такие отношения, как <, >= и т.д., работаютнадлежащим образом. Например, P < Q истинно, если P указывает на более ранний элемент массива,чем Q. Отношения == и != тоже работают. Любой указатель мож-но осмысленным образом сравнить на равенство или неравенствос NULL. Но ни за что нельзя ручаться, если вы используетесравнения при работе с указателями, указывающими на разныемассивы. Если вам повезет, то на всех машинах вы получитеочевидную бессмыслицу. Если же нет, то ваша программа будетправильно работать на одной машине и давать непостижимые ре-зультаты на другой. Во-вторых, как мы уже видели, указатель и целое можноскладывать и вычитать. Конструкция P + N подразумевает N-ый объект за тем, на который P указывает внастоящий момент. Это справедливо независимо от того, на ка-кой вид объектов P должен указывать; компилятор сам масшта-бирует N в соответствии с определяемым из описания P разме-ром объектов, указываемых с помощью P. например, на PDP-11масштабирующий множитель равен 1 для CHAR, 2 для INT иSHORT, 4 для LONG и FLOAT и 8 для DOUBLE. Вычитание указателей тоже возможно: если P и Q указываютна элементы одного и того же массива, то P-Q - количествоэлементов между P и Q. Этот факт можно использовать для на-писания еще одного варианта функции STRLEN: STRLEN(S) /* RETURN LENGTH OF STRING S */ CHAR *S; { CHAR *P = S; WHILE (*P != '\0') P++; RETURN(P-S); } При описании указатель P в этой функции инициализированпосредством строки S, в результате чего он указывает на пер-вый символ строки. В цикле WHILE по очереди проверяется каж-дый символ до тех пор, пока не появится символ конца строки\0. Так как значение \0 равно нулю, а WHILE только выясняет,имеет ли выражение в нем значение 0, то в данном случае яв-ную проверку можно опустить. Такие циклы часто записывают ввиде WHILE (*P) P++; Так как P указывает на символы, то оператор P++ передви-гает P каждый раз так, чтобы он указывал на следующий сим-вол. В результате P-S дает число просмотренных символов, т.е. Длину строки. Арифметика указателей последовательна:если бы мы имели дело с переменными типа FLOAT, которые за-нимают больше памяти, чем переменные типа CHAR, и если бы Pбыл указателем на FLOAT, то оператор P++ передвинул бы P наследующее FLOAT. таким образом, мы могли бы написать другойвариант функции ALLOC, распределяющей память для FLOAT,вместо CHAR, просто заменив всюду в ALLOC и FREE описательCHAR на FLOAT. Все действия с указателями автоматически учи-тывают размер объектов, на которые они указывают, так чтобольше ничего менять не надо. За исключением упомянутых выше операций (сложение и вы-читание указателя и целого, вычитание и сравнение двух ука-зателей), вся остальная арифметика указателей является неза-конной. Запрещено складывать два указателя, умножать, де-лить, сдвигать или маскировать их, а также прибавлять к нимпеременные типа FLOAT или DOUBLE.


<== предыдущая лекция | следующая лекция ==>
Указатели и массивы | Указатели символов и функции


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 0.039 сек.