Совпадает ли адрес типа int с прямым и обратным порядком байтов?

Например, если у меня есть массив int.

int arr[3] = { 1 , 2 , 3 } ;
unsigned char * a = ( unsigned char* )&arr[0] ;

printf("%d " , *( int* )a ) ;
a += sizeof( int ) ;
printf("%d " , *( int* )a ) ;
a += sizeof( int ) ;
printf("%d " , *( int* )a ) ;

Будет ли этот код производить 1 2 3 как на архитектуре с прямым порядком, так и на архитектуре с прямым порядком байтов?

Я предполагаю, что это верно для всех типов, включая структуры?


person this    schedule 26.11.2013    source источник
comment
Поскольку хранилище, т.е. запись и последующее чтение, являются указателями int, оно должно печатать 1 2 3. Вы пробовали это и нашли другой ответ?   -  person Ganesh    schedule 26.11.2013
comment
@Ganesh У меня нет машины с прямым порядком байтов.   -  person this    schedule 26.11.2013
comment
Большой / маленький порядок байтов в вопросе также относится к strcutures, однако распространение вашего примера на структуры может вызвать проблемы с заполнением.   -  person alk    schedule 26.11.2013
comment
@alk Как так, sizeof не заботится об этом?   -  person this    schedule 26.11.2013
comment
@self .. Если вы typecast данные из одного типа в другой, тогда вы можете ожидать проблем, если интерпретация данных не будет обработана должным образом. Структуры также должны вести себя одинаково в обеих архитектурах, включая вопросы заполнения. Пожалуйста, проверьте этот запрос для получения более подробной информации по этой теме: stackoverflow.com/questions/9971369/   -  person Ganesh    schedule 26.11.2013
comment
@alk Было бы здорово, если бы вы могли подробнее рассказать о проблемах с заполнением в ответе, если это возможно.   -  person this    schedule 26.11.2013
comment
Заполнение не является специфическим для big или little endian, поэтому вам лучше задать другой вопрос по этому поводу.   -  person alk    schedule 26.11.2013
comment
@alk Можете намекнуть, что это за проблема с заполнением, чтобы я мог задать понятный вопрос?   -  person this    schedule 26.11.2013
comment
@alk Я честно думаю, что в моем примере кода выше нет проблемы с заполнением, и что вы ошибаетесь.   -  person this    schedule 26.11.2013
comment
Пожалуйста, извините за непонятность. В текущем примере кода этого вопроса нет проблемы с заполнением. расширение вашего примера на структуры может вызвать проблемы с заполнением, однако должно было сказать, что аналогичный пример, имеющий дело с структурами , может ввести проблемы с заполнением.   -  person alk    schedule 26.11.2013
comment
@alk Спасибо, не могли бы вы намекнуть на проблему с заполнением, или проблема, о которой вы говорите, не может быть определена?   -  person this    schedule 26.11.2013
comment
Прочтите статью о структурах заполнения для выравнивания ее членов по определенным машинно-зависимым границам, и вы поймете, о чем я говорю. Первое обращение к gxxgle по фразе выше: en.wikipedia.org/wiki/Data_structure_alignment   -  person alk    schedule 26.11.2013
comment
@alk Спасибо, что указали мне прямо на очевидный ответ.   -  person this    schedule 26.11.2013


Ответы (2)


Да, если вы сохраняете значения int, а затем повторно извлекаете те же самые значения int позже, тогда не имеет значения, как они хранятся ниже (например, big / little endian).

Например, предположим, что вы определяете

int a = 0xaabbccdd;

В системе с прямым порядком байтов это будет сохранено в памяти как 0xdd 0xcc 0xbb 0xaa. В системе с прямым порядком байтов это будет сохранено как 0xaa 0xbb 0xcc 0xdd. Однако, когда вы рассматриваете эту память как int, она всегда будет рассматриваться как 0xaabbccdd. Теперь, если вы просматриваете части исходной памяти (например, часть значения int в памяти), в игру вступает порядок байтов. Например, предположим, что вы читаете только первые два байта из той области памяти, где хранится int:

int *ptr = &a;
short firstTwoBytesInMemory = *(short*)ptr;

Значение firstTwoBytesInMemory будет 0xccdd в системе с прямым порядком байтов и 0xaabb в системе с прямым порядком байтов.

Обновление. В целях дальнейшего расширения структуры, по сути, представляют собой наборы примитивных типов (например, байты, целые числа, указатели на другие объекты и т. д.). Эти примитивные типы обычно располагаются в памяти непрерывно (за некоторыми исключениями для выравнивания и т. Д.). Таким образом, те же правила, которые применяются к приведенному выше примеру int / short, применяются к коллекциям примитивных типов (например, структур).

Если вы начнете получать доступ к частям переменных, то порядок байтов в архитектуре будет иметь значение, но если вы всегда имеете дело с вещами в их правильных типах (например, int, double и т. Д.) В целом, то то, как вещи хранятся ниже, должно быть прозрачный.

person mattnedrich    schedule 26.11.2013
comment
@Klas Он преобразует байты в памяти в целые (на тех же границах int, что и исходные данные) - person mattnedrich; 26.11.2013
comment
Он не просматривается сначала с помощью MSB, он просматривается с помощью MSB наиболее существенно! Внутри int нет ни первого, ни последнего байтов, это просто int - его можно хранить абсолютно любым способом, который выберет архитектура (например, чередование цифр каким-то безумным образом). - person Nicholas Wilson; 26.11.2013
comment
Это правда, что я пытался сказать (возможно, не очень ясно), что если вы храните целые числа, а затем читаете их позже как целые числа на тех же границах int, на которых вы их создали, вы всегда будете получать те же значения. Однако, если вы начнете читать части исходных данных, то, что вы получите, будет зависеть от того, как архитектура хранит свою память. - person mattnedrich; 26.11.2013
comment
Если целые числа хранятся на диске или отправляются по сети на машину с обратным порядком байтов, вам нужно будет учитывать коммутатор. - person Charlie; 25.03.2014

Ваше предположение верно. в данной архитектуре проблема с порядком байтов не возникнет, если вы явно не используете функции преобразования с порядком байтов для изменения значения. Проблема endianess возникает при обмене информацией между LE и архитектурой BE (обычно ПК и портативное устройство). в вашем случае вы конвертируете int * в (unsigned char *) и конвертируете (unsigned char *) обратно в (int *), что не влияет на фактические данные (содержимое массива int) при разыменовании указателя. преобразование выполняется по указателю, а не по самому int.

person wacky6    schedule 26.11.2013