关于字节序的问题——代码理解

什么是字节序
字节序指的是多字节的数据各字节的存储顺序。在几乎所有计算机中,多字节数据被存储为连续的字节序列。例如,一个4字节的int类型变量a,其存储的起始地址为0x804900,那么a的四个字节将被分别存在0x804900,0x804901,0x804902,0x804903的位置。但是问题来了,a的最低有效位可以存储在最前面,也可以存储在高最后面,就有两种不同的存储顺序。这就引出了大端序和小端序。

大端序和小端序
实际上,如果最低有效位在最高有效位的前面,则该存储规则为小端序;反之,如果最低有效位在最高有效的后面,则该存储规则为大端序。不同的处理器体系,采用的字节序可能是不同的。例如,x86采用小端序,而PowerPc 970等采用大端序。那么如此一来,不同机器之间的数据传输是不是会出问题呢?

本地序和网络序
本地序(也称主机序)即指前面处理器本身所采用的字节序,因此有的大端序,有的小端序。而网络序,是指网络传输采用的字节序。所幸,网络序是标准化的,即一般统一采用大端序。因此,发送网络数据之前需要将数据转换为网络序,从而避免了前面所担心的问题。而C语言也针对整型数据提供了一组接口,htonl、htons用于本地序转网络序,以及ntohl、ntohs用于网络序转本地序。

示例
我们通过一个例子来观察大端序和小端序,本地序和网络序的不同。示例程序做的事情很简单,定义整型变量a,将a的每一个字节的地址和值打印出来,将其转换为网络序之后,再打印观察。程序清单如下:

#include<stdio.h>
#include<arpa/inet.h>

/* 将char类型(1个字节)逐个打印成十六进制形式*/
void stringToHex(char *string,unsigned int len)
{
unsigned int loop=0;
//指向整型变量a的地址
char *temp=string;
//如果指针为NULL,跳出函数
if(temp==NULL)
{
printf(“input para is NULL\n”);
return;
}
for(loop = 0; loop<len;loop++)
{
//输出指针的地址,指针所指的地址(即指针的值,以十六进制形式输出2位,即8bit/1个字节)
printf(“%p:0x%2x\n”,temp,*temp);
//指针指向下一个字节的地址
temp++;
}

}

int main(int argc, char const *argv[])
{
printf(“转换之前\n”);
//定义一个整型变量并赋值(十六进制数)
int a=0x12345678;
printf(“a=%d\n”,a);
stringToHex((char )&a,sizeof(int));
/转为网络字节序之后再打印/
printf(“转换之后\n”);
a = htonl(a);/转换为网络序/
printf(“a = %d\n”,a);
//(char
)&a,强制a的地址(&a)转换成char (字符串)形式
stringToHex((char
)&a,sizeof(int));

return 0;

}

编译运行后的结果:
在这里插入图片描述

观察运行结果,我们可以发现以下几件事情:

  • 小端序a低位的0x78存储在低地址,而高位的12存储在高地址,也就是说对于小端序,其低位存储在高位之前。
  • 使用htonl宏将a转为网络序(大端序)之后,a的低位存储在高位之后。
  • 转换前后,打印a的数值大小截然不同。

————————————————
版权声明:本文为CSDN博主「守望之名」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/hyb612/article/details/82928446/

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值