Ответ 1
Да - ваш расчет верен. На вашем компьютере sizeof(int) == 4
и int
должны быть выровнены в 4 байта.
Вы можете узнать о заполнении, вручную добавив размеры базовых элементов и вычтя их из размера, указанного функцией sizeof (). Вы можете предсказать заполнение, если вы знаете требования к выравниванию на вашей машине. Обратите внимание, что некоторые машины довольно суетливы и выдают ошибки SIGBUS при доступе к смещенным данным; другие более слабые, но замедляют работу при доступе к выровненным данным (и они могут поддерживать «#pragma packed
» или что-то подобное). Часто базовый тип имеет размер, равный степени 2 (1, 2, 4, 8, 16), и такой n-байтовый тип должен быть выровнен по n-байту. Кроме того, помните, что структуры должны быть дополнены так, чтобы массив структур оставил все элементы правильно выровненными. Это означает, что структура обычно будет дополнена размером, кратным размеру наиболее строго выровненного элемента в структуре.
Ответ 2
Вообще, вариант на первом лучше; это остается правильным, когда вы меняете базовый тип массива с 'foo' на 'foobar'. Макрос, который я обычно использую:
#define DIM(x) (sizeof(x)/sizeof(*(x)))
У других людей есть другие имена для той же основной операции - и вы можете отнести имя, которое я использую, к загрязнению из смутного и далекого прошлого и некоторому использованию Бейсика.
Как обычно, есть предостережения. В частности, вы не можете применить это осмысленно к аргументам массива функции или к динамически распределенному массиву (используя malloc()
et al или new[]
); Вы применили к фактическому определению массива. Обычно значение является константой времени компиляции. Под C99 это могло быть оценено во время выполнения, если массив является массивом VLA - переменной длины.
Ответ 3
Из-за способа инициализации, когда у вас недостаточно скобок. Ваша структура 'foo' должна иметь два элемента. 10 и 20 размещены в первом ряду; 30 и неявный 0 поставляются во второй ряд. Следовательно, размер равен двум. Когда вы задаете подкобы, в массиве есть 3 элемента, первые компоненты которых имеют значения 10, 20, 30, а вторые компоненты имеют нули.