Ответ 1
Структурный модуль имитирует структуры C. Процессу требуется больше циклов процессора для чтения 16-разрядного слова на нечетном адресе или 32-битном dword по адресу, не делящемуся на 4, поэтому структуры добавляют "байты на панели", чтобы члены структуры падали на естественные границы. Рассмотрим:
struct { 11
char a; 012345678901
short b; ------------
char c; axbbcxxxdddd
int d;
};
Эта структура будет занимать 12 байт памяти (x - байты пэдов).
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'
Остерегайтесь пропускать ручку структуры. В C эти структуры:
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'