powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Получить int из char
25 сообщений из 25, страница 1 из 1
Получить int из char
    #38853963
DrumAsm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте. Пишу программу в Visual Studio 2008. Проект Win32.
Подскажите, имеется

Код: plaintext
1.
unsigned char p[] = {0x20, 0x00, 0xA3, 0x45, 0x89, 0x41 };



Как получить
Код: plaintext
1.
short int i

из значений
Код: plaintext
1.
p[1]

и
Код: plaintext
1.
p[2]

. В данном случае i должно быть равно 163. Я сделал так:

Код: plaintext
1.
i=p[2]*256+p[1];



Мне кажется, что это примитивно. Может есть другие варианты? Потому что long long int таким методом не удобно получать. Цикл наверное тоже не красиво будет смотреться. Спасибо.
...
Рейтинг: 0 / 0
Получить int из char
    #38853992
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DrumAsmМне кажется, что это примитивно
Ну замени умножение на сдвиг для "продвинутости".

Это решение, в отличии от каста, не зависит от процессора.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Получить int из char
    #38854057
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DrumAsmВ данном случае i должно быть равно 163. Я сделал так: i=p[2]*256+p[1];
Так у тебя будет 0xA300
163 будет так p[1]*256+p[2]

Если все-таки правильно считать так как ты написал, то можно так
Код: plaintext
1.
unsigned short i = *((unsigned short*)&p[1]);


Если правильно как я написал, то *256 но делать это в цикле
Код: plaintext
1.
2.
3.
4.
5.
int res = 0;
for(int i = 1; i <= 2; i++) {
   res *= 256;
   res += p[i];
}
...
Рейтинг: 0 / 0
Получить int из char
    #38854092
DrumAsm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dima T,

Точно! 0xA300. Sorry. Это я уже запарился.. А в первом случае просто переносится указатель?
...
Рейтинг: 0 / 0
Получить int из char
    #38854115
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DrumAsmDima T,

Точно! 0xA300. Sorry. Это я уже запарился.. А в первом случае просто переносится указатель?
Нет, читается значение, но читается как тип unsigned short. А т.к. unsigned short это два байта, то кроме p[1] берется p[2].
ХЗ как еще объяснить.
если пошагово расписать то вот что происходит:
Код: plaintext
1.
2.
3.
unsigned char* pp = &p[1];
unsigned short* pi = (unsigned short*) pp;
unsigned short i = *pi;
...
Рейтинг: 0 / 0
Получить int из char
    #38854136
RWolf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это решение чувствительно к архитектуре процессора — на одних архитектурах результат будет 0xA300, на других 0x00A3, на третьих результат не определён, на четвёртых программа упадёт. Лучше уж сдвигами.
...
Рейтинг: 0 / 0
Получить int из char
    #38854140
DrumAsm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dima T,

А вот всегда интересовал такой вопрос. Можно указателю unsigned short i присвоить адрес p[1], чтобы из указателя i я мог получить p[1] и p[2]?
...
Рейтинг: 0 / 0
Получить int из char
    #38854180
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DrumAsm, в том то и весь цимес брат. Можно. Это похоже на езду без ремней безопасности.
Быстро и опасно. Но можно. На сях. В отличие от этих ваших шарпов и джав.
...
Рейтинг: 0 / 0
Получить int из char
    #38854186
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DrumAsmDima T,

А вот всегда интересовал такой вопрос. Можно указателю unsigned short i присвоить адрес p[1], чтобы из указателя i я мог получить p[1] и p[2]?
брр ... ты сам понял что написал? Сделать из указателя char указатель short чтобы потом из него извлекать char. Можно, но зачем?
...
Рейтинг: 0 / 0
Получить int из char
    #38854221
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
RWolfЭто решение чувствительно к архитектуре процессора — на одних архитектурах результат будет 0xA300, на других 0x00A3, на третьих результат не определён, на четвёртых программа упадёт. Лучше уж сдвигами.
Вроде уже не осталось архитектур где будет 0x00A3 (т.н. big endian), а "результат не определён" вообще из области фантастики.

Недавно пробовал откомпилировать одну свою программулину с подобными конструкциями под ARM-процессор - запустилось, работало корректно, общалась по сетке с другой прогой под виндой. Возможно есть какая-то экзотическая электроника с big endian, но если ТС до нее доберется, то, думаю, проблема big endian будет не самой серьезной.
...
Рейтинг: 0 / 0
Получить int из char
    #38854222
DrumAsm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dima T,

извлекать не char, а short int. Он же из себя и будет представлять p[2]*256+p[1] ? Или я ошибаюсь?
...
Рейтинг: 0 / 0
Получить int из char
    #38854245
RWolf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

не определён — это ARM ниже v7. В зависимости от ядра невыровненный доступ к данным может как менять порядок чтения байт, так и прерывать выполнение. Выровненный доступ при этом будет работать нормально.
...
Рейтинг: 0 / 0
Получить int из char
    #38854247
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DrumAsmDima T,

извлекать не char, а short int. Он же из себя и будет представлять p[2]*256+p[1] ? Или я ошибаюсь?
Все верно.

Я же тебе выше подробно расписал что происходит. Если надо указатель на short то сокращенно так:
Код: plaintext
1.
unsigned short* pi = (unsigned short*)&p[1];



суть такая: ты даешь указание компилятору рассматривать последовательность байт не как массив, а как значение другого типа (размером больше байта), т.е. например в памяти лежит массив байт
Адрес значение123400x20123410x00123420xA3123430x45123440x89
Если этот кусок памяти рассматривать как массив char то для получения значения p[1] будет взято значение байта по адресу 12341, т.е. 0x00
Если посчитать что по адресу 12341 лежит значение типа short, то будут взяты два байта 0x00 и 0xA3 и т.к. принят порядок хранения от младшего к старшему, то процессор посчитает это числом 0xA300
Если захочешь прочитать как тип int (4 байта) то получится 0x8945A300. Подробнее тут
...
Рейтинг: 0 / 0
Получить int из char
    #38854325
DrumAsm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dima T,

спасибо, получилось)) А если вот так? short * i = reinterpret_cast<short*>(&p[1]); Читал, что не желательно это использовать, но всё же..
...
Рейтинг: 0 / 0
Получить int из char
    #38854338
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DrumAsmА если вот так? short * i = reinterpret_cast<short*>(&p[1]);
не знаю что такое reinterpret_cast, это из С++, я с ним слабо дружу.
...
Рейтинг: 0 / 0
Получить int из char
    #38854351
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кроме порядка байтов следует еще учитывать что не на всех платформах можно читать слова большие байта по невыравненным адресам.

Если же не учитывать выравнивание, то считывать big endian можно так:
Код: plaintext
1.
2.
short i = ntohs(*(short*)&p[1]);
long i = ntohl(*(long*)&p[1]);
...
Рейтинг: 0 / 0
Получить int из char
    #38854440
DrumAsm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем спасибо за помощь. Всё получилось. Кому тоже интересно, вот варианты:
Код: plaintext
1.
short * i = reinterpret_cast<short*>(&p[1]);


или
Код: plaintext
1.
unsigned short* i = (unsigned short*)&p[1];
...
Рейтинг: 0 / 0
Получить int из char
    #38854545
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DrumAsm, а тебе интересно узнать в чем разница между этими вариантами?
...
Рейтинг: 0 / 0
Получить int из char
    #38855159
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DrumAsm
Как получить
Код: plaintext
1.
short int i

из значений
Код: plaintext
1.
p[1]

и
Код: plaintext
1.
p[2]

. В данном случае i должно быть равно 163. Я сделал так:

Код: plaintext
1.
i=p[2]*256+p[1];



Мне кажется, что это примитивно.



На самом деле это -- лучший вариант. Тут нет неопределённого поведения и всё явным образом определено.
Можно заменить ещё умножения на сдвиги и сложения на побитовое ИЛИ -- это просто более простые операции.
Но в принципе это одно и то же.
...
Рейтинг: 0 / 0
Получить int из char
    #38855360
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Арифметически-чистый.
...
Рейтинг: 0 / 0
Получить int из char
    #38855694
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте.

Anatoly MoskovskyКроме порядка байтов следует еще учитывать что не на всех платформах можно читать слова большие байта по невыравненным адресам.

Если же не учитывать выравнивание, то считывать big endian можно так:
Код: plaintext
1.
2.
short i = ntohs(*(short*)&p[1]);
long i = ntohl(*(long*)&p[1]);



Если мы работаем только с artithmetic types, то в каком случаем данная конструкция будет работать некорректно ?
Код: plaintext
1.
T2=*(T2*)&object;



Если &object адрес элемента массива A и &object+sizeof(T) адрес элемента массива A. Объекты массива А имеют тип T1
...
Рейтинг: 0 / 0
Получить int из char
    #38855695
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
почему вообще сложилось так, что little-endian и big-endian имеют место быть вместе ? Неужели когда проектировался фундамент, не было конференций и встреч разработчиков ведущих IT компаний, и они не могли согласовать стандарт, которого все должны были придерживаться ?
прошу прощение за офтоп.
...
Рейтинг: 0 / 0
Получить int из char
    #38855713
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryЕсли мы работаем только с artithmetic types, то в каком случаем данная конструкция будет работать некорректно ?
Код: plaintext
1.
T2=*(T2*)&object;


Я же написал:
Anatoly MoskovskyЕсли же не учитывать выравнивание

SashaMercuryпочему вообще сложилось так, что little-endian и big-endian имеют место быть вместе ? Неужели когда проектировался фундамент, не было конференций и встреч разработчиков ведущих IT компаний, и они не могли согласовать стандарт, которого все должны были придерживаться ?
прошу прощение за офтоп.
А также всех пересадить за одну ОС, поселить в одинаковых домах и заставить ездить только на метро )))
...
Рейтинг: 0 / 0
Получить int из char
    #38855716
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryпочему вообще сложилось так, что little-endian и big-endian имеют место быть вместе ?
Вообще конечно, все стандарты диктуются экономикой.
Изначально большинство применяло big-endian, потому что он ближе к человеческому представлению чисел, а компьютеры при реализации разных фич могли себе позволить занимать любой физический объем.
Но когда появились первые микропроцессоры с ограничением на размер оборудования и количество элементов в нем, то для экономии транзисторов стали применять такое размещение данных, которое соответствует алгоритмам обработки.
В частности арифметические операции производятся от младших разрядов к старшим.

Так и появилось два подхода, потому что существующий big-endian никто естественно не стал отменять - ничего личного, просто бизнес :)
...
Рейтинг: 0 / 0
Получить int из char
    #38855717
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky, понятно.
Спасибо :)
...
Рейтинг: 0 / 0
25 сообщений из 25, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Получить int из char
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]