我不确定这是否正确,我已经测试过了,似乎有一些字节关闭了。。。基本上,我有以下几种:
unsigned char szBuffer[1024] = {0};
long long nValue = 1334553536;
memcpy(szBuffer, (char*)&nValue, sizeof(long long));
//
long long nNewValue = reinterpret_cast<long long>(szBuffer);
printf(nNewValue); //prints out a smaller number than previously stated
有人介意指出我哪里错了吗?非常感谢。
您将nNewValue
设置为szBuffer
的地址,而不是从该地址读取数据。用途:
long long nNewValue = *reinterpret_cast<long long*>(szBuffer);
更改此语句
long long nNewValue = reinterpret_cast<long long>(szBuffer);
至
long long nNewValue = *reinterpret_cast<long long *>(szBuffer);
这是您的程序的修改版本,在我的系统上运行(扩展为完整的程序):
#include <iostream>
#include <cstring>
int main() {
unsigned char szBuffer[1024] = {0};
long long nValue = 1334553536;
std::memcpy(szBuffer, &nValue, sizeof(long long));
long long nNewValue = *(reinterpret_cast<long long*>(&szBuffer));
std::cout << nValue << "n" << nNewValue << "n";
}
memcpy
的前两个参数属于void*
类型,因此不需要强制转换它们;如果确实强制转换它们(C++中不赞成这种转换吗?),则应该强制转换为void*
,而不是char*
。
对nNewValue
的赋值将缓冲区的地址转换为long long*
,然后取消引用转换后的值。
但这是个坏主意。g++对转换后的指针的取消引用发出警告:
warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
此外,不能保证作为unsigned char
的数组的szBuffer
是正确对齐的,因此它的前几个字节可以安全地被视为long long
对象。您最可能使用的x86或x86_64系统可以容忍未对齐的内存访问,但并非所有系统都这样做
指针强制转换通常是不安全的,除非您确切地您在做什么。
如果要将字符数组的一部分重新解释为其他类型的对象,如果确实需要将内存本身解释为不同类型的对象或使用memcpy
,则可以使用并集。(即便如此,也要确保你真的需要这样做;很可能你没有。大多数时候,如果你想存储long long
对象,你只需要定义一个long long
对象。)