 |
С учетом этого, следующие операторы являются недопустимыми:
pi= 3.0; /* присвоение значения константе */
i= maxint++; /* инкремент константы */
str = "Hi, there!"; /* установка указателя str на
что-то еще
Однако, отметим, что вызов функции strcpy(str,"Hi,
there!") является допустимым, поскольку он выполняет посим-
вольное копирование из строкового литерала "Hi, there!" в
адрес памяти, указываемый str.
В С++ const также "скрывает" объект const и предотвра-
щает внешнюю компоновку. При необходимости нужно использо-
вать extern const. Указатель на const не может быть присвоен
- 49 -
указателю на неconst (в противном случае значению const мог-
ло было быть выполнено присвоение при помощи указателя на не
-const.) Например,
char *str3 = str2 /* запрещено */
Модификатор функции прерывания interrupt
Модификатор interrupt специфичен для Turbo C++. Функции
прерывания предназначены для работы с векторами прерывания
8086/8088. Turbo C++ компилирует функцию interrupt с допол-
нительным кодом входа и выхода, таким образом, чтобы сохра-
нялись регистры AX, BX, CX, DX, SI, DI, ES иDS. Прочие ре-
гистры (BP, SP, SS, CS и IP) сохраняются как часть
вызывающей последовательности С или как часть самого обра-
ботчикапрерываний. Для возвратафункция использует команду
Iret, поэтому функция можетслужить для обслуживания аппарат-
ных илипрограммных прерываний. Ниже показан пример типичного
определения interrupt:
void interrupt myhandler()
(*
...
*)
Вы должны объявлять функции прерывания с типом void.
Функции прерывания могут быть объявлены с любой моделью па-
мяти. Для всех моделей памяти, кроме huge, DS устанавливает-
ся на сегмент данных программы. В случае модели huge DS ус-
танавливаетсяна сегмент данных модуля.
Модификатор volatile
В C++ volatile имеетспециальное значение для функций
компонентов класса. Если вы объявили объект volatile, вы мо-
жете использовать для него только функции компонентов
volatile.
Модификатор volatile указывает, что данный объект может
быть модифицирован не только вами, но также и извне вашей
программы, например, подпрограммой прерывания или портом
ввода/вывода. Объявление объекта volatile предупреждает ком-
пилятор, что тот не должен делать допущений относительно
значения объекта во время расчета содержащих его выражений,
поскольку его значение (теоретически) можетв любой момент
измениться. Компилятор также не будет делать такую перемен-
ную регистровой переменной.
volatile int ticks;
interrupt timer()
(*
ticks++;
*)
wait(int interval)
(*
ticks = 0;
while (ticks < interval); // не делает ничего
Эти подпрограммы (предполагается, что timer правильно
связана с аппаратным прерыванием часов) реализуют выдержкупо
времени между"тиканьем" часов, заданную аргументом interval.
Высоко оптимизированный компилятор не может загружать значе-
ние ticks в проверку выхода из цикла while, так как цикл не
изменяет значения ticks.
Модификаторы cdecl и pascal
Turbo C++ позволяет вашим программам легко вызывать
- 50 -
подпрограммы, написанные на других языках, и наоборот.При
смешанном программировании приходится иметь дело с двумя
важными вопросами: идентификаторы и передача параметров.
В Turbo C++ все глобальные идентификаторы сохраняются в
своем исходном виде (строчные, заглавныебуквы и их комбина-
ции) с присоединенным в начале идентификатора знакомподчер-
кивания (_), если вы не выберете опцию-u-
(GenerateUnderbars...Off) в диалоговом поле Options \!
Compiler \! Code Generation).
На стр.32 оригинала рассказано, как использовать
extern,что позволяет ссылаться на имена С из программы на C+
+.
pascal
В Паскале глобальные идентификаторы не сохраняются в
своем исходном виде и не имеют первым символом знак подчер-
кивания. Turbo C++ позволяют объявлять любые идентификаторы
как имеющие тип pascal; тогда такойидентификатор преобразо-
вывается к верхнему регистру, и ему непредшествует знак под-
черкивания. (Если идентификатор является функцией,то что
также влияет на используемую последовательность передачи па-
раметров;подробности см. на стр. 51 оригинала, "Модификаторы
типа функции".)
Опция компилятора -p (Calling Convention...Pascal в ди-
алоговом поле Options \! Compiler \!Code Generation) вызыва-
ет обработку функций (и указателей на эти функции) как если
бы они имели тип pascal.
Модификатор pascal специфичен для Turbo C++; он пред-
назначен для функций (и указателей функций), использующих
последовательность передачи параметров Паскаля. Кроме того,
функции, объявленные с типом pascal, могут тем не менее вы-
зываться из подпрограмм С, если последним известно, что дан-
ная функция имеет тип pascal.
pascal putnums(int i, int j, int k)
(*
printf("And the answers are: %d, %d, and %j\n",i,j,k);
*)
Функции типа pascal немогут принимать переменное число
аргументов, в отличие от таких функций, как printf. Поэтому
в определении функции типа pascal использовать многоточие
(...) нельзя.
cdecl
Программа main должна быть объявлена как cdecl, пос-
кольку загрузочный код С всегда пытается вызвать главную
процедуру (main) по соглашениям С.
После компиляции программы с опцией -pвам может понадо-
биться,чтобы некоторые идентификаторы сохранили регистр, в
котором они были первоначально набраны, и ведущий знак под-
черкивания, особенно если это идентификаторы С из другого
файла. Это можно сделать, объявив этиидентификаторыкак
cdecl. (Это также влияет на передачу параметров функциям).
Как и pascal, модификатор cdecl специфичен для Turbo C+
+. Он используется с функциями и указателями функций. Этот-
модификатор переопределяет директиву компилятора -p и позво-
ляет вызывать такую функцию как правильную функцию С. Напри-
мер, если вы компилируете предыдущую программус
- 51 -
установленной опцией -p, но желаете использовать printf, то
нужно сделать следующее:
extern cdecl printf();
putnums(int i, int j, int k);
cdecl main()
(*
putnums(1,4,9);
*)
putnums(int i, int j, int k)
(*
printf("And the answers are: %d, %d, and %j\n",i,j,k);
*)
При компиляции такой программы с опцией -p все функции
из библиотеки исполняющей системы должны иметь объявление
cdecl. Если вы посмотрите файлы заголовка (такие как
stdio.h), вы увидите, что с учетом этого каждая функция оп-
ределена там как cdecl.
Модификаторы указателей
Turbo C++ имеет восемь модификаторов, влияющих на опе-
рацию обращения поссылке, то есть на модификацию указателей
в данные. Эти модификаторы: near, far, huge, _cs, _ds, _es,
_seg и _ss.
С позволяет выполнять компиляцию с использованием одной
из нескольких моделей памяти. Используемая вами модель опре-
деляет (помимо всего прочего) внутренний формат указателей.
Например, при использованиималой данных small (tiny, small,
medium)все указатели данных содержат 16-битовое смещение ре-
гистра сегмента данных (DS). При использовании большой моде-
ли данных (compact, large, huge)все указатели данных имеют
длину 32 бита и содержат как адрес сегмента, так и смещение.
Иногда, используя один размер модели данных, вам может
понадобитьсяобъявить указатель, размер или формат которого
отличен от текущегопо умолчанию.Это делаетсяс помощью моди-
фикаторов указателей.
Углубленное рассмотрение указателей near, far и huge
см. на стр. 192 оригинала в главе 4, а описание нормализо-
ванных указателей см. на стр. 193 оригинала. Кроме того, см.
на стр. 199 оригинала обсуждение _cs, _ds, _es, _seg и _ss.
|