Вы имели возможность убедиться, что структуры и объединения можно использовать для создания переменных разных размеров, а также в том, что настоящий размер этих переменных в разных машинах может быть разным. Оператор sizeof подсчитывает размер любой переменной или любого типа и может быть полезен, если в программах требуется свести к минимуму машинно-зависимый код. Этот оператор особенно полезен там, где приходится иметь дело со структурами или объединениями.
Перед тем как переходить к дальнейшему изложению, предположим, что определенные типы данных имеют следующие размеры:
Тип Размер в байтах
char 1
int 4
double 8
Поэтому при выполнении следующего кода на экран будут выведены числа 1, 4 и 8:
char ch;
int i;
double f;
printf("%d", sizeof(ch));
printf("%d", sizeof(i));
printf("%d", sizeof(f));
Размер структуры равен сумме размеров ее членов или, возможно, даже больше этой суммы. Рассмотрим пример:
struct s {
char ch;
int i;
double f;
} s_var;
Здесь sizeof(s_var) равняется как минимум 13 (=8+4+1). Однако размер s_var может быть и больше, потому что компилятору иногда необходимо специально увеличить размер структуры, выровнять некоторые ее члены на границу слова или параграфа. (Параграф занимает 16 байтов.) Так как размер структуры может быть больше, чем сумма размеров ее членов, то всегда, когда нужно знать размер структуры, следует использовать sizeof. Например, если требуется динамически выделять память для объекта типа s, необходимо использовать последовательность операторов, аналогичную той, что показана здесь (а не вставлять вручную значения длины его членов):
struct s *p;
p = malloc(sizeof(struct s));
Так как sizeof — это оператор времени компиляции, то вся информация, необходимая для вычисления размера любой переменной, становится известной как раз во время компиляции. Это особенно важно для объединений, потому что размер каждого из них всегда равен размеру наибольшего члена. Например, проанализируйте следующее объединение:
union u {
char ch;
int i;
double f;
} u_var;
Для него sizeof(u_var) равняется 8. Впрочем, во время выполнения не имеет значения, какой размер на самом деле имеет u_var. Важен размер его наибольшего члена, так как любое объединение должно быть такого же размера, как и его самый большой элемент.