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;
 }

运行结果:

Java重置字节数组_字节数


结论:多字节数据作为左值赋给单字节的右值时,由于单字节的“容量”不足以存放多字节,数据截断到可以存放为止,目前的标准是存放最低位到足够位置存放。所以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;
 }

运行结果:

Java重置字节数组_字节数_02


结论:多字节数据赋值给等值单字节数组时,会使用右移将多字节数据移到最低位字节,就像这样下面这句,移位后打印的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;
 }

运行结果:

Java重置字节数组_Java重置字节数组_03


结论:单字节数组赋值给多字节数据时,采用左移,将单字节数据移到多字节对应位的位置。另外上面的例程也说明了对数组的运算,“+”和“|”运算机制不一样,但结果是一样的。因为目标操作位的位置正好是0,所以结果一样,如果目标操作位有数据时,则会体现2种运算的差异,例如

printf("%d  %d   %d   %d ", (2 + 3), (2 | 3), (2 | 8), (2 + 8));

Java重置字节数组_数据_04

运行结果:

Java重置字节数组_Java重置字节数组_05

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;
 }

运行结果:

Java重置字节数组_数据_06


结论:得到目标数据只是最后一次赋值的结果,而不是4(2)次赋值的总和。