Язык программирования Си для персонального компьютера
Шрифт:
Хотя объявления ра в примерах 9 и 10 идентичны, в примере 9 ра объявляется как указатель на near массив указателей на тип far char, а в примере 10 ра объявляется как указатель на far массив указателей на тип far char.
В примере 11 pb объявляется как указатель на near массив указателей на тип far char. В примере 12 pb объявляется как указатель на far массив указателей на тип far char.
Объявление функций
Правила применения модификаторов near и far в объявлениях функций аналогичны правилам применения их в объявлениях данных. Если непосредственно за модификатором следует имя функции, то данное ключевое слово определяет, в каком сегменте будет размещена функция. Например,
char far fun;
определяет fun как функцию, вызываемую по 32-битовому адресу и возвращающую тип char.
Если же непосредственно за специальным ключевым словом следует признак указателя (звездочка), то данное ключевое слово определяет тип адреса функций, которые могут вызываться через этот указатель. Например,
char (far *pfun);
определяет pfun как указатель (32-битовый) на far функцию, возвращающую char.
Модификатор huge к функциям и указателям на функции неприменим.
Объявления функций должны соответствовать их определениям по набору и расположению модификаторов. Рекомендуется всегда использовать предварительные объявления функций со списками типов аргументов, чтобы компилятор мог выявить ситуации некорректного вызова функции.
Примеры:
char far fun; /* пример 1: малая модель */
static char far *near fun; /* пример 2: большая модель */
void far fun; /* пример 3: малая модель */
void (far *pfun) = fun;
double far * far fun; /* пример 4: компактная модель */
double far* (far *pfun) = fun;
В первом примере fun объявляется как функция, возвращающая char. Ключевое слово far в объявлении означает, что fun вызывается по 32-битовому адресу типа far.
Во втором примере fun объявляется как near функция класса памяти static, возвращающая указатель на far char. Такая функция в большой модели памяти может быть использована, например, как вспомогательная подпрограмма, которая вызывается часто, но только функциями из своего исходного файла. Поскольку все функции из одного исходного файла помещаются в один и тот же сегмент, они могут обращаться друг к другу по адресам типа near. Будет ошибкой, однако, передать адрес функции fun в качестве аргумента другой функции, расположенной за пределами сегмента, в котором определена fun, поскольку из другого сегмента функция fun не может быть вызвана.
В
В примере 4 pfun объявляется как указатель на far функцию, возвращающую указатель на far double, после чего ему присваивается адрес функции fun. Такой вариант может использоваться, например, в компактной модели памяти для функции, которая используется редко, и потому необязательно должна находиться в стандартном сегменте кода. И функция, и указатель должны быть объявлены с модификатором far.
Модели памяти СП ТС
Организация работы с моделями памяти в СП ТС имеет ряд отличий от СП MSC.
В дополнение к описанным выше моделям СП ТС имеет еще одну — tiny (минимальную). В этой модели вся программа — код, данные, стек, динамическая память — размещается в одном сегменте. Таким образом, размер программы ограничен 64 Кбайтами. Все указатели в этой модели имеют тип near. Программы модели памяти tiny могут быть преобразованы в формат выполняемых файлов СОМ операционной системы MSDOS.
В компактной и большой моделях статические данные занимают не несколько сегментов, а один. В этом сегменте также размещается стек. По умолчанию для данных используются указатели типа far, однако для статических данных лучше применять указатели типа near. В компактной, большой и максимальной моделях стек занимает отдельный сегмент.
Только в максимальной модели памяти СП ТС позволяет статическим данным занимать более одного сегмента, т. е. более 64 Кбайтов. Однако в одном исходном файле может быть не более 64 Кбайтов статических данных. Вследствие этого недопустимы массивы, превышающие по размеру 64 Кбайта.
Указатели типа huge в СП ТС всегда хранятся в нормализованном виде, так что значение смещения никогда не превышает 15. Нормализация требует дополнительных временных затрат при работе с указателями тип huge, но зато позволяет применять к ним операции отношения (с ненормализованными 32-битовыми указателями операции отношения работают некорректно).
Допустимо применение модификатора huge к функциям и указателям на функции.
Имеется также четыре специальных указателя типа near с именами _cs, _ds, _ss, _es. Это 16-битовые указатели, ассоциированные с сегментными регистрами микропроцессора, содержащими адреса сегментов кода, данных, стека и динамической памяти, соответственно. Например, указатель р, объявленный следующим образом