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

Порядок байт

24.02.2020, 18:17. Показов 11025. Ответов 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
26.02.2020, 18:01
Студворк — интернет-сервис помощи студентам

Не по теме:

Цитата Сообщение от liv Посмотреть сообщение
Конкретно, для int-а, как будет себя вести?
Откуда я то знаю, стандарт об это ничего не говорит. (Если что, это был почти сарказм, если бы не было так грустно...)

0
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
26.02.2020, 18:01
Цитата Сообщение от liv Посмотреть сообщение
Но после приведения к (char*) адрес int-а становится char[4]
Та вы шо? Приводили к указателю, а получился массив?
0
Эксперт CЭксперт С++
 Аватар для liv
5120 / 4574 / 855
Регистрация: 07.10.2015
Сообщений: 9,462
26.02.2020, 18:05
Цитата Сообщение от Azazel-San Посмотреть сообщение
Изменилось ли то, что указатель указывает на первый байт объекта (не массива)? Возможно.
Ну почему возможно-то? Рассматриваем только объект int, только его. Куда будет указывать указатель после того, как мы приведем его к char*?
Цитата Сообщение от Azazel-San Посмотреть сообщение
Не гарантируется != не будет работать.
Кому нужна такая работа, когда нет гарантий?
0
248 / 70 / 9
Регистрация: 22.07.2018
Сообщений: 321
26.02.2020, 18:07
Цитата Сообщение от liv Посмотреть сообщение
Обратите внимание, по [conv.ptr]/2 проводится каст к void*. Все! Никакого x и int* уже нет! После каста к char* по [expr.static.cast]/13 появился указатель на объект типа char. При этом не поменялось значение указателя, значение, а не тип!
Ещё раз перечитайте Порядок байт про разницу между типом и значением выражения. Выражение может иметь тип void* или char* или float* или std::string*, но при этом значение "указатель на объект x (с типом int)"
0
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
26.02.2020, 18:07
Цитата Сообщение от liv Посмотреть сообщение
Куда будет указывать указатель после того, как мы приведем его к char*?
На объект int, уже раз 100 было сказанно.
0
Эксперт CЭксперт С++
 Аватар для liv
5120 / 4574 / 855
Регистрация: 07.10.2015
Сообщений: 9,462
26.02.2020, 18:18
Цитата Сообщение от Azazel-San Посмотреть сообщение
Приводили к указателю, а получился массив
А что смущает? Привели к указателю на char. Который фактически указывает на 4 байта бывшего int-а

Добавлено через 9 минут
argcargv, читал и перечитывал не раз.
Вот это
Тип *((char*)&x) — char, а результат — "объект x"
я не понимаю и не принимаю.
Хотите сказать, что чтение по адресу *((char*)&x) даст тот же x?
0
248 / 70 / 9
Регистрация: 22.07.2018
Сообщений: 321
26.02.2020, 18:29
Цитата Сообщение от liv Посмотреть сообщение
Вот это
Тип *((char*)&x) — char, а результат — "объект x"
я не понимаю
См. [expr.unary.op]/1
Цитата Сообщение от liv Посмотреть сообщение
Хотите сказать, что чтение по адресу *((char*)&x) даст тот же x?
Зависит от значения x. Если значение x влазит в диапазон для char, lvalue-to-rvalue conversion, применённое к этим двум lvalue, должно дать одно и то же значение — значение x.
0
Эксперт CЭксперт С++
 Аватар для liv
5120 / 4574 / 855
Регистрация: 07.10.2015
Сообщений: 9,462
26.02.2020, 18:31
После (char*)&x уже нет int*, появился char*. Хотя адрес продолжает указывать на место, где был int.
В этом смысле указатель по-прежнему указывает на объект int. С такой формулировкой я согласен
0
 Аватар для COKPOWEHEU
4139 / 2717 / 433
Регистрация: 09.09.2017
Сообщений: 12,050
26.02.2020, 18:31
Цитата Сообщение от Azazel-San Посмотреть сообщение
То как работает memcpy стандарт тоже не определяет
Допустим, вы malloc'ом выделили кусок памяти и начали складывать туда int'ы начиная с нулевого адреса. Они как, за левую границу должны уйти? Или оставить в начале пустое место?
Эзотерику какую-то разводите "как оно могло бы быть". Но чтобы это реализовать и не поломать того что есть, пришлось бы приложить изрядные усилия. А зачем?
1
Эксперт CЭксперт С++
 Аватар для liv
