Как из 4-ех байт сделать int-овое значение
У меня есть 4 байта. Как можно из них слепить int-овое число? И float-овое?
Дык все также. Берешь массив
BYTE bt[4];
И переменую
int val;
А потом:
memcpy(&val, &bt, sizeof(int));
Это один из способов. Намек ясен? :)
Дык все также. Берешь массив
BYTE bt[4];
И переменую
int val;
А потом:
memcpy(&val, &bt, sizeof(int));
Это один из способов. Намек ясен? :)
Неа... Не пройдет.
bt имеет тип BYTE[4], а &bt имеет тип BYTE[4]*, что в данном случае равносильно BYTE**.
Кстати, в твоем примере потенциальный Buffer Overflow. Найдешь?
Все значительно проще:
val = *(int*)bt;
Только обрати внимание, что старшие байты int хранятся в конце массива BYTE[4], т.е. содержимого массива {0x01, 0x02, 0x03, 0x04} будет соотвестствовать значение int 0x04030201.
Большое сасыбо, оба способа работают, но почему же 2-ой лучше?
Да потому, что он проще, работает быстрее, не соджержит потенциальных ошибок, да и просто понятнее.
Только обрати внимание, что старшие байты int хранятся в конце массива BYTE[4], т.е. содержимого массива {0x01, 0x02, 0x03, 0x04} будет соотвестствовать значение int 0x04030201.
Не отрицаю :) И автор темы должен был в это сам разобраться. Собственно вопрос сформулирован так что разницы это не имеет :D
Сдаюсь. Не поможешь? ;)
. Вероятно ты прав. Привык работать с динамическими массивами, забыл как тут со статическими-то :)
Сдаюсь. Не поможешь? ;)
Рассмотрим твой, но исправленный пример
memcpy(&val, bt, sizeof(int));
т.е. bt без амперсанда(&)
Так вот sizeof(int) не обязательно равен sizeof(bt), и хорошо если он будет меньше, а если больше? Тогда мы вполне можем получить Access Deny.
Как исправить?
Для начала скажу, что memcpy - это пережиток C. На С++ лучше этой функцией не пользоваться.
А исправить можно так:
memcpy(&val, bt, min(sizeof int, sizeof bt));
P.S. С buffer overflow - это я оговорился, невнимательно посмотрел, sizeof чего ты используешь.
memcpy(&val, bt, min(sizeof int, sizeof bt));
Хм...
Я тут подумал про min, и родилась задачка для "домашнего задания".
Т.к. тема топика, видимо, исчерпана предлагаю эту задачку.
Обычно min это подобный макрос:
#define min(a,b) (a)<(b)?(a):(b)
Для чего так много скобок, думаю очевидно? :)
Вопрос в том вычисляется ли значение в данном случае (min(sizeof int, sizeof bt)) в рантайм или на этапе компиляции (что возможно при наличии толкового оптимизатора)?
Если результат вычисляется каждый раз в рантайм, что само по себе не есть хорошо, то как перенести это вычисление на этап компиляции?
Хм...
Я тут подумал про min, и родилась задачка для "домашнего задания".
Т.к. тема топика, видимо, исчерпана предлагаю эту задачку.
Обычно min это подобный макрос:
#define min(a,b) (a)<(b)?(a):(b)
Для чего так много скобок, думаю очевидно? :)
Вопрос в том вычисляется ли значение в данном случае (min(sizeof int, sizeof bt)) в рантайм или на этапе компиляции (что возможно при наличии толкового оптимизатора)?
Если результат вычисляется каждый раз в рантайм, что само по себе не есть хорошо, то как перенести это вычисление на этап компиляции?
Гы, а я вот сидел и искал оверфлоу :) Чуть лысину на затылке не расцарапал 8)
Насколько я знаю, компилятор на этапе сборки подставляет вместо того что задефайнено макросом то что дефайн означает (во, млин, выразился! :). Так что в реалтайме оно будет вычисляться каждый раз. это был имхо.
Про sizeof'ы.
Эээ, это-то при том что bt объявлена как
BYTE bt[4];
? Вероятно, это возможно только если инт в данном случае размером не четыре байта. Это устроить достаточно просто. Мое предложение - проверить чтоб количество елементов массива байт равнялось сайзофу инта. Возможно на этаме компиляции (как только лучше?). И вопрос в догонку: что произойдет если инт у нас, например, двухбайтен в твоем примере:
Проде старшие для инта биты должны урезаться? Я прав?
Гы, а я вот сидел и искал оверфлоу :) Чуть лысину на затылке не расцарапал 8)
Насколько я знаю, компилятор на этапе сборки подставляет вместо того что задефайнено макросом то что дефайн означает (во, млин, выразился! :). Так что в реалтайме оно будет вычисляться каждый раз. это был имхо.
Правильно... что ИМХО :D
sizeof - это константное значение, которое вычисляется на этапе компиляции.
Математические операции с константами так же вычисляются на этапе компиляции, т.е. 4/2 не будет вычислятся каждый раз, а лишь единожды, причем еще при компиляции.
Не вижу особого отличия для min с константными аргументами, поэтому, думаю, что и min вычисляется на этапе компиляции. Проверить это несложно, попробуй.
Мое предложение - проверить чтоб количество елементов массива байт равнялось сайзофу инта. Возможно на этаме компиляции (как только лучше?).
Конечно, лучше все операции, которые можно сделать на этапе компиляции, сделать именно на этапе компиляции.
Но вот зачем проверять на равенство?
Достаточно узнать минимальный размер, как уже показал.
И вопрос в догонку: что произойдет если инт у нас, например, двухбайтен в твоем примере:
Проде старшие для инта биты должны урезаться? Я прав?
Абсолютно.
Правильно... что ИМХО :D
sizeof - это константное значение, которое вычисляется на этапе компиляции.
Математические операции с константами так же вычисляются на этапе компиляции, т.е. 4/2 не будет вычислятся каждый раз, а лишь единожды, причем еще при компиляции.
Не вижу особого отличия для min с константными аргументами, поэтому, думаю, что и min вычисляется на этапе компиляции. Проверить это несложно, попробуй.
Ухты. Я как то на это никогда и внимания не обращал. Вообще для меня это естественно и разумно - следовательно скорей всего так и есть
(железная логика. Работает када влом пробовать.)
Значит сейчас нужен кто-нить кто найдет время это проверить и закроет тему :)
а теперь по делу.
ну во-первых тема топика даже и не начала исчерпывать себя. Так как было замечено, что memcpy - пережиток прошлого (что кстати, неверно - для копирования строк и подобной фигни - самое то), то советую обратить внимание на различные X_cast'ы - static_cast, reinterpret_cast и т.д. - это как раз то, что вам надо... хотя все нормальные люди юзают именно двойное преобразование указателей :) - проще и быстрее, зато менее корректно с точки зрения С++.
Как будет вычисляться min, заранее сказать нельзя. это одна из фишек, которые отдаются на откуп компилятору. хотя, скорее всего, при выключенной оптимизации будет точно считаться в рантайме, а при включенной - никто не знает, кто, как, где и когда вычисляется. если надо перевести на этап компиляции, то можно использовать различные __intXX - у них заранее определен размер.
Кстати, sizeof - это не константа, а оператор!!!! а математические операции вычисляются на этапе компиляции лишь при включенной оптимизации И по желанию компилятора в define'ах. А если попробовать говорить о различных системах... ну да ладно... форум все-таки про winapi :)
удачи :)
фигушки вам, а не закрытие темы. разве что как не соответствующей теме форума :), но так как вопрос интересный, а тем негусто - пусть живет
а теперь по делу.
ну во-первых тема топика даже и не начала исчерпывать себя. Так как было замечено, что memcpy - пережиток прошлого (что кстати, неверно - для копирования строк и подобной фигни - самое то), то советую обратить внимание на различные X_cast'ы - static_cast, reinterpret_cast и т.д. - это как раз то, что вам надо... хотя все нормальные люди юзают именно двойное преобразование указателей :) - проще и быстрее, зато менее корректно с точки зрения С++.
Как будет вычисляться min, заранее сказать нельзя. это одна из фишек, которые отдаются на откуп компилятору. хотя, скорее всего, при выключенной оптимизации будет точно считаться в рантайме, а при включенной - никто не знает, кто, как, где и когда вычисляется. если надо перевести на этап компиляции, то можно использовать различные __intXX - у них заранее определен размер.
Кстати, sizeof - это не константа, а оператор!!!! а математические операции вычисляются на этапе компиляции лишь при включенной оптимизации И по желанию компилятора в define'ах. А если попробовать говорить о различных системах... ну да ладно... форум все-таки про winapi :)
удачи :)
Гы, спасибо что наставил на путь истинный :) Думаю, сия полезная инфа может пригодиться многим.
Как будет вычисляться min, заранее сказать нельзя. это одна из фишек, которые отдаются на откуп компилятору. хотя, скорее всего, при выключенной оптимизации будет точно считаться в рантайме, а при включенной - никто не знает, кто, как, где и когда вычисляется.
Конкретные факты. Лично я другого мнения, и мнение это не напустом месте.
Заметь, min не просто, а от констактных значений.
если надо перевести на этап компиляции, то можно использовать различные __intXX - у них заранее определен размер.
Не понял, причем тут это?
Если мне что-то надо перевести на этап компиляции, я использую шаблонные классы.
Кстати, sizeof - это не константа, а оператор!!!! а математические операции вычисляются на этапе компиляции лишь при включенной оптимизации И по желанию компилятора в define'ах.
ЕРУНДА!!!
sizeof ВСЕГДА вычисляется на этапе компиляции:
sizeof
The sizeof operator is a compile-time operator that returns the size, in bytes, of the argument passed to it.
и вправду я не прав оказался.
хотя...Green, можешь сказать откуда взято это:
The sizeof operator is a compile-time operator that returns the size, in bytes, of the argument passed to it.
и есть ли там что-нибудь подобное для арифметических и тернарного операторов?
у трупа страуса я к сожалению ничего подобного не нашел :(
Green, спасибо.
и вправду я не прав оказался.
хотя...Green, можешь сказать откуда взято это:
и есть ли там что-нибудь подобное для арифметических и тернарного операторов?
у трупа страуса я к сожалению ничего подобного не нашел :(
http://www.cppreference.com
а точнее здесь:
http://www.cppreference.com/keywords_details.html#sizeof
В стандарте С++, кроме того, сказано:
The result is a constant of an implementation-defined type which is
the same type as that which is named size_t in the standard header
<cstddef>
http://www.csci.csusb.edu/dick/c++std/cd2/expr.html#expr.sizeof