Программирование на C и C++

Онлайн справочник программиста на C и C++

Использование sizeof для обеспечения переносимости

Как было показано, структуры и объединения могут использоваться для создания переменных различных типов и настоящий размер этих переменных может меняться при переносе программы с одной платформы на другую. Унарный оператор sizeof используется для вычисления размера любой переменной или типа, и он может использоваться для устранения машинной зависимости кода программы. Особенно он эффективен при использовании со структурами и объединениями.

Необходимо помнить, что Borland С++ имеет следующие размеры для следующих типов данных:

Тип Размер в байтах
char
int (16 бит)
int (32 бита)
long int
float
double
long double
1
2
4
4
4
8
10

Следовательно, если в системе используются 16-битные целые, то следующий код выдаст на экран 1, 2, 4 и 10:

char ch;
int i;
float f;
printf("%d", sizeof ch);
printf("%d", sizeof i);
printf("%d", sizeof f);
printf("%d", sizeof (long double));

Размер структуры равен или больше суммы размеров ее членов. Например:

struct s {
char ch;
int i;
float f;
} s_var;

Здесь sizeof(s_var) имеет размер, по крайней мере 7 (4+2+1). На самом деле размер s_var может быть больше. В зависимости от используемого компилятора (и от установки опций), возможно выравнивание данных на границу слов (или параграфов). Это означает, что размер составного типа данных (типа структур) может быть немного больше, чем сумма частей. Таким образом, складывание вручную длин членов структуры может не дать правильного размера. Поэтому для максимальной переносимости следует использовать sizeof для определения размера структурной переменной.

Поскольку оператор sizeof - это оператор времени компиляции, вся необходимая информация для вычисления размера переменных известна на этапе компиляции. Это особенно важно для объединений, поскольку размер объединений всегда равен размеру самого большого члена. Рассмотрим следующий пример:

union u {
char ch;
int i;
float f;
} u_var;

sizeof(u var) будет равен 4. Во время выполнения не имеет значения, что содержит u_var. Имеет значение только размер наибольшей переменной, которую оно может содержать, поскольку размер объединения совпадает с размером наибольшего элемента.