Oбъединения - это переменная, которая в различные момен-ты времени может содержать объекты разных типов и размеров,причем компилятор берет на себя отслеживание размера и тре-бований выравнивания. Объединения представляют возможностьработать с различными видами данных в одной области памяти,не вводя в программу никакой машинно-зависимой информации. В качестве примера, снова из символьной таблицы компиля-тора, предположим, что константы могут быть типа INT , FLOATили быть указателями на символы. значение каждой конкретнойконстанты должно храниться в переменной соотвествующего ти-па, но все же для управления таблицей самым удобным было бы,если это значение занимало бы один и тот же объем памяти ихранилось в том же самом месте независимо от его типа. это иявляется назначением объединения - выделить отдельную пере-менную, в которой можно законно хранить любую одну из пере-менных нескольких типов. Как и в случае полей, синтаксис ос-новывается на структурах. UNION U_TAG \( INT IVAL; FLOAT FVAL; CHAR *PVAL; \) UVAL; Переменная UVAL будет иметь достаточно большой размер,чтобыхранить наибольший из трех типов, независимо от машины, накоторой осуществляется компиляция, - программа не будет за-висить от характеристик аппаратных средств. Любой из этихтрех типов может быть присвоен UVAR и затем использован ввыражениях, пока такое использование совместимо: извлекаемыйтип должен совпадать с последним помещенным типом. Делопрограммиста - следить за тем, какой тип хранится в объеди-нении в данный момент; если что-либо хранится как один тип,а извлекается как другой, то результаты будут зависеть отиспользуемой машины. Синтаксически доступ к членам объединения осуществляетсяследующим образом: имя объединения.член --------------------или указатель объединения ->член ---------------------------- то есть точно так же, как и в случае структур. если для отс-леживания типа, хранимого в данный момент в UVAL, использу-ется переменная UTYPE, то можно встретить такой участокпрограммы: IF (UTYPE == INT) PRINTF("%D\N", UVAL.IVAL); ELSE IF (UTYPE == FLOAT) PRINTF("%F\N", UVAL.FVAL); ELSE IF (UTYPE == STRING) PRINTF("%S\N", UVAL.PVAL); ELSE PRINTF("BAD TYPE %D IN UTYPE\N", UTYPE); Объединения могут появляться внутри структур и массивови наоборот. Запись для обращения к члену объединения вструктуре (или наоборот) совершенно идентична той, котораяиспользуется во вложенных структурах. например, в массивеструктур, определенным следующим образом STRUCT \( CHAR *NAME; INT FLAGS; INT UTYPE; UNION \( INT IVAL; FLOAT FVAL; CHAR *PVAL; \) UVAL; \) SYMTAB[NSYM]; на переменную IVAL можно сослаться как SYMTAB[I].UVAL.IVAL а на первый символ строки PVAL как *SYMTAB[I].UVAL.PVAL В сущности объединение является структурой, в которой всечлены имеют нулевое смещение. Сама структура достаточно ве-лика, чтобы хранить "самый широкий" член, и выравниваниепригодно для всех типов, входящих в объединение. Как и вслучае структур, единственными операциями, которые в настоя-щее время можно проводить с объединениями, являются доступ к члену и извлечение адреса; объединения не могут быть присво-ены, переданы функциям или возвращены ими. указатели объеди-нений можно использовать в точно такой же манере, как и ука-затели структур. Программа распределения памяти, приводимая в главе 8 ,показывает, как можно использовать объединение, чтобы сде-лать некоторую переменную выровненной по определенному видуграницы памяти.