5120 / 4574 / 855
Регистрация: 07.10.2015
Сообщений: 9,462
26.02.2020, 18:34
Цитата Сообщение от argcargv Посмотреть сообщение
Если значение x влазит в диапазон для char
Ага, а если значение икса будет, например, 0x0201. Что тогда даст чтение *((char*)&x)?
Или, может, так уже вообще нельзя делать, ибо, оказывается, нет никаких гарантий?

Добавлено через 1 минуту
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Но чтобы это реализовать и не поломать того что есть, пришлось бы приложить изрядные усилия. А зачем?
И я о том же... Столько написано, немерянно...
0
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
26.02.2020, 19:01
Цитата Сообщение от liv Посмотреть сообщение
Что тогда даст чтение *((char*)&x)?
UB.
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Они как, за левую границу должны уйти?
Стандарт предполагает, что такое может быть.
Я лишь говорю то, что стандарт описывает или не описывает. Этот случай подпадает под второе.
0
Эксперт CЭксперт С++
 Аватар для liv
5120 / 4574 / 855
Регистрация: 07.10.2015
Сообщений: 9,462
26.02.2020, 19:22
Цитата Сообщение от Azazel-San Посмотреть сообщение
UB.
Я понимаю, что вы хотите сказать, но не принимаю.
Хорошо, что делать, когда НАДО прочитать первый или второй байт int-а? Прямо из памяти, а не сдвигами, and-ами и т.п.
И что делать с union, в которых совмещаются int и 4 байта? Тоже вне закона?

Добавлено через 1 минуту
Таких вопросов найдется вагон и маленькая тележка
0
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
26.02.2020, 19:31
Цитата Сообщение от liv Посмотреть сообщение
но не принимаю
Это уже дело каждого
Цитата Сообщение от liv Посмотреть сообщение
Хорошо, что делать, когда НАДО прочитать первый или второй байт int-а?
Та делать так же, как вы и делали. То о чем говорил я, это лишь выводы сделанные при просмотре стандарта. Заметьте я не говорил, что это *(char*)&x не будет работать, или что это UB. Так как я не уверен в этом, явного вординга об этом в стандарте нету, по крайней мере пока что. Возможно потенциально это и UB, но когда это кого останавливало?
Type punnig тоже UB.
Цитата Сообщение от liv Посмотреть сообщение
когда НАДО прочитать первый или второй байт int-а?
Можно еще попробовать через union:
C++
1
2
3
4
5
6
union {
    int32_t as_value;
    int8_t  as_array[sizeof(as_value)];
} unpack{1};
unpack.as_array[0];
unpack.as_array[3];
Цитата Сообщение от liv Посмотреть сообщение
И что делать с union, в которых совмещаются int и 4 байта? Тоже вне закона?
Сам по себе юнион? Нет, почему же?
0
248 / 70 / 9
Регистрация: 22.07.2018
Сообщений: 321
26.02.2020, 19:38
Цитата Сообщение от Azazel-San Посмотреть сообщение
Заметьте я не говорил, что это *(char*)&x не будет работать, или что это UB. Так как я не уверен в этом, явного вординга об этом в стандарте нету, по крайней мере пока что.
Про чтение значения через *(char*)&x, когда значение не в диапазоне char, явно сказано что UB.
0
Эксперт CЭксперт С++
 Аватар для liv
5120 / 4574 / 855
Регистрация: 07.10.2015
Сообщений: 9,462
26.02.2020, 19:42
Azazel-San, так юнион по сути есть адресация байтов int-а.
Если каст инта на чар есть UB, то почему юнион разрешен?

Добавлено через 1 минуту
Хотя с юнион в целом понятно. Вопрос снимаю

Добавлено через 1 минуту
А вот с приведением к char* и получением UB не могу согласиться
0
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
26.02.2020, 20:18
argcargv, так у нас вроде в диапазоне было? Или что вы имели ввиду под диапазоном?
liv, дело ваше. А вы понимаете, что такое UB?
0
Параллельный Кот
 Аватар для valen10
1905 / 827 / 350
Регистрация: 25.03.2016
Сообщений: 2,045
26.02.2020, 20:33
Цитата Сообщение от liv Посмотреть сообщение
А вот с приведением к char* и получением UB не могу согласиться
В [basic.types]/4 говорится, что объект типа T представлен последовательностью из N unsigned char, N=sizeof(T). Получается, что стандарт явно признает тот факт, что любой объект можно рассматривать как последовательность байтов.

О том, что указатель указывает на первый байт объекта, в стандарте не нашел, но есть пара цитат из `Programming Principles and Practice Using C++` Страуструпа.
`17.3 Memory, addresses, and pointers`

