Составные типы данных

В этом разделе рассматриваются модифицируемые, перечислимые и структурные типы данных языка Си.

9.1. Имена с модификаторами

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

Модификаторы cdecl,pascal,interrupt воздействуют на идентификатор и могут быть записаны непосредственно рядом c ним:

<модификатор> тип список;

тип <модификатор> список;

В ряде случаев допускаются оба варианта.

Модификаторы const,volatile,near,far,huge воздействуют либо на идентификатор, либо на указатель, расположенный непосредственно справа. Если справа расположен идентификатор, модифицируется тип именуемого объекта. Если справа расположен признак указателя "*", то преобразуется тип объекта, адресуемого указателем на модифицированный тип. Таким образом, конструкция "модификатор *" обозначает указатель на модифицированный тип.

Например, int const*t; - это указатель на const int, который можно переназначать, тогда как int * const t; — это const указатель на int и переназначить его нельзя.

Указание const не допускает действий по изменению значения переменной. Приведем пример.

char *const str = "Строка текста";

str = "Другая строка";

Последний оператор недопустим, т. к. пытается переназначить const указатель. Тем не менее, допустим оператор

strcpy(str,"Строка");

Последнее было бы невозможно для указателя видаchar const *str = "Строка текста";

т. к. он указывает на неизменяемую строку.

Модификатор volatile несет противоположный смысл. Он подчеркивает, что значение переменной может быть изменено не только исполняемой программой, но и некоторым внешним воздействием, например, программой обработки прерываний или обменом с внешним устройством. Фактически, объявление volatile "предупреждает" компилятор, что модифицируемая переменная может измениться в любой момент и не следует делать предположений относительно стабильности значения соответствующего объекта в памяти. Для выражений, содержащих объекты volatile, не будут применяться методы оптимизации кода, такие объекты не будет загружаться в регистры процессора.

Модификатор pascal в применении к идентификатору означает, что он преобразуется к верхнему регистру и к нему не добавляется символ подчеркивания. В применении к имени функции модификатор оказывает влияние также на передачу аргументов. В этом случае аргументы пересылаются в стек в прямомпорядке, т. е., первым отправляется первый аргумент. По умолчанию в Си принято пересылать аргументы в обратном порядке. Существует также настройка компиляции, которая присваивает всем функциям и указателям на функции тип pascal. Такие функции могут вызываться из программы на Паскале. При этом может потребоваться, чтобы некоторые функции и указатели на функции применяли вызывающую последовательность, принятую в Си, а их имена имели принятый для идентификаторов Си вид. В этом случае соответствующие объявления делаются с модификатором cdecl. Все функции в стандартных включаемых файлах объявлены с модификатором cdecl.Модификатор interrupt предназначен для объявления функций‑обработчиков прерываний. Для такой функции генерируется дополнительный код для сохранения и восстановления состояния регистров процессора. Модификатор не может использоваться совместно с near, far или huge. Приведем пример использования volatile и interrupt.

volatile int t;

void interrupt time() { t++; }

wait(int i) {

t=0;

while (t < i);

}

Без объявления t как volatile оптимизирующий компилятор мог бы вынести за пределы цикла сравнение t и i, поскольку обе они не меняются в теле цикла. Это привело бы к зацикливанию.

Модификаторы near, far, huge оказывают действие на работу с адресами объектов. Формат указателей, принятый в данный момент по умолчанию, определяется используемой моделью памяти (см. п. 11). Однако можно объявить указатель с форматом, отличным от действующего по умолчанию. Это делается с помощью явного указания ключевого слова near, far или huge:

char far *p = 0xB8000000ul; //"длинный" указатель сегмент+смещение

Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: