1 .谈到字节序,那么会有朋友问什么是字节序
很简单:【例如一个16位的整数,由2个字节组成,8位为一字节,有的系统会将高字节放在内存低的地址上,有的则将低字节放在内存高的地址上,所以存在字节序的问题。】
2 .那么什么是高字节、低字节?
也相当简单:【一个16进制整数有两个字节组成,例如:0xA9。
高字节就是指16进制数的前8位(权重高的8位),如上例中的A。
低字节就是指16进制数的后8位(权重低的8位),如上例中的9。】
大于一个字节的变量类型一般有两种表示方法:
例如:变量0xabcd在大端字节序和小端字节型系统中表示方法如图
我们用代码验证一下我们自己的系统是小端还是大端吧
#include <stdio.h>
/* 联合类型的变量类型,用于测试字节序
* 成员value的高低端字节可以由成员type按字节访问
*/
typedef union{
unsigned short int value; /*短整型变量*/
unsigned char byte[2]; /*字符类型*/
}to;
int main(int argc, char *argv)
{
to typeorder ; /*一个to类型变量*/
typeorder.value = 0xabcd; /* 将typeorder变量赋值为0xabcd */
/* 小端字节序检查 */
if(typeorder.byte[0] == 0xcd && typeorder.byte[1]==0xab){ /*低字节在前*/
printf("Low endian byte order"
"byte[0]:0x%x,byte[1]:0x%x\n",
typeorder.byte[0],
typeorder.byte[1]);
}
/* 大端字节序检查 */
if(typeorder.byte[0] == 0xab && typeorder.byte[1]==0xcd){ /*高字节在前*/
printf("High endian byte order"
"byte[0]:0x%x,byte[1]:0x%x\n",
typeorder.byte[0],
typeorder.byte[1]);
}
return 0;
}
3 .字节序转换函数介绍
字节序转换函数的使用:
#include <stdio.h>
/* 联合类型的变量类型,用于测试字节序
* 成员value的高低端字节可以由成员type按字节访问
*/
/* 16位 */
typedef union{
unsigned short int value;
unsigned char byte[2];
}to16;
/* 32位 */
typedef union{
unsigned long int value;
unsigned char byte[4];
}to32;
#define BITS16 16 /*16位*/
#define BITS32 32 /*32位*/
/* 按照字节打印,begin为字节开始,
* flag为BITS16表示16位,
* flag为BITS32表示32位,
*/
void showvalue(unsigned char *begin, int flag)
{
int num = 0, i = 0;
if(flag == BITS16){
num = 2;
}else if(flag == BITS32){
num = 4;
}
for(i = 0; i< num; i++)
{
printf("%x ",*(begin+i));
}
printf("\n");
}
int main(int argc, char *argv)
{
to16 v16_orig, v16_turn1,v16_turn2; /*一个to16类型变量*/
to32 v32_orig, v32_turn1,v32_turn2; /*一个to32类型变量*/
v16_orig.value = 0xabcd; /* 赋值为0xabcd */
v16_turn1.value = htons(v16_orig.value);/*第一次转换*/
v16_turn2.value = ntohs(v16_turn1.value);/*第二次转换*/
v32_orig.value = 0x12345678; /* 赋值为0x12345678 */
v32_turn1.value = htonl(v32_orig.value);/*第一次转换*/
v32_turn2.value = ntohl(v32_turn1.value);/*第二次转换*/
/* 打印结果 */
printf("16 host to network byte order change:\n");
printf("\torig:\t");showvalue(v16_orig.byte, BITS16); /* 16位数值的原始值 */
printf("\t1 times:");showvalue(v16_turn1.byte, BITS16); /* 16位数值的第一次转换后的值 */
printf("\t2 times:");showvalue(v16_turn2.byte, BITS16); /* 16位数值的第二次转换后的值 */
printf("32 host to network byte order change:\n");
printf("\torig:\t");showvalue(v32_orig.byte, BITS32); /* 32位数值的原始值 */
printf("\t1 times:");showvalue(v32_turn1.byte, BITS32); /* 32位数值的第一次转换后的值 */
printf("\t2 times:");showvalue(v32_turn2.byte, BITS32); /* 32位数值的第二次转换后的值 */
return 0;
}