байтовый порядок байтов
На разных машинах этот код может давать разные результаты:
union endian_example {
unsigned long u;
unsigned char a[sizeof(unsigned long)];
} x;
x.u = 0x0a0b0c0d;
int i;
for (i = 0; i< sizeof(unsigned long); i++) {
printf("%u\n", (unsigned)x.a[i]);
}
Это связано с тем, что разные машины могут хранить значения в любом порядке байтов. Это довольно произвольно. В великой схеме вещей нет ни вперед, ни вперед.
Бит Endianness
Обычно вам не нужно беспокоиться о порядке байтов. Наиболее распространенный способ доступа к отдельным битам - сдвиги (>>
, <<
), но они действительно связаны со значениями, а не байтами или битами. Они предварительно выполняют арифметическую операцию над значением. Это значение хранится в битах (в байтах).
Где вы можете столкнуться с проблемой в C с порядком байтов, если вы когда-либо используете битовое поле. Это редко используемая (по этой и некоторым другим) «функциям» C, позволяющая сообщать компилятору, сколько битов будет использовать член struct
.
struct thing {
unsigned y:1; // y will be one bit and can have the values 0 and 1
signed z:1; // z can only have the values 0 and -1
unsigned a:2; // a can be 0, 1, 2, or 3
unsigned b:4; // b is just here to take up the rest of the a byte
};
В этом порядке байтов зависит от компилятора. Должен ли y
быть наиболее или наименее значимым битом в thing
? Кто знает? Если вы заботитесь о порядке следования битов (описывая такие вещи, как расположение заголовка пакета IPv4, управляющие регистры устройства или просто формат хранилища в файле), то вам, вероятно, не стоит беспокоиться о том, что какой-то другой компилятор сделает это неправильно путь. Кроме того, компиляторы не всегда так умны в работе с битовыми полями, как можно было бы надеяться.