#c #endianness
#c #порядковость
Вопрос:
В c меня мало беспокоит концепция порядковости. Предположим, я объявляю целое число (2 байта) на маленькой десятичной машине как
int a = 1;
и она хранится как:
Address value
1000 1
1001 0
В big endian она должна храниться как наоборот. Теперь, если я сделаю amp; a, то я должен получить 1000 на обеих машинах.
Если это верно, то если я сохраню int a=1
, то я должен получить a = 1 на младшем конце, тогда как 2 ^ 15 на большом конце. Правильно ли это?
Ответ №1:
Для вас не должно иметь значения, как представлены данные, пока вы не передаете их между платформами (или не получаете к ним доступ через ассемблерный код).
Если вы используете только стандартный C — это скрыто от вас, и вам не стоит беспокоиться об этом. Если вы передаете данные между неизвестными компьютерами (например, у вас есть клиентское и серверное приложения, которые взаимодействуют через некоторую сеть) — используйте hton
и ntoh
функции, которые преобразуют из локального в сетевое и из сетевого в локальное порядковость, чтобы избежать проблем.
Если вы обращаетесь к памяти напрямую, то проблема будет не только в порядковом номере, но и в упаковке, так что будьте осторожны с этим.
Комментарии:
1. @prp: Нет, вы, вероятно, не получите 1 и 2 ^ 15. Вероятно, вы получите 0x0100 в качестве шестнадцатеричного значения, если ваша большая конечная машина считывает два байта данных, представляющих 0x0001, записанных на маленькой конечной машине, или если вы считываете на маленькой конечной машине данные, записанные на большой конечной машине.
2. Два исключения из правила «не имеет значения»: 1) Все, что «подключено к Интернету», такое как IP-адреса, имеет «сетевой порядок байтов» (большой порядковый номер) даже между двумя маленькими порядковыми номерами . Использование соответствующих функций-оболочек скрывает эти детали реализации и позволяет полностью избежать этой проблемы (читайте документы!). 2) Встроенные функции SSE. Некоторые из них могут подействовать на вас даже на той же машине, когда вы, казалось бы, пишете код на C, если вы не читаете внимательно . Это потому, что, например, в
_mm_set_ps
Intel предпочла упорядочить параметры наоборот, как и ожидало бы большинство «нормально мыслящих» людей.
Ответ №2:
Как в младшем, так и в старшем разрядах возвращается адрес «первого» байта. Здесь под «первым» я подразумеваю 1000 в вашем примере, а не «первый» в смысле наиболее значимого или наименее значимого байта.
Ответ №3:
Теперь, если я это сделаю
amp;a
, то я должен получить 1000 на младшем конце и 1001 на большом конце.
Нет; на обеих машинах вы получите адрес 1000.
Если это верно, то если я сохраню int a = 1, то я должен получить a = 1 в младшем конце, тогда как 2 ^ 15 в большом конце. Правильно ли это?
Нет; потому что предварительное условие равно false. Кроме того, если вы присвоите переменной 1, а затем снова прочитаете значение, вы получите результат 1 обратно. Все остальное было бы основной причиной путаницы. (Бывают случаи, когда это (считывание сохраненного значения) не гарантируется — например, если переменную могут изменять несколько потоков или если это регистр ввода-вывода во встроенной системе. Однако вы бы знали об этом, если бы вам нужно было знать об этом.)
По большей части вам не нужно беспокоиться о порядковости. Есть несколько мест, где вы это делаете. Сетевые функции сокетов являются одной из таких; запись двоичных данных в файл, который будет передаваться между машинами с разным порядковым номером, является другой. Практически все остальное время вам не нужно беспокоиться об этом.
Ответ №4:
Это правильно, но это проблема не только в c, но и в любой программе, которая считывает и записывает двоичные данные. Если данные останутся на одном компьютере, то все будет в порядке.
Кроме того, если вы читаете / записываете из текстовых файлов, это не будет проблемой.