Объединяются ключевым словом union. Способы описания такие же, как и в случае структур, только вместо слова struct используется слово union.
union {int a; long b;} pr;
Для переменной pr выделяется память, достаточная для хранения самого длинного элемента объединения, т. е. в нашем примере - 4 байта.
Если использовать pr.a, то выделенная память будет использоваться как int, в случае pr.b как long. Однако, участок памяти один и тот же. Поэтому одновременно существовать pr.a и pr.b не могут. Ответственность за некорректное использование памяти лежит на программисте. Объединения используются для экономии памяти:
union {int bc[100]; double kk[20];} cc;
На все отводится 200 байт.
int bc[100] 200 байт
______________________________
|----------------------------|
double kk[20] (160 байт)
Одновременно работать с массивом cc.bc и cc.kk нельзя.
Объединения нельзя инициализировать.
Препроцессор обрабатывает текст программы перед компиляцией.
1. Включение файлов (рассмотрено ранее):
#include <conio.h> - файл из специального каталога;
#include "d:\\user\\ff.h" - файл ищется по правилам MS DOS.
2. Текстовые подстановки (рассматривалось ранее):
#define N 21
#define ABC (a*b*c+\
d*sin(x))
\ - переход на следующую строку.
3. Создание макросов.
#define SQR(x) ((x)*(x))
В результирующую строку подставляется фактическая строка x. Например, если в тексте программы встречается SQR(y), то после макрораскрутки получим ((y)*(y)). Скобки нужны для того, чтобы не получилось недоразумений, например
#define SQR(x) x*x
SQR(y+2); превратится в
y+2*y+2;
Конечно, это не то, что хотелось.
4. Отмена ранее созданного имени:
#undef SQR.
5. Условная компиляция:
#if константное выражение
.
. строки программы
.
#else
.
. строки программы
.
#endif
Если константное выражение истинно, то в программу будут включены строки из первого блока, иначе из второго.
Пример:
#define DEBUG 1
.
.
.
#if DEBUG
printf("%d", x);
#endif
Можно проверить наличие или отсутствие какого-либо имени:
#ifdef имя (если имя определено, то истина)
.
.
.
#else
.
.
.
#endif
#ifndef имя (если имя не определено)
.
.
.
#else
.
.
.
#endif
Это свойство широко используется в библиотечных включаемых файлах, чтобы избежать противоречия. Например, в conio.h имеются следующие строки:
#ifndef COLORS
enum COLORS {BLACK, ...};
#endif
Эта конструкция языка C в некоторых случаях позволяет заменить оператор if и сократить запись программы.
БНФ:
условное выр = выр0 "?" выр1 ":" выр2
Значение условного выражения равно выр1, если выр0 не равно 0 и выр2 впротивном случае.
Пример:
a = b>c ? b:c; тоже самое, что
if (b>c) a=b; else a = c;
С помощью условного выражения можно, например, определить макросы max и min:
#define max(x,y) ((x)>(y) ? (x):(y))
#define min(x,y) ((x)<(y) ? (x):(y))
При этом макросы max и min будут работать для любых типов арифметических данных.