4字节数组强制转换为32位整数问题

时间:2023-01-12 08:06:39
BYTE data[4]={0x00,0x00,0xe6,0x00};//第一句
UINT a11=*(UINT*)data;//第二句

第一句中data排列的二进制对应的整数是58880,而第二句强制转换的结果却是15073280。

在VC6下调试的,请问上面的强制转换哪里出了问题?

15 个解决方案

#1


大小端问题。

#2


0xe60000 = 15073280

#3


百度百科  大小端模式

大端模式
  所谓的大端模式,是指数据的低位(就是权值较小的后面那几位)保存在内存的高地址中,而数据的高位,保存在内存的低地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;
小端模式
  所谓的小端模式,是指数据的低位保存在内存的低地址中,而数 据的高位保存在内存的高地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低,和我们的逻辑方法一致。

#4


58880=0xe600;0xe60000=15073280
为什么强制转换在后面加0了,请luciferisnotsatan
 朋友具体说说!!

#5


谢谢luciferisnotsatan
看来这里的强制转换使用了大端模式,而现在需要用小端模式,那如何来指定这种模式?

#6


用<<

#7


大小端与你的cpu及os有关系,不要自己决定是什么顺序

#8


int x = 0x12345678;
在你机器(通常PC机都是小字节序)的内存上,这个int值的存放如下

0x78 0x56 0x34 0x12

data数组,内存里
0x00 0x00 0xe6 0x00

当作int来读取后就成了 0x00e60000  十进制就是15073280

多了个0,那是你选的数字,交换后看上去多了个0。实际你用0x12345678看看就知道了

#9


BYTE data[4]={0x00,0x00,0xe6,0x00};//第一句
UINT a11=*(UINT*)data;//第二句


al1表示成0x0000e600
al1 = data[0]<<24 + data[1]<<16 + data[2]<<8 + data[3];

al1表示成0x00e60000
al1 = data[3]<<24 + data[2]<<16 + data[1]<<8 + data[0];

#10


/*****************************************************************/
//name          : convert.h
//function      : 底层 socket 流字节序列转换类实现 
//copyright     : 
//author        : 
//date          : 2007-08-21
/**************************************************************/

#include "convert.h"

CConvert::CConvert(void)
{
}

CConvert::~CConvert(void)
{
}

void CConvert::WriteUInt16(char * pBuffer,unsigned short value)
{
pBuffer[0] = (unsigned char)((value >> 8) & 0xFF);
pBuffer[1] = (unsigned char)((value) & 0xFF);
pBuffer+=2;
}

unsigned short CConvert::ReadUInt16(const char *pBuffer)
{
unsigned short ch1, ch2, ret=0;
ch1 = (unsigned short)(pBuffer[ 0] & 0xff);
ch2 = (unsigned short)(pBuffer[ 1] & 0xff);
ret=((ch1 << 8) + (ch2 << 0));
return ret;
}

void CConvert::WriteUInt32(char *pBuffer ,unsigned int value)
{
pBuffer[0] = (unsigned char)((value >> 24) & 0xFF);
pBuffer[1] = (unsigned char)((value >> 16) & 0xFF);
pBuffer[2] = (unsigned char)((value >>  8) & 0xFF);
pBuffer[3] = (unsigned char)((value >>  0) & 0xFF);
}

