Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.90/40: Рейтинг темы: голосов - 40, средняя оценка - 4.90
-41 / 49 / 5
Регистрация: 10.01.2017
Сообщений: 1,915

Порядок байт

24.02.2020, 18:17. Показов 11010. Ответов 88
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте,

Подскажите пожалуйста, вот есть:
C++
1
int m_int = 1073741824;  //в двоичном представлении: 01000000 00000000 00000000 00000000
Если к этому числу применить маску:
C++
1
2147483648 //  в двоичном представлении: 10000000 00000000 00000000 00000000
Если применить логическое сложение:
C++
1
2
3
4
5
6
7
cout << (m_int & 2147483648) << endl;
 
01000000 00000000 00000000 00000000
10000000 00000000 00000000 00000000
 
То естественно получим 0:
10000000 00000000 00000000 00000000
Если сделать сдвиг бита вЛево:
C++
1
2
3
4
5
6
7
8
cout << ((m_int<<1) & 2147483648) << endl;
 
    0<<1000000 00000000 00000000 000000000
           10000000 00000000 00000000 00000000
 
То получим: 2147483648
 
           10000000 00000000 00000000 00000000
То есть байта int`а слева направо.

Но, если сделать так:
C++
1
char * m_ptr_char = (char*)m_int;
И вывести 4 элемента int в качестве значения char:

C++
1
2
3
4
cout<<(int)m_ptr_char[0]<<endl;
cout<<(int)m_ptr_char[1]<<endl;
cout<<(int)m_ptr_char[2]<<endl;
cout<<(int)m_ptr_char[3]<<endl;
Выведется:
C++
1
2
3
4
0
0
0
64
То есть первый элемент будет 0 и только 4ый будет 64: b01000000

То есть компьютер просматривает байты в int справо налево, противоположно привычно-человеческому слева направо ? :
C++
1
00000000 00000000 00000000 01000000
Это связано вот с этими странными понятиями bigendian, littleendian ?

Если да, то подскажите пожалуйста:

1)Но если сделать сдвиг бита << влево, то бит сдвигается влево. То есть bigendian, littleendian - влияет только на байты, а не биты внутри байта ?

2) bigendian, littleendian - зависит от ОС или от процессора ? И есть функция, как определить какая из этих штук действует условно на моем компе ?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
24.02.2020, 18:17
Ответы с готовыми решениями:

Порядок следования байт
Привет. Есть флаги: None = 0x000, DateTimeFormat = 0x001, ... Diagnoses = 0x010, ......

Порядок байт в union
#include &lt;iostream&gt; using namespace std; void disp_binary(unsigned u); union swap_bytes { short int num; char ch; ...

Порядок байт у числовой переменной
Здравствуйте. Можно ли как то указать у числовой переменной чтоб байты у нее должны быть little endian

88
248 / 70 / 9
Регистрация: 22.07.2018
Сообщений: 321
26.02.2020, 22:30
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от liv Посмотреть сообщение
Ага, а если значение икса будет, например, 0x0201. Что тогда даст чтение *((char*)&x)?
UB.
Пока значение x влазит в диапазон представимых значений для char, чтение через x lvalue и через *((char*)&x) lvalue даёт одно и то же значение.
Если значение не влазит в диапазон то при чтении *((char*)&x) будет UB.

Так стандарт написан.
0
 Аватар для COKPOWEHEU
4138 / 2716 / 433
Регистрация: 09.09.2017
Сообщений: 12,050
27.02.2020, 10:55
Цитата Сообщение от Azazel-San Посмотреть сообщение
Стандарт предполагает, что такое может быть.
Где?! Вот как хотите, а я не верю, что стандарт языка предусматривает возможность обратиться к несуществующей памяти вроде отрицательной ячейки.
Цитата Сообщение от liv Посмотреть сообщение
И что делать с union, в которых совмещаются int и 4 байта? Тоже вне закона?
Да, ведь поведение на разных системах будет различаться. Не считая того, что int далеко не всегда 4 байта.
Цитата Сообщение от argcargv Посмотреть сообщение
Про чтение значения через *(char*)&x, когда значение не в диапазоне char, явно сказано что UB.
Так ведь именно поэтому вариант liv и может работать. Если бы не UB, всегда возвращалось бы одно и то же число, 0 или 1 независимо от архитектуры, ОС и прочего.
Цитата Сообщение от liv Посмотреть сообщение
Если каст инта на чар есть UB, то почему юнион разрешен?
Хотя с юнион в целом понятно. Вопрос снимаю
Эй! А как же остальным рассказать?
Скажем, что union позволяет хранить в одной и той же памяти разные типы данных, но не требует их одновременного использования. Например, в SDL (SDL_events.h) такое используется для вообще любых событий: выставляется флажок события, а остальные байты приводятся к той или иной структуре.
Кликните здесь для просмотра всего текста
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
typedef struct SDL_UserEvent
{
    Uint32 type;        /**< ::SDL_USEREVENT through ::SDL_LASTEVENT-1 */
    Uint32 timestamp;   /**< In milliseconds, populated using SDL_GetTicks() */
    Uint32 windowID;    /**< The associated window if any */
    Sint32 code;        /**< User defined event code */
    void *data1;        /**< User defined data pointer */
    void *data2;        /**< User defined data pointer */
} SDL_UserEvent;
typedef struct SDL_SysWMEvent
{
    Uint32 type;        /**< ::SDL_SYSWMEVENT */
    Uint32 timestamp;   /**< In milliseconds, populated using SDL_GetTicks() */
    SDL_SysWMmsg *msg;  /**< driver dependent data, defined in SDL_syswm.h */
} SDL_SysWMEvent;
typedef union SDL_Event
{
    Uint32 type;                    /**< Event type, shared with all events */
    SDL_CommonEvent common;         /**< Common event data */
    SDL_DisplayEvent display;       /**< Window event data */
    SDL_WindowEvent window;         /**< Window event data */
    SDL_KeyboardEvent key;          /**< Keyboard event data */
    SDL_TextEditingEvent edit;      /**< Text editing event data */
    SDL_TextInputEvent text;        /**< Text input event data */
    SDL_MouseMotionEvent motion;    /**< Mouse motion event data */
    SDL_MouseButtonEvent button;    /**< Mouse button event data */
    SDL_MouseWheelEvent wheel;      /**< Mouse wheel event data */
    SDL_JoyAxisEvent jaxis;         /**< Joystick axis event data */
    SDL_JoyBallEvent jball;         /**< Joystick ball event data */
    SDL_JoyHatEvent jhat;           /**< Joystick hat event data */
    SDL_JoyButtonEvent jbutton;     /**< Joystick button event data */
    SDL_JoyDeviceEvent jdevice;     /**< Joystick device change event data */
    SDL_ControllerAxisEvent caxis;      /**< Game Controller axis event data */
    SDL_ControllerButtonEvent cbutton;  /**< Game Controller button event data */
    SDL_ControllerDeviceEvent cdevice;  /**< Game Controller device event data */
    SDL_AudioDeviceEvent adevice;   /**< Audio device event data */
    SDL_SensorEvent sensor;         /**< Sensor event data */
    SDL_QuitEvent quit;             /**< Quit request event data */
    SDL_UserEvent user;             /**< Custom event data */
    SDL_SysWMEvent syswm;           /**< System dependent window event data */
    SDL_TouchFingerEvent tfinger;   /**< Touch finger event data */
    SDL_MultiGestureEvent mgesture; /**< Gesture event data */
    SDL_DollarGestureEvent dgesture; /**< Gesture event data */
    SDL_DropEvent drop;             /**< Drag and drop event data */
    Uint8 padding[56];
} SDL_Event;

Цитата Сообщение от liv Посмотреть сообщение
Azazel-San, да знаю я, что такое UB (undefined behavior, неопределенное поведение), знаю.
Чуть выше об этом писал: у вас алгоритм на этом построен.
UB тут только в том, что неизвестно какой байт попадет в начало переменной. Они могут идти как 1234, могут как 4321, могут как 3412, да хоть 00001234.
Цитата Сообщение от argcargv Посмотреть сообщение
Пока значение x влазит в диапазон представимых значений для char, чтение через x lvalue и через *((char*)&x) lvalue даёт одно и то же значение.
Если значение не влазит в диапазон то при чтении *((char*)&x) будет UB.
Ничего подобного. Число 0x00000001 через приведение к *(char*) вполне может быть нулем, если старший байт имеет меньший адрес.
0
Эксперт CЭксперт С++
 Аватар для liv
5120 / 4574 / 855
Регистрация: 07.10.2015
Сообщений: 9,462
27.02.2020, 12:41
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Если бы не UB, всегда возвращалось бы одно и то же число, 0 или 1 независимо от архитектуры, ОС и прочего.
Кстати, да
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Да, ведь поведение на разных системах будет различаться. Не считая того, что int далеко не всегда 4 байта.
А поведение и сейчас отличается. У каждой системы свой набор инструментов. И всегда будет отличаться друг от друга. Чего-то меня гложат сомнения, что будут писаться программы, которые будут сходу работать как на x86, так и на той же Motorola.
А вот совать палки в колеса разработкам на одной и той же постоянной системе с кастами, как-то нехорошо.
Размер в 4 байта был взят условно. В некоторых union, всегда 4 байта, например IN_ADDR
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Эй! А как же остальным рассказать?
Так понимаю, применение union для доступа к составляющим частям более крупного объекта не должно приводить к проблемам, т.к. будет явное обращение к нужному месту. И не важно в каком они порядке! А вот после каста (см чуть далее)...
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
UB тут только в том, что неизвестно какой байт попадет в начало переменной. Они могут идти как 1234, могут как 4321, могут как 3412, да хоть 00001234
Да-да, на этом и построет алгоритм.
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Число 0x00000001 через приведение к *(char*) вполне может быть нулем, если старший байт имеет меньший адрес
Уважаемые оппоненты утверждают, что все равно будет читаться единица. Т.к. объект остается int-ом! UB нет, т.к. int помещается в char. Прочитанный int усекается до байта и получаем на выходе байт 0x01. Вот такие пироги!

Добавлено через 4 минуты
Еще раз процитирую:
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Если бы не UB, всегда возвращалось бы одно и то же число, 0 или 1 независимо от архитектуры, ОС и прочего
Именно об этом оппоненты и говорят

Добавлено через 3 минуты
Отсюда вывод, граждане: в данном контексте UB необходим, т.к. позволяет определить систему!
0
 Аватар для COKPOWEHEU
4138 / 2716 / 433
Регистрация: 09.09.2017
Сообщений: 12,050
27.02.2020, 13:06
Цитата Сообщение от liv Посмотреть сообщение
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Число 0x00000001 через приведение к *(char*) вполне может быть нулем, если старший байт имеет меньший адрес.
Уважаемые оппоненты утверждают, что все равно будет читаться единица. Т.к. объект остается int-ом! UB нет, т.к. int помещается в char. Прочитанный int усекается до байта и получаем на выходе байт 0x01. Вот такие пироги!
При преобразовании int->char идет работа со значениями, тут результат однозначный (забудем пока про знаковость и прочие не относящиеся к нашей теме вещи)
При преобразовании int*->char* идет работа с указателями, а сами значения остаются неизменными. И значение по указателю уже будет зависеть от способа хранения.
Цитата Сообщение от liv Посмотреть сообщение
Уважаемые оппоненты утверждают, что все равно будет читаться единица.
Но ведь не читается. Точнее, не всегда читается. Это что, они таким способом нашли баг в компиляторе, что он делает что-то, противоречащее стандарту?
Цитата Сообщение от liv Посмотреть сообщение
Так понимаю, применение union для доступа к составляющим частям более крупного объекта не должно приводить к проблемам, т.к. будет явное обращение к нужному месту. И не важно в каком они порядке! А вот после каста (см чуть далее)...
Это не понял.
Мой-то пример был проще: если у нас есть объединение int и char[4], то если мы пишем в int, а читаем из char[], получаем UB. А если пишем в int, читаем из int, либо пишем в char[], читаем из char[] - вполне себе определенное поведение.
Именно это и используется в SDL: одна и та же переменная может трактоваться как один из нескольких типов данных на выбор. При этом если перепутать тип при чтении - закономерно получишь мусор.
0
248 / 70 / 9
Регистрация: 22.07.2018
Сообщений: 321
27.02.2020, 18:02
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Ничего подобного. Число 0x00000001 через приведение к *(char*) вполне может быть нулем, если старший байт имеет меньший адрес.
Пруфов, конечно, не будет.
Цитата Сообщение от liv Посмотреть сообщение
Уважаемые оппоненты утверждают, что все равно будет читаться единица.
Стандарт. Стандарт утверждает.
0
0 / 1 / 0
Регистрация: 10.07.2017
Сообщений: 8
27.02.2020, 18:17
Цитата Сообщение от argcargv Посмотреть сообщение
UB.
Пока значение x влазит в диапазон представимых значений для char, чтение через x lvalue и через *((char*)&x) lvalue даёт одно и то же значение.
Если значение не влазит в диапазон то при чтении *((char*)&x) будет UB.
Так стандарт написан.
А можна конкретную ссылочку на вординг?
Спасибо.
0
Эксперт CЭксперт С++
 Аватар для liv
5120 / 4574 / 855
Регистрация: 07.10.2015
Сообщений: 9,462
27.02.2020, 18:27
Kovacz, мне уже здесь отвечали на этот вопрос. Вот, посмотрите теперь Вы
0
0 / 1 / 0
Регистрация: 10.07.2017
Сообщений: 8
27.02.2020, 18:41
liv, меня интересовала ссылочка где описывается именно об не попадании в диапазон char. Как я понимаю, эта ситуация исходя из слов argcargv явно описана в стандарте и приводит к UB, я вот пока этого не нашел, хотел бы конкретную ссылочку.
0
Эксперт CЭксперт С++
 Аватар для liv
5120 / 4574 / 855
Регистрация: 07.10.2015
Сообщений: 9,462
27.02.2020, 18:45
Я также внимательно слежу за этим вопросом...
0
248 / 70 / 9
Регистрация: 22.07.2018
Сообщений: 321
27.02.2020, 20:15
Kovacz, liv, вы меня поражаете. Что в следующем коде UB это новость?
C++
1
2
int i = INT_MAX;
i + 1;
0
 Аватар для avgoor
1550 / 877 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
27.02.2020, 20:51
Цитата Сообщение от argcargv Посмотреть сообщение
Пруфов, конечно, не будет.
Вот. Даже с названиями платформ.
1
Эксперт CЭксперт С++
 Аватар для liv
5120 / 4574 / 855
Регистрация: 07.10.2015
Сообщений: 9,462
27.02.2020, 21:33
argcargv, это не новость, причем результат известен всегда
Но это из другой оперы

Добавлено через 2 минуты
avgoor, именно UB используется для определения платформы.
Т.к. в каждой платформе своя организация
0
 Аватар для avgoor
1550 / 877 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
27.02.2020, 21:36
Цитата Сообщение от liv Посмотреть сообщение
именно UB используется для определения платформы.
Не путайте UB с "определяется реализацией"
0
Эксперт CЭксперт С++
 Аватар для liv
5120 / 4574 / 855
Регистрация: 07.10.2015
Сообщений: 9,462
27.02.2020, 21:42
avgoor, вот это "определяется реализацией" давайте адресуем нашим оппонентам
0
248 / 70 / 9
Регистрация: 22.07.2018
Сообщений: 321
27.02.2020, 23:00
Цитата Сообщение от avgoor Посмотреть сообщение
Вот.
> ru
> wikipedia
> пруф
Это даже не смешно. Можно ещё "пруф" с луркомора или абсурдопедии?
0
 Аватар для avgoor
1550 / 877 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
27.02.2020, 23:02
Цитата Сообщение от argcargv Посмотреть сообщение
Это даже не смешно.
Т.е. тот факт, что на SPARC-е будет 0 вас не смутил?
0
248 / 70 / 9
Регистрация: 22.07.2018
Сообщений: 321
27.02.2020, 23:30
Цитата Сообщение от avgoor Посмотреть сообщение
Т.е. тот факт, что на SPARC-е будет 0 вас не смутил?
А тот факт что мы тут обсуждаем что стандарт требует вас не смутил?
0
 Аватар для avgoor
1550 / 877 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
28.02.2020, 00:19
Цитата Сообщение от argcargv Посмотреть сообщение
А тот факт что мы тут обсуждаем что стандарт требует вас не смутил?
Меня - нет. Просто его читать надо уметь.

Ну, ладно. А в этом коде UB есть?
C++
1
2
3
4
    char* c = (char*)malloc(4);
    int32_t* i = new(c) int32_t(1);
    std::cout << (c[0] == 0 ? "big" : "little");
    free(c);
0
 Аватар для COKPOWEHEU
4138 / 2716 / 433
Регистрация: 09.09.2017
Сообщений: 12,050
28.02.2020, 11:26
Цитата Сообщение от argcargv Посмотреть сообщение
Пруфов, конечно, не будет.
А какие еще нужны пруфы кроме использования этого факта людьми?
Цитата Сообщение от argcargv Посмотреть сообщение
Стандарт. Стандарт утверждает.
Может, стоило его почитать, прежде чем нести чушь?
Цитата из стандарта:
When a pointer to an object is converted to a pointer to a character type, the result points to the lowest addressed byte of the object
"При преобразовании указателя к char*, результат указывает на младший (по адресу) байт объекта". Следовательно, если архитектура little-endian (младший байт имеет меньший адрес), адресован будет младший, если big-endian (старший байт раньше) - то старший.
Как вообще по-другому можно понять различие big-endian и little-endian?
0
0 / 1 / 0
Регистрация: 10.07.2017
Сообщений: 8
28.02.2020, 11:43
Цитата Сообщение от argcargv Посмотреть сообщение
Что в следующем коде UB это новость?
То все дело в обычном переполнении? Соответственно если там будет unsigned char - UB не будет?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
28.02.2020, 11:43

Порядок байт в слове и бит в байте
читал эту требуются пояснения. A B C D - адреса в них число 128 BE A B C D ...

Определить порядок хранения байт 16-ричного числа
Всем привет! Имеется следующий вопрос: написать программу, которая показывает порядок хранения байт 16-ричного числа. Как это сделать?

Порядок байт. Массив чаров приводится к типу unsigned int.
Есть массив из 4 char. Массив приводится к типу unsigned int и затем данные извлекаются в переменную типа unsigned int. Нужно, чтобы байты...

Порядок байт в big-endian и little-endian
Всем привет! Народ подскажите мне пожалуйста простые прописные истины, а то я что то запутался! Предположим что у нас в байте 8 - бит и...

Закодировать файл. Взять 7 байт. Первый бит каждого байта переместить в 8 байт
Нужно открыть бинарный файл и закодировать следующим образом. Взять 7 байт. Первый бит каждого байта переместить в 8 байт. То есть,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
80
Ответ Создать тему
Новые блоги и статьи
Запрет пометки на удаление и отмены проведения
Maks 16.07.2026
Алгоритм из решения ниже реализован на нетиповом документе "ПутевойЛист" разработанного в КА2. Задача: запретить помечать на удаление и отменять проведения путевого листа при условии, если он сдан. . .
Как надо было делать правильно - вообще не слушать ИИ, его дело - текст.
Hrethgir 15.07.2026
А вообще надо было делать не так, чтобы не исправлять ошибку https:/ / www. cyberforum. ru/ blogs/ 223907/ 10996. html , правильно было : удалил кнопку, а потом добавил её. Всё это стресс конечно. Почему?. . .
Знаете, от чего появляется стресс?
kumehtar 15.07.2026
Стресс появляется оттого, что вы, зная как поступить правильно, делаете наоборот. Ларри Уингет
Нас бьют, а мы крепчаем? Какая чушь!
kumehtar 15.07.2026
Вот это вот бытующее мнение, что человек меняется только под действием проблем, всегда считал вредоносным. Поверь, от проблем у людей появляются не изменения, а нервное расстройство и ПТСР. А. . .
сукцессия 29. Переход от одних деревьев на другие делать более или менее вероятностным?
anaschu 12.07.2026
Насколько смена типов микоризы — исключительное событие в двухвековой сукцессии? Оценка вероятности в пространстве параметров В текущей версии модели успешно реализован ключевой механизм. . .
сукцессия 27. Думаю, как переделывать уже написанную статью с планами на сукцессию.
anaschu 12.07.2026
Анализ соответствия модели требованиям Реализованные компоненты: Механизм закисления почвы через протонную помпу Конкуренция между типами микориз pH как триггер сукцессии C/ P соотношение. . .
Сукцессия 26. Мат модель создана.
anaschu 12.07.2026
Модель смены растительных сукцессий посредством управления грибами работает внутри небольшой ячейки почвы, восстанавливающейся после пожара, где ненадолго бывшее царство хвойных снова захватили. . .
Решил проблему с ошибкой пагинации сообщений с сервера на алгоритме обхода дерева "Эстафета хвоста".
Hrethgir 12.07.2026
Проблема была в том, что удалялась именно новая кнопка, а не старая. Ни один ИИ не обнаружил это, а сам я смог только когда с работой стало попроще и когда заставил работать будущее автономное. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru