Модуль struct имитирует C-структуры. Процессору требуется больше циклов ЦП, чтобы прочитать 16-разрядное слово по нечетному адресу или 32-разрядное слово по адресу, не делимому на 4, поэтому структуры добавляют «байты заполнения», чтобы элементы структуры попадали на естественные границы. Рассмотрим:
struct { 11
char a; 012345678901
short b; ------------
char c; axbbcxxxdddd
int d;
};
Эта структура будет занимать 12 байтов памяти (x - это байты pad).
Python работает аналогично (см. Документацию struct ):
>>> import struct
>>> struct.pack('BHBL',1,2,3,4)
'\x01\x00\x02\x00\x03\x00\x00\x00\x04\x00\x00\x00'
>>> struct.calcsize('BHBL')
12
Компиляторы обычно имеют способ устранения дополнения. В Python любой из = <>! исключит заполнение:
>>> struct.calcsize('=BHBL')
8
>>> struct.pack('=BHBL',1,2,3,4)
'\x01\x02\x00\x03\x04\x00\x00\x00'
Остерегайтесь позволить struct обрабатывать отступы. В С эти структуры:
struct A { struct B {
short a; int a;
char b; char b;
}; };
обычно составляют 4 и 8 байтов соответственно. Заполнение происходит в конце структуры в случае, если структуры используются в массиве. Это сохраняет члены 'a' выровненными по правильным границам для структур, которые будут позже в массиве Структурный модуль Python в конце не дополняется:
>>> struct.pack('LB',1,2)
'\x01\x00\x00\x00\x02'
>>> struct.pack('LBLB',1,2,3,4)
'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04'