Со структурами и объединениями могут производиться сле-дующие операции: ссылка на один из членов структуры илиобъединения (с помощью операции.), получение адреса (спомощью унарной операции
&), присваивание структуры струк-туре, передача структуры в качестве формального параметра,возврат структуры функцией. Все остальные операции запре-щены. В реализации возвращения структур функциями на CM-ЭВМимеется коварный дефект: если во время возврата происходитпрерывание и та же самая функция реентерабельно вызываетсяво время этого прерывания, то значение, возвращаемое из пер-вого вызова, может быть испорчено. Эта трудность может воз-никнуть только при наличии истинного прерывания, как из опе-рационной системы, так и из программы пользователя; прерыва-ния, которое действительно асинхронно; обычные рекурсивныевызовы совершенно безопасны. В разделе "Выражения" говорится, что при прямой иликосвенной ссылке на структуру (с помощью. или - >) имясправа должно быть членом конструкции, названной или указан-ной выражением слева. Это ограничение не навязывается строгокомпилятором, чтобы дать возможность обойти правила соот-ветствия типов. В действительности перед. допускаетсялюбое l_значение и затем предполагается, что это l_значениеимеет форму структуры, для которой стоящее справа имя явля-ется членом. Таким же образом, от выражения, стоящего перед - >, требуется только быть указателем или целым. В случаеуказателя предполагается, что он указывает на структуру, длякоторой стоящее справа имя является членом. В случае целогооно рассматривается как абсолютный адрес соответствующейструктуры, заданный в единицах машинной памяти. Такие структуры не являются переносимыми.
-46-
Функции
Только две операции можно применять к функции: вызватьее или извлечь ее адрес. Если имя функции входит в выражениене в позиции имени функции, соответствующей обращению к ней,то генерируется указатель на эту функцию. Следовательно,чтобы передать одну функцию другой, можно написать
int f ();...
g (
f); тогда определение функции
g могло бы выглядеть так:
g (
funcp)
int (
*funcp)();
{... (
*funcp)();...
} Обратите внимание, что в вызывающей процедуре функция
f должна быть описана явно, потому что за ее появлением в
g (
f)не следует скобка "(".