Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Решенные оветы на теорию Си.docx
Скачиваний:
4
Добавлен:
01.03.2025
Размер:
166.91 Кб
Скачать

13. Производные типы данных. Указатели. Особенности использования. Адресная арифметика.

Производные типы можно условно подразделить на две группы:

  • Непосредственно производные типы. Эти типы являются производными от некоторых существующих типов, реализуя типы указателей, ссылки, функции преобразования типов. В группу непосредственно производных типов входят:

    • массивы

    • указатели

    • ссылки

    • перечисления

    • указатели на члены класса.

  • Составные производные типы:

    • классы

    • структуры

    • объединения

Указатель - это переменная, содержащая адрес переменной.

1) Унарный оператор & выдает адрес объекта:

p = &c - присваиваем переменной p адрес ячейки c Применяется к объектам, расположенным в памяти: к переменным и элементам массивов.

2) Унарный оператор * - оператор косвенного доступа - выдает объект, на который данный указатель указывает.

int х = 1, у = 2, z[10]; int *ip; /* ip - указатель на int */ ip = &x; /* теперь ip указывает на x */ y = *ip; /* y теперь равен 1 */ *ip = 0; /* x теперь равен 0 */ *ip = *ip + 10 - увеличивает *ip на 10.

Унарные операторы * и & имеют более высокий приоритет, чем арифметические операторы, так что присваивание

y = *ip + 1; берет то, на что указывает ip, и добавляет к нему 1, а результат присваивает переменной y.

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

1) p++ - p указывает на следующий элемент

2) p+=i - p указывает на i-й элемент после того, на который указывал ранее

3) если p и q указывают на элементы одного массива, то к ним можно применять операторы отношения ==, !=, <, >= и т. д :

а) p < q - истинно, если p указывает на более ранний элемент массива, чем q

б) можно сравнить на равенство/неравенство с нулем

в) вычитание указателей: если p<q, то q-p+1 -число элементов от p до q включительно

4) конструкция p + n означает адрес объекта, занимающего n-е место после объекта, на который указывает p

5) присваивание значения указателя другому указателю того же типа

Данные примеры арифметики над указателями - примеры адресной арифметики.

Арифметика с указателями учитывает тип: если она имеет дело со значениями float, занимающими больше памяти, чем char, и p - указатель на float, то p++ продвинет p на следующее значение float.

Нельзя складывать два указателя, перемножать их, делить, сдвигать, выделять разряды; указатель нельзя складывать со значением типа float или double; указателю одного типа нельзя присвоить указатель другого типа, не выполнив предварительно операции приведения (исключение составляют лишь указатели типа void*).

14. Операции над указателями. Указатели и модели памяти. Модификаторы.

Указатели и модели памяти

Размер памяти, выделяемой компилятором под указатель, зависит от модели памяти, для которой будет компилироваться программа. Память для программы на Турбо Си требуется для четырех целей:

- для размещения программного кода

- для статических данных

- для динамических данных по запросу из программы

- для организации стека

В зависимости от объема кода программы и данных, ее нужно скомпилировать для одной из шести моделей памяти, предлагаемых Турбо Си:

1. Tiny (крошечная): под код программы, статические данные, кучу и стек отводится

в сумме 64К памяти. Для указателя требуется два байта (близкий указатель).

2. Small (маленькая): под код программы отводится 64К; под стек, кучу и статические данные отводится в сумме 64К. Программа работает с близкими указателями.

3. Medium (средняя): под код программы - 1Мгб памяти. Все обращения к функциям и возвраты из функций, осуществляемые через указатель, должны использовать указатель длиной в 4байта, чтобы в нем мог разместиться далекий адрес памяти (далекий указатель). Под стек, кучу и статические данные - 64К памяти и для адресации

данных - близкие указатели.

4. Compact (компактная); под код программы -64К. Под данные - 1Мгб, но объем статических данных ограничивается размером 64К. Под стек - 64К. Адресация внутри программы осуществляется близкими указателями, а адресация данных - далекими указателями.

5. Large (большая). Под код программы - 1Мгб, под статические данные - 64К, куча может занимать до 1Мгб памяти.Как программа так и данные адресуются далекими указателями.

6. Huge (огромная). Аналогична Large, но объем статических данных может превышать 64К. Для любой адресации необходимы далекие указатели.

Модификаторы

Какая модель памяти должна быть выбрана для компиляции программы зависит от соотношения объемов код-данные.

Чтобы задать размер указателя, отличный от размера устанавливаемого при компиляции в той или иной модели памяти, используют модификаторы описания указателей near,

far и huge:

- модификатор near устанавливает 16-ти битный, т.е. близкий указатель. Данные программы ограниченны размером сегмента 64К;

- far устанавливает 32-х битный, т.е. далекий указатель. При использовании far-указателей можно ссылаться на данные в пределах 1 Мгб адресного пространства;

- huge устанавливает 32-х битный указатель аналогичный far-указателю, НО:

а) операции отношения ==, !=, <, >, <= и >= работают правильно с huge-указателями

б) все арифметические операции над указателями типа huge воздействуют как на адрес сегмента, так и на смещение, а при использовании указателей типа far воздействуют только на смещение.

Способы описания указателей с модификаторами near, far u huge.

Когда одно из этих ключевых слов встречается в описании, то оно модифицирует объект,

расположенный справа от ключевого слова, например:

char far *ptr; ptr описан как far-указатель,

int huge *ptr; ptr описан как huge-указатель,

float near *ptr; ptr описан как near=указатель,

int *(far *ptr); ptr описан как far-указатель на указатель к данным целого