当我尝试运行以下代码时:
void* data = new char[SIZE]();
int16_t* num = static_cast<int16_t*>(data);
char* c = static_cast<char*>(data);
num[0] = 49;
num[1] = 50;
num[2] = 48;
for(int i = 0; i < 3; ++i)
cout << num[i] << " ";
cout << endl;
for(int i = 0; i < 6; ++i)
cout << "'" << c[i] << "' ";
cout << endl;
c[1] = 1;
cout << num[0] << endl;
我得到了一些意外的结果:
49 50 48
'1' '' '2' '0' ''
305
因此,输出的第一行将确认
num[0] == 49
(int16),其二进制格式为00000000 00110001
。转换为char
,第一个字节应该是不可打印的字符,第二个字节应该是'1'
。但是第二行表明情况恰恰相反。同样,第三行显示了尝试将第二个字节更改为
00000001
而不是第一个字节的尝试。我期望它是00000000 00000001
,但是int16的值为305,它是00000001 00110001
。这里发生了什么?
最佳答案
发生这种情况是由于计算机将信息保存在其内存中的方式,即Endianness。
这是两个大/小尾数表示法的16bit变量说明:
在您的情况下,由于您是通过uint16_t
变量设置值的,并且您的计算机使用的是little-endian,因此每对都以相反的顺序存储,因此,在不可打印字符之前打印'1'。
额外阅读(阐述马丁·邦纳的评论)
对于16位变量,只有两种可能的字节字节序表示法,即上述的那些。对于32位变量,总共有12种可能的字节顺序,并且至少使用了其中的三种:大字节序,小字节序和PDP字节序(又名中间字节序):
关于c++ - C++:强制转换char指针指向数据的意外部分,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46687360/