unsigned int CConvert::ReadUInt32(const char *pBuffer)
{
unsigned int ch1, ch2, ch3, ch4, ret=0;
ch1 = (unsigned int)(pBuffer[ 0] & 0xff);
ch2 = (unsigned int)(pBuffer[ 1] & 0xff);
ch3 = (unsigned int)(pBuffer[ 2] & 0xff);
ch4 = (unsigned int)(pBuffer[ 3] & 0xff);
ret=((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
return ret;
}
/*
void CConvert::WriteUInt64(char *pBuffer ,UInt64 value)
{
pBuffer[0] = (UInt8)((value >> 56) & 0xFF);
pBuffer[1] = (UInt8)((value >> 48) & 0xFF);
pBuffer[2] = (UInt8)((value >> 40) & 0xFF);
pBuffer[3] = (UInt8)((value >> 32) & 0xFF);
pBuffer[4] = (UInt8)((value >> 24) & 0xFF);
pBuffer[5] = (UInt8)((value >> 16) & 0xFF);
pBuffer[6] = (UInt8)((value >>  8) & 0xFF);
pBuffer[7] = (UInt8)((value >>  0) & 0xFF);
}

UInt64 CConvert::ReadUInt64(char *pBuffer)
{
unsigned int ch1, ch2, ch3, ch4, ch5,ch6,ch7,ch8, ret=0;
ch1 = (unsigned int)(pBuffer[ 0] & 0xff);
ch2 = (unsigned int)(pBuffer[ 1] & 0xff);
ch3 = (unsigned int)(pBuffer[ 2] & 0xff);
ch4 = (unsigned int)(pBuffer[ 3] & 0xff);
ch5 = (unsigned int)(pBuffer[ 4] & 0xff);
ch6 = (unsigned int)(pBuffer[ 5] & 0xff);
ch7 = (unsigned int)(pBuffer[ 6] & 0xff);
ch8 = (unsigned int)(pBuffer[ 7] & 0xff);

ret=((ch1 << 56) + (ch2 << 48) + (ch3 << 40) + (ch4 << 32)
+(ch5 << 24) + (ch6 << 16) + (ch7 << 8) + (ch8 << 0));
return ret;
}*/

void CConvert::WriteUInt8(char * pBuffer,unsigned char value)
{
pBuffer[0] = (unsigned char)(value);
}

unsigned char CConvert::ReadUInt8(const char *pBuffer)
{
return (unsigned char)pBuffer[0];
}

unsigned int CConvert::ReadByteArray(const char *pBuffer, unsigned int uiLen)
{
//assert(0);
return 0;
}

unsigned int CConvert::WriteByteArray(char *pBuffer, unsigned int Len)
{
//assert(0);
return 0;
}

#11


vc6判断结果xp下使用的是小端模式,上面搞混了。现在需要大端模式来强制转换。

#12


原始问题是用4个字节表示时间:年存到1-6位(6位);月存到7-10位(4位);日存到11-15位(5位);时存到16-20位(5位);分存到21-26位(6位);秒存到27-32位(6位)。年月日秒默认取0,只取时分,{0x00,0x00,0xe6,0x00}对应的时分就是14时24分,用位运算运算如何取出?
按大端模式h=(0xe600>>12)&(~((UINT)(~0)<<5),m=(0xe600>>6)&(~((UINT)(~0)<<6)正好就取出时间了,可小端模式如何取,现在局限在强制转换这个思路上了,还有其他思路?

#13


为什么不写个结构体,用位域呢?
至于大小端,在单机上就不用纠结(除非你的代码打算跨平台)。网络通信,也有已经做好的函数给你用。

#14


谢谢回复的朋友,算是明白这个问题了。

#15


写个函数判断一下是小端或者大端模式
   typedef union t
{
unsigned char a;
unsigned short b;
} _t;
  _t t;
t.b = 1;
if(t.a == 1)
{
cout<< "da duan style"<<endl;
}
else
{
cout<<"xiao duan style"<<endl;
}

#1


大小端问题。

#2


0xe60000 = 15073280

#3


百度百科  大小端模式

大端模式
  所谓的大端模式,是指数据的低位(就是权值较小的后面那几位)保存在内存的高地址中,而数据的高位,保存在内存的低地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;
小端模式
  所谓的小端模式,是指数据的低位保存在内存的低地址中,而数 据的高位保存在内存的高地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低,和我们的逻辑方法一致。

#4


58880=0xe600;0xe60000=15073280
为什么强制转换在后面加0了,请luciferisnotsatan
 朋友具体说说!!

#5


谢谢luciferisnotsatan
看来这里的强制转换使用了大端模式,而现在需要用小端模式,那如何来指定这种模式?

#6


用<<

#7


大小端与你的cpu及os有关系,不要自己决定是什么顺序

#8


int x = 0x12345678;
在你机器(通常PC机都是小字节序)的内存上,这个int值的存放如下

0x78 0x56 0x34 0x12

data数组,内存里
0x00 0x00 0xe6 0x00

当作int来读取后就成了 0x00e60000  十进制就是15073280

多了个0,那是你选的数字,交换后看上去多了个0。实际你用0x12345678看看就知道了

#9


BYTE data[4]={0x00,0x00,0xe6,0x00};//第一句
UINT a11=*(UINT*)data;//第二句


al1表示成0x0000e600
al1 = data[0]<<24 + data[1]<<16 + data[2]<<8 + data[3];

al1表示成0x00e60000
al1 = data[3]<<24 + data[2]<<16 + data[1]<<8 + data[0];

#10


/*****************************************************************/
//name          : convert.h
//function      : 底层 socket 流字节序列转换类实现 
//copyright     : 
//author        : 
//date          : 2007-08-21
/**************************************************************/

#include "convert.h"

CConvert::CConvert(void)
{
}

CConvert::~CConvert(void)
{
}

void CConvert::WriteUInt16(char * pBuffer,unsigned short value)
{
pBuffer[0] = (unsigned char)((value >> 8) & 0xFF);
pBuffer[1] = (unsigned char)((value) & 0xFF);
pBuffer+=2;
}

unsigned short CConvert::ReadUInt16(const char *pBuffer)
{
unsigned short ch1, ch2, ret=0;
ch1 = (unsigned short)(pBuffer[ 0] & 0xff);
ch2 = (unsigned short)(pBuffer[ 1] & 0xff);
ret=((ch1 << 8) + (ch2 << 0));
return ret;
}

void CConvert::WriteUInt32(char *pBuffer ,unsigned int value)
{
pBuffer[0] = (unsigned char)((value >> 24) & 0xFF);
pBuffer[1] = (unsigned char)((value >> 16) & 0xFF);
pBuffer[2] = (unsigned char)((value >>  8) & 0xFF);
pBuffer[3] = (unsigned char)((value >>  0) & 0xFF);
}

unsigned int CConvert::ReadUInt32(const char *pBuffer)
{
unsigned int ch1, ch2, ch3, ch4, ret=0;
ch1 = (unsigned int)(pBuffer[ 0] & 0xff);
ch2 = (unsigned int)(pBuffer[ 1] & 0xff);
ch3 = (unsigned int)(pBuffer[ 2] & 0xff);
ch4 = (unsigned int)(pBuffer[ 3] & 0xff);
ret=((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
return ret;
}
/*
void CConvert::WriteUInt64(char *pBuffer ,UInt64 value)
{
pBuffer[0] = (UInt8)((value >> 56) & 0xFF);
pBuffer[1] = (UInt8)((value >> 48) & 0xFF);
pBuffer[2] = (UInt8)((value >> 40) & 0xFF);
pBuffer[3] = (UInt8)((value >> 32) & 0xFF);
pBuffer[4] = (UInt8)((value >> 24) & 0xFF);
pBuffer[5] = (UInt8)((value >> 16) & 0xFF);
pBuffer[6] = (UInt8)((value >>  8) & 0xFF);
pBuffer[7] = (UInt8)((value >>  0) & 0xFF);
}

UInt64 CConvert::ReadUInt64(char *pBuffer)
{
unsigned int ch1, ch2, ch3, ch4, ch5,ch6,ch7,ch8, ret=0;
ch1 = (unsigned int)(pBuffer[ 0] & 0xff);
ch2 = (unsigned int)(pBuffer[ 1] & 0xff);
ch3 = (unsigned int)(pBuffer[ 2] & 0xff);
ch4 = (unsigned int)(pBuffer[ 3] & 0xff);
ch5 = (unsigned int)(pBuffer[ 4] & 0xff);
ch6 = (unsigned int)(pBuffer[ 5] & 0xff);
ch7 = (unsigned int)(pBuffer[ 6] & 0xff);
ch8 = (unsigned int)(pBuffer[ 7] & 0xff);

ret=((ch1 << 56) + (ch2 << 48) + (ch3 << 40) + (ch4 << 32)
+(ch5 << 24) + (ch6 << 16) + (ch7 << 8) + (ch8 << 0));
return ret;
}*/

void CConvert::WriteUInt8(char * pBuffer,unsigned char value)
{
pBuffer[0] = (unsigned char)(value);
}

unsigned char CConvert::ReadUInt8(const char *pBuffer)
{
return (unsigned char)pBuffer[0];
}

unsigned int CConvert::ReadByteArray(const char *pBuffer, unsigned int uiLen)
{
//assert(0);
return 0;
}

unsigned int CConvert::WriteByteArray(char *pBuffer, unsigned int Len)
{
//assert(0);
return 0;
}

#11


vc6判断结果xp下使用的是小端模式,上面搞混了。现在需要大端模式来强制转换。

#12


原始问题是用4个字节表示时间:年存到1-6位(6位);月存到7-10位(4位);日存到11-15位(5位);时存到16-20位(5位);分存到21-26位(6位);秒存到27-32位(6位)。年月日秒默认取0,只取时分,{0x00,0x00,0xe6,0x00}对应的时分就是14时24分,用位运算运算如何取出?
按大端模式h=(0xe600>>12)&(~((UINT)(~0)<<5),m=(0xe600>>6)&(~((UINT)(~0)<<6)正好就取出时间了,可小端模式如何取,现在局限在强制转换这个思路上了,还有其他思路?

#13


为什么不写个结构体,用位域呢?
至于大小端,在单机上就不用纠结(除非你的代码打算跨平台)。网络通信,也有已经做好的函数给你用。

#14


谢谢回复的朋友,算是明白这个问题了。

#15


写个函数判断一下是小端或者大端模式
   typedef union t
{
unsigned char a;
unsigned short b;
} _t;
  _t t;
t.b = 1;
if(t.a == 1)
{
cout<< "da duan style"<<endl;
}
else
{
cout<<"xiao duan style"<<endl;
}