`17.4.1 Free-store allocation`


И наконец о преобразовании указателей (цитаты из `17.8 Messing with types: void* and casts` той же книги):
1. A pointer to any object type can be assigned to a void*.
2. A static_cast can be used to explicitly convert between related pointer types.
Исходя из этих двух правил, получается так:
C++
1
2
3
4
5
6
7
8
9
10
11
int x = 1;
void *pv = &x;                      // Ok.
char *pc = static_cast<char*>(pv);  // Ok.
 
// И далее *pc является первыйм байтом объекта x.
if (*pc == 1) {
    //...
}
else {
    //...
}
А *(char*)&x делает то же самое, но запись короче. Где же тут UB?
0
248 / 70 / 9
Регистрация: 22.07.2018
Сообщений: 321
26.02.2020, 20:50
Цитата Сообщение от Azazel-San Посмотреть сообщение
так у нас вроде в диапазоне было?
Это было ответом в том числе на
Цитата Сообщение от liv Посмотреть сообщение
Ага, а если значение икса будет, например, 0x0201. Что тогда даст чтение *((char*)&x)?
1
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
26.02.2020, 20:52
Цитата Сообщение от argcargv Посмотреть сообщение
Это было ответом в том числе на
А я говорил, о этом примере.
0
Эксперт CЭксперт С++
 Аватар для liv
5120 / 4574 / 855
Регистрация: 07.10.2015
Сообщений: 9,462
26.02.2020, 21:46
Azazel-San, да знаю я, что такое UB (undefined behavior, неопределенное поведение), знаю. Это практически означает, что нет гарантий того или иного поведения. Мне не нравится создание ситуаций, приводящих к UB, причем, на пустом месте.

Добавлено через 2 минуты
Почитаю потом ещё раз предложенный стандарт, с лупой
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
26.02.2020, 21:46

Порядок байт в слове и бит в байте
читал эту требуются пояснения. 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 байт. То есть,...


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

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Новые блоги и статьи
Установка нескольких штампов электронной подписи в строго определенных местах файла docx
ВладимирСамохин 19.07.2026
(В!) Работа с Электронной подписью - это неотъемлемая часть современного документооборота. Но что делать, если нужно поставить несколько штампов электронной подписи в строго определенных местах. . .
сукцессия 35. Научная статья о проделанной работе
anaschu 19.07.2026
Написал в формате латекс и пдф
Вангую, что это не пройдёт модерацию, и на неделе я запущу свой сервер.
Hrethgir 19.07.2026
Эта публикация сейчас в песочнице и ждёт приглашения. https:/ / habr. com/ ru/ sandbox/ 295048/ начало и оглавление - Как «пернатого» заставить осваивать новые горизонты опыта через масштабирование. . .
сукцессия 33. открытые вопросы от клауде
anaschu 19.07.2026
"Что накопилось за эту часть А — тринадцать правок, из которых шесть пришли из ваших вопросов и каждая оказалась реальной ошибкой, а не калибровкой: односторонний симбиоз, отсутствующий листопад,. . .
32 сукцессия
anaschu 19.07.2026
сукцессия 28‑мерное ядро стабилизировано Коллеги, фиксирую разбор инженерных правок и их изоморфную проекцию на экономику, меметику и половой отбор. Модель теперь не «подкручивает» сходимость —. . .
сукцессия 31: модель микоризы - это модель ещё нескольких явлений, социальных и экономических
anaschu 18.07.2026
Теория «Всего»: апдейт v1. 1. 2 — 28‑мерное ядро стабилизировано Коллеги, фиксирую разбор инженерных правок и их изоморфную проекцию на экономику, меметику и половой отбор. Модель теперь не. . .
сукцессия 30. Массив проверяющих друг друга моделей
anaschu 18.07.2026
Архитектура сети взаимопроверяющих моделей микоризной сукцессии (v2. 0) Развитие тензорного ОДУ-ядра и создание кросс-платформенного калибровочного полигона Уважаемые коллеги! В продолжение. . .
Грибы - это женщины, деревья - это мужчины. Анти инь янь для союза мужчины и женщины.
anaschu 18.07.2026
ГЛАВНЫЙ НАУЧНО-ФИЛОСОФСКИЙ ВЫВОД: Сексуально-Репродуктивный Капитализм против Государства Моногамии Коллеги, мы вышли на финишную прямую 20-мерного ОДУ-моделирования вековой сукцессии (ветка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru