КОМПЬЮТЕРНАЯ ЛИТЕРАТУРА

Turbo C++ Version 1.0 Programmer’s Guide

Комментировать

LIB.com.ua [электронная библиотека]: : TURBO C++ Version 1.0 Programmer’s Guide

Модификаторы типа функции

Модификаторы near, far и huge могут также использовать-
сякак модификаторы типа функции; т.е., они могут модифициро-
вать, помимо указателей данных, функции и указатели функций.
Кроме того,для модификации функций могут служить модификато-
ры _export, _loadds и _saveregs.

Модификаторы функций near, far и huge могут комбиниро-
ваться с модификаторами cdecl или pascal, но не с interrupt.

Функции типа huge полезны для интерфейса с кодами на
языке ассемблера, не использующими такое же,как вTurbo С++,
распределение памяти.

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

Функция near использует ближние (near) вызовы; функ-
цияfar или huge использует дальние (far) команды вызова.

— 52 —

В случае моделей памяти tiny, small и compact функция,
где это не было задано явно, имеет по умолчанию тип near. В
моделях medium и large по умолчанию функция имеет тип far. В
модели памяти huge по умолчанию используется тип huge.

Функция huge аналогична функции far, за исключением то-
го, что при входе вфункцию huge регистрDS устанавливается на
адрес сегмента данных исходного модуля, нодля функции far
остается неустановленным.

Модификатор _export лексически анализируется, но игно-
рируется. Он обеспечивает совместимость с исходными модуля-
ми, написанными для OS/2. Для программ в DOS модификатор
_export никакого значения не имеет.

Модификатор _loadds указывает, что функция должна уста-
навливатьрегистр DS аналогично тому, как это делает функция
huge, но не подразумевает вызовов near или far. Таким обра-
зом, _loadds far эквивалентно объявлению huge.

Модификатор _saveregsзаставляет функцию сохранитьвсе
значения регистров и затем восстановить их перед возвра-
том(за исключением явных значений возврата, передаваемых в
таких регистрах AX или DX.)

Модификаторы _loadds и_saveregs полезны при написании
подпрограмм интерфейса нижнего уровня, как например, подп-
рограммы поддержки мыши.

Сложные объявления и деклараторы

Синтаксис декларатора см. на стр.35 оригинала.Определе-
ние включает в себя деклараторы идентификаторов и функций.

Простыеобъявления содержат список разделенных запятыми
идентификаторов, за которыми следуютопциональные специфика-
торы класса памяти, спецификаторы типа и прочие модификато-
ры.

Сложное объявление использует разделенный запятыми спи-
сок деклараторов,за которыми следуют различные спецификаторы
и модификаторы. В каждом деклараторе содержитсяровно один
идентификатор, а именно объявляемый им идентификатор. Каждый
из деклараторовв списке связан сведущим классом памяти и
спецификатором типа.

Формат декларатора указывает на то, каким образом объ-
явленное имя-декларатора должно интерпретироваться при ис-
пользовании в выражениях. Если type это любой тип, а специ-
фикатор-класса-памяти это любой спецификатор класса памяти,
то объявление

спецификатор-класса-памятиtype D1, D2;

указывает, что каждое вхождение D1 или D2 в выражение
будет рассматриваться как объект типа «type» и с заданным
«классом-памяти». Тип имени-декларатора, входящего в декла-
ратор, должно быть некоторой фразой, содержащей type, напри-
мер «type», «pointer to type», «array of type», «function
returning type» или «pointer to function returning type», и
т.д.

Например, в объявлениях

int n, nao[], naf[3], *pn, *apr[], (*pan)[], &nr=n

— 53 —
int f(void), *frp(void), (*pfn)(void);

каждый из деклараторов мог бы быть использован в ка-
честве значения переменной (правой части) (или, возможно, в

некоторых случаях в качестве именующего выражения (левой
части) ) в выражениях, где допустим один объект int. Типы
встроенных идентификаторов берутся из их деклараторов следу-
ющим образом:

Сложные объявления Таблица 1.17
————————————————————
Синтаксис Подразумеваемый тип имени Пример
————————————————————
type имя; type int count;
type имя[] (открытый) массив array of type int count[1];
type имя[3]; Фиксированный массив из трех int count[3];
элементов типа type
(name[0],name[1],name[3])
type *имя; Указатель на type int *count;
type *имя[]; (открытый) массив указателей int *count[];
type *(имя[]) То же самое int *(count[]);
type (*имя)[]; Указатель на (открытый) массив int
(*count)[];
типа type
type &имя; Ссылка на тип type (только С++) int &count;
type имя(); Функция, возвращающая тип type int count();
type *имя(); Функция, возвращающая указатель int *count();
на тип type
type *(имя()); То же самое int *(count());
type (*имя)(); Указатель на функцию, возвращающую int
(*count)();
тип type
————————————————————

Отметим необходимость круглых скобок в (*имя)[] и
(*имя)(), поскольку приоритет декларатора массива [] и дек-
ларатора функции () выше, чем декларатора указателя *. Круг-
лые скобки в *(имя[]) опциональны.

Указатели

Обсуждение создания ссылок и обращения по ссылкам (ра-
зыменования) см. на стр.80 оригинала.

Указатели делятся на две основные категории: указатели
объектов и указатели функций. Указатели обоихтипов представ-
ляют собой специальные объекты, хранящие адреса памяти.

Два этиклассауказателей имеют отличные друг от друга
свойства, назначения и правила манипулирования, хотя и те и
другие разделяют между собойопределенные операцииTurbo C++.
Вообще говоря, указатели функций используются для доступа к
функциям и для передачиодних функцийдругим в качествеаргу-
ментов; выполнение арифметических операцийс указателямифунк-
ций не допускается. И напротив, указателиобъектов при скани-
ровании массивов или более сложных структур памяти регулярно
инкрементируются и декрементируются.

Хотя указатели содержат числа сбольшинством характерис-
тик типаunsigned int, они имеют свои собственные правила и
ограничения на присвоения, преобразования ивыполнение с ними
арифметических действий. Примеры в следующих нескольких раз-
делах иллюстрируют эти правила и ограничения.

Указатели объектов

— 54 —
«Указатель на объект типа type» содержит адрес (то есть
указывает) объекта с типом type. Поскольку указатель сам по
себе является объектом, то вы можете установить указатель на
указатель (и т.д.). В число прочих объектов,на которые обыч-
но устанавливается указатель, входят массивы, структуры,объ-
единения и классы.

Размер указателей объектов зависит обычно от модели па-
мяти, размера и расположения сегментов данных, а также,
возможно, от опциональных модификаторов указателей (этот
вопрос рассматривается на стр.51 оригинала).

Указатели функций

Указатель функции лучше всего рассматривать как адрес,
обычно в кодовом сегменте, где располагается выполняемый код
функции; это адрес, по которому передается управление при
вызове функции. Размеры и расположение кодовых сегментов
программы определяется действующей моделью памяти, и в свою
очередь определяют размер указателей функций, которые нужны
для вызова функций.

Указатель функции имеет тип «указатель функции, возвра-
щающей тип type», где type есть тип возвращаемых функцией
данных.

В С++, где контроль типов данных болеестрогий, указа-
тель функции имеет тип «указатель функции принимающей агру-
менты типа type и возвращающей тип type». Действительно, в С
функция, определенная с типами аргументов, также будет иметь
данный, более узкий тип. Например,

void (*func)();

В С это будет указатель функции, не возвращающей ника-

Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *