В ответах много дезинформации, поэтому уточню. Это может быть по одной из двух причин (я не знаком с компилятором).
Единица хранения битового поля - 2.
Выравнивание выполняется по границе слова (2 байта).
Я сомневаюсь, что это первый случай, так как это обычное расширение, которое принимает единицу хранения битового поля в качестве размера объявленного «базового» типа. В этом случае типом является тип char, который всегда имеет размер 1.
[В стандарте вы можете объявлять только битовые поля типа int или unsigned int, и «единица хранения», в которой сгруппированы битовые поля, является фиксированной (обычно такой же размер, как и int). Даже одно битовое поле будет использовать одну единицу хранения.]
Во 2-м случае для компиляторов C характерно применение #pragma pack
, чтобы разрешить управление выравниванием. Я подозреваю, что упаковка по умолчанию равна 2, и в этом случае в конце объединения будет добавлен байт pad. Чтобы избежать этого, используйте:
#pragma pack(1)
Вы должны также использовать #pragma pack()
впоследствии, чтобы установить значение по умолчанию (или даже лучше использовать аргументы push и pop, если это поддерживается вашим компилятором).
Всем респондентам, которые сказали, что вы должны мириться с тем, что делает компилятор, это противоречит духу C. Вы должны иметь возможность использовать битовые поля для отображения на любой размер или битовый порядок в ситуациях, когда у вас нет контроль над ним, такой как формат файла или аппаратное отображение.
Конечно, это очень непереносимо, поскольку разные реализации имеют разные порядки байтов, порядки добавления битов в единицу хранения битовых полей (сверху или снизу), размер единиц хранения, выравнивание по умолчанию и т. Д.
Что касается вашего второго вопроса, я не вижу проблемы, хотя я никогда не использую scanf
, поскольку это проблематично.