我有unsigned char*
。通常这指向一大块数据,但在某些情况下,指针是数据,即。将int
值转换为unsigned char*
指针(unsigned char* intData = (unsigned char*)myInteger;
),反之亦然。
但是,我需要使用float
值执行此操作,并且不断给出转换错误。
unsigned char* data;
float myFloat = (float)data;
我该怎么做?
答案 0 :(得分:4)
bit_cast:
template <class Dest, class Source>
inline Dest bit_cast(Source const &source) {
static_assert(sizeof(Dest)==sizeof(Source), "size of destination and source objects must be equal");
static_assert(std::is_trivially_copyable<Dest>::value, "destination type must be trivially copyable.");
static_assert(std::is_trivially_copyable<Source>::value, "source type must be trivially copyable");
Dest dest;
std::memcpy(&dest, &source, sizeof(dest));
return dest;
}
用法:
char *c = nullptr;
float f = bit_cast<float>(c);
c = bit_cast<char *>(f);
答案 1 :(得分:3)
使用给定变量存储其他数据的唯一正确方法是按字节复制数据:
template <typename T>
void store(unsigned char * & p, T const & val)
{
static_assert(sizeof(unsigned char *) >= sizeof(T));
char const * q = reinterpret_cast<char const *>(&val);
std::copy(q, q + sizeof(T), reinterpret_cast<char *>(&p));
}
用法:
unsigned char * p;
store(p, 1.5);
store(p, 12UL);
匹配检索功能:
template <typename T>
T load(unsigned char * const & p)
{
static_assert(sizeof(unsigned char *) >= sizeof(T));
T val;
char const * q = reinterpret_cast<char const *>(&p);
std::copy(q, q + sizeof(T), reinterpret_cast<char *>(&val));
return val;
}
用法:
auto f = load<float>(p);
答案 2 :(得分:2)
如果您的编译器支持它(GCC),那么使用union。根据C ++标准,这是未定义的行为。
union {
unsigned char* p;
float f;
} pun;
pun.p = data;
float myFloat = pun.f;
这适用于sizeof(unsigned char *) == sizeof(float)
。如果指针大于浮点数,那么你必须重新考虑你的策略。
请参阅type punning上的维基百科文章,特别是关于use of a union的部分。
GCC允许使用union进行类型惩罚,只要你直接使用union而不是对联合... see this IBM discussion on type-pun problems进行类型转换,以获得使用GCC进行类型惩罚的正确和错误方法。
另请参阅维基百科关于strong and weak typing的文章以及关于type punning and strict aliasing的精心研究的文章。
答案 3 :(得分:-1)
unsigned char* data;
float myFloat = *(float*)data;