1,多个字节的数据赋值给单个字节
#include<stdio.h>
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
int main(void)
{
printf("u32 is %d byte(s)\t u16 is %d byte(s)\t u8 is %d byte(s)\n",sizeof(u32),sizeof(u16),sizeof(u8));
u32 intNum = 0x11223344;
u16 shortNum = 0x5566;
u8 charNum = 0x77;
charNum = intNum;
printf("The charNum is %x.\t", charNum);
charNum = shortNum;
printf("Now the charNum is %x.\t", charNum);
return 0;
}
运行结果:
结论:多字节数据作为左值赋给单字节的右值时,由于单字节的“容量”不足以存放多字节,数据截断到可以存放为止,目前的标准是存放最低位到足够位置存放。所以u32的0x11223344赋给u8的charNum时,相较截断了高位的0x112233,把0x44赋给了charNum;同理0x5566的0x55也被截断,只留低位的0x66被赋给charNum。
2,单字节数组的数据赋值给多字节数据
也可以把u32的数据看成是4个u8数据组成的数组,u16看成2个u8
#include<stdio.h>
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
int main(void)
{
int i = 0;
u32 intNum = 0x11223344;
u16 shortNum = 0x5566;
u8 charNum[4] = {0x77,0x88,0x99,0xAA};
u8 charNum1[2] = { 0xbb,0xcc };
/* output the primary data of array charNum and charNum1 */
printf("output the primary data of array charNum and charNum1\n");
for ( i = 0;i < sizeof(charNum);i++)
{
printf("The charNum[%d] is %x.",i, charNum[i]);
}
printf("\n");
for (i = 0;i < sizeof(charNum1);i++)
{
printf("The charNum1[%d] is %x.", i, charNum1[i]);
}
printf("\n\n");
/* output the shifted data of array charNum and charNum1 */
printf("output the shifted data of array charNum and charNum1\n");
charNum[0] = ((u32)intNum>>24); //0x11 = 0x00000011 = 0x11223344>>24
charNum[1] = ((u32)intNum >> 16); //0x22 = 0x00001122 = 0x11223344>>16
charNum[2] = ((u32)intNum >> 8); //0x33 = 0x00112233 = 0x11223344>>8
charNum[3] = intNum; //0x44 = 0x11223344 = 0x11223344
for (i = 0;i < sizeof(charNum);i++)
{
printf("The charNum[%d] is %x.", i, charNum[i]);
}
printf("\n");
charNum1[0] = ((u16)shortNum >> 8); //0x55 = 0x0055 = 0x5566>>8
charNum1[1] = shortNum; //0x66 = 0x5566
for (i = 0;i < sizeof(charNum1);i++)
{
printf("The charNum[%d] is %x.", i, charNum1[i]);
}
printf("\n");
return 0;
}
运行结果:
结论:多字节数据赋值给等值单字节数组时,会使用右移将多字节数据移到最低位字节,就像这样下面这句,移位后打印的charNum[0]为0x11;
charNum[0] = ((u32)intNum>>24); //0x11223344>>24 0x00000011
当移位后除最低位字节以外的字节仍然有非0数据时也不用担心,它会因为内存不够的关系被截断,而只剩下最低位字节数据。例如这句,移位后打印的charNum[2]为0x33。
charNum[2] = ((u32)intNum >> 8); //0x11223344>>8 0x00112233
3,多字节数据赋值给单字节数组的数据
#include<stdio.h>
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
int main(void)
{
int i = 0;
u32 intNum = 0x11223344;
u16 shortNum = 0x5566;
u8 charNum[4] = {0x77,0x88,0x99,0xAA};
u8 charNum1[2] = { 0xbb,0xcc };
/* output the primary data of intNum */
printf("output the primary data of charNum and charNum1\n");
printf("The intNum is %x, shortNum is %x.", intNum, shortNum);
printf("\n\n");
/* output the shifted data of intNum */
printf("output the shifted data of intNum and shortNum\n");
intNum = ((u32)charNum[0] << 24) | ((u32)charNum[1] << 16) | ((u32)charNum[2] << 8) | charNum[3];
//0x77000000 = 0x00000077<<24 0x77880000 = 0x00000088<<16 0x77889900 = 0x00000099<<8 0x778899AA = 0x000000AA<<24
printf("The intNum is %x\n", intNum);
shortNum = ((u16)charNum1[0] << 8) + charNum1[1];
//0xBB00 = 0x00BB<<8 0xBBCC = 0x00CC
printf("The shortNum is %x\n", shortNum);
return 0;
}
运行结果:
结论:单字节数组赋值给多字节数据时,采用左移,将单字节数据移到多字节对应位的位置。另外上面的例程也说明了对数组的运算,“+”和“|”运算机制不一样,但结果是一样的。因为目标操作位的位置正好是0,所以结果一样,如果目标操作位有数据时,则会体现2种运算的差异,例如
printf("%d %d %d %d ", (2 + 3), (2 | 3), (2 | 8), (2 + 8));
运行结果:
PS:如果用多个表达式进行移位赋值,像这样
#include<stdio.h>
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
int main(void)
{
int i = 0;
u32 intNum = 0x11223344;
u16 shortNum = 0x5566;
u8 charNum[4] = {0x77,0x88,0x99,0xAA};
u8 charNum1[2] = { 0xbb,0xcc };
/* output the primary data of intNum */
printf("output the primary data of charNum and charNum1\n");
printf("The intNum is %x, shortNum is %x.", intNum, shortNum);
printf("\n\n");
/* output the shifted data of intNum */
printf("output the shifted data of intNum and shortNum\n");
/* expect real */
intNum = ((u32)charNum[0] << 24); //0x77000000 = 0x00000077<<24 0x77000000 = 0x00000077<<24
intNum = ((u32)charNum[1] << 16); //0x77880000 = 0x00000088<<16 0x00880000 = 0x00000088<<16
intNum = ((u32)charNum[2] << 8); //0x77889900 = 0x00000099<<8 0x00009900 = 0x00000099<<8
intNum = charNum[3]; //0x778899AA = 0x000000AA<<24 0x000000AA = 0x000000AA<<24
//intNum = ((u32)charNum[0] << 24) | ((u32)charNum[1] << 16) | ((u32)charNum[2] << 8)| charNum[3];
printf("The intNum is %x\n", intNum);
/* expect real */
shortNum = ((u16)charNum1[0] << 8); //0xBB00 = 0x00BB<<8 0xBB00 = 0x00BB<<8
shortNum = charNum1[1]; //0xBBCC = 0x00CC 0x00CC = 0x00CC
//shortNum = ((u16)charNum1[0] << 8) + charNum1[1];
printf("The shortNum is %x\n", shortNum);
return 0;
}
运行结果:
结论:得到目标数据只是最后一次赋值的结果,而不是4(2)次赋值的总和。