Порядок байтов, почему символы помещаются в печать Int16 задом наперед?

Следующий код C, скомпилированный и запущенный в XCode:

UInt16 chars = 'ab';
printf("\nchars: %2.2s", (char*)&chars);

печатает «ба», а не «аб».

Почему?


person morgancodes    schedule 21.10.2011    source источник
comment
Разрешается ли вообще 'ab' быть литералом? Какой это компилятор (платформа)?   -  person Blagovest Buyukliev    schedule 21.10.2011
comment
Это C. g++ (я думаю), работающий за XCode.   -  person morgancodes    schedule 21.10.2011


Ответы (4)


Эта конкретная реализация, похоже, хранит многосимвольные константы в формате с прямым порядком байтов. В константе 'ab' символ 'b' является младшим значащим байтом (маленький конец), а символ 'a' является старшим байтом. Если бы вы рассматривали chars как массив, это были бы chars[0] = 'b' и chars[1] = 'a', и, таким образом, printf обрабатывал бы их как "ba".

Кроме того, я не уверен, насколько точным вы считаете Википедию, но в отношении синтаксиса C она имеет эта секция:

Многосимвольные константы (например, «xy») допустимы, хотя и редко полезны — они позволяют хранить несколько символов в целом числе (например, 4 символа ASCII могут поместиться в 32-битном целом, 8 — в 64-битном). Поскольку порядок, в котором символы упаковываются в одно целое, не указан, переносимое использование многосимвольных констант затруднено.

Таким образом, формат многосимвольной константы 'ab' следует избегать в целом.

person Andrew Cottrell    schedule 21.10.2011

Это зависит от системы, в которой вы компилируете/запускаете свою программу.

Очевидно, что в вашей системе короткое значение хранится в памяти как 0x6261 (ba): обратный порядок байтов.

Когда вы просите декодировать строку, printf будет байт за байтом считывать значение, которое вы сохранили в памяти, которое на самом деле равно «b», а затем «a». Итак, ваш результат.

person Alex Garcia    schedule 21.10.2011

Литералы многосимвольных символов определяются реализацией:

C99 6.4.4.4p10: «Значение целочисленной символьной константы, содержащей более одного символа (например,« ab »), или содержащую символ или управляющую последовательность, которая не отображается на однобайтовый символ выполнения, определяется реализацией. ."

gcc и icl печатают ba в Windows 7. tcc печатает a и вообще отбрасывает вторую букву...

person Dennis    schedule 21.10.2011
comment
Значения, определенные реализацией, и неопределенное поведение — это разные вещи. - person Steve Jessop; 21.10.2011

Ответ на ваш вопрос можно найти в ваших тегах: Endianness. На машине с прямым порядком байтов наименее значащий байт сохраняется первым. Это условность и никак не влияет на эффективность.

Конечно, это означает, что вы не можете просто привести его к строке символов, так как порядок символов неправильный, потому что в строке символов нет значащих байтов, а есть только последовательность.

Если вы хотите просмотреть байты в вашей переменной, я предлагаю использовать отладчик, который может считывать фактические байты.

person Constantinius    schedule 21.10.2011