什么是大端法和小端法?

什么是大端法和小端法?

在几乎所有的机器上,多字节对象都被存储为连续的字节序列,对象的地址为所使用字节中的最小地址。

例如,假设一个类型为int的变量x的地址为0x100,即&x的值为0x100。那么x的4个字节将被存储在
存储器的0x100,0x101,0x102和0x103的位置。

字节序即为多字节对象存储在内存中的字节顺序,有两种不同的存储方案:大端法和小端法。现代的处理器大多为双端法,大小端都支持,可以配置称大端法或者小端法。

大端法

最高有效字节在最前面的方式称为大端法,例如假设变量x类型为int型,位于地址0x100的地方,其16进制值为0x12345678,地址范围为0x100到0x103字节。

对于大端法的机器来说:

0x1000x1010x1020x103
12345678

由上图可见,地址从左向右增长,x的最高有效字节12在最前面存储。这正好和我们平时书写习惯一致,先书写最高有效字节,再依次写其余字节。

小端法

最低有效字节在最前面的方式成为小端法,这正好和大端法相反,仍然用大端法中举的例子说明:

0x1000x1010x1020x103
78563412

由上图可见,地址依然从左向右增长,x的最低有效字节在最前面存储,与大端法相反。

如何判断我的机器是大端法还是小端法?

在《UNIX网络编程》上有一个程序可以判断一个机器是大端法还是小端法,我稍加改造了一下:

#include<stdio.h>
#include<stdlib.h>

int
main(int argc, char **argv)
{
    union {
        short  s;
        char   c[sizeof(short)];
    } un;

    un.s = 0x0102;
    if (sizeof(short) == 2) {
	if (un.c[0] == 1 && un.c[1] == 2)
		printf("大端法\n");
	else if (un.c[0] == 2 && un.c[1] == 1)
		printf("小端法\n");
	else
		printf("不能判断\n");
    } else
	printf("sizeof(short) = %d\n", sizeof(short));

    exit(0);
}

大端法和小端法对程序员有什么影响?

多数程序员不必关系所使用的机器是大端法还是小端法,在大多数情况下都不会出问题,但在某些特殊情况下这有可能成为问题:

1.编写网络程序时,主机之间通过网络相互通信,不同主机之间可能采用不同的方法,而且网络字节序和主机字节序也可能不同。

当小端法机器产生的数据被发送到大端法机器或者反方向发送时会发现接受程序子里面的字节成了反序的。为了避免这种情况的发

生,规定网络应用程序在将数据发送之前现将数据转换称网络字节序,在接收主机那边,主机再将网络字节序的数据转换成适合本

主机的主机字节序,从而避免了字节序异常。(网络字节序为大端法)

网络编程中常用的转换函数有如下几个:

uing16_t htons(uint16_t host16bitvalue);    // 参数为16位主机字节序的值,返回值是16位网络字节序的值

uint32_t htonl(uint32_t host32bitvalue);    // 参数为32位主机字节序的值,返回值是32位网络字节序的值

uint16_t ntohs(uint16_t net16bitvalue);     // 参数为16位网络字节序的值,返回值是16位主机字节序的值

uint32_t ntohl(uint32_t net32bitvalue);     // 参数为16位网络字节序的值,返回值是16位主机字节序的值

2.当调试程序时常常需要将程序编译成汇编形式,当阅读汇编代码时数据的字节序很重要,需要根据自己的机器是大端法还是小

端法来不同对待,以免搞错字节顺序。

3.当编写规避正常类型系统的程序时,在C语言中可以使用强制类型转换来允许以一中类型引用一个对象,而这种数据类型与创建

这个对象时定义的数据类型不同,大多数应用编程都不推荐这种编码技巧,但是它们对于系统级编程来说十分有用。

bool_布尔型数据类型(True 或者 False)
int_默认的整数类型(类似于 C 语言中的 long,int32 或 int64)
intc与 C 的 int 类型一样,一般是 int32 或 int 64
intp用于索引的整数类型(类似于 C 的 ssize_t,一般情况下仍然是 int32 或 int64)
int8字节(-128 to 127)
int16整数(-32768 to 32767)
int32整数(-2147483648 to 2147483647)
int64整数(-9223372036854775808 to 9223372036854775807)
uint8无符号整数(0 to 255)
uint16无符号整数(0 to 65535)
uint32无符号整数(0 to 4294967295)
uint64无符号整数(0 to 18446744073709551615)
float_float64 类型的简写
float16半精度浮点数,包括:1 个符号位,5 个指数位,10 个尾数位
float32单精度浮点数,包括:1 个符号位,8 个指数位,23 个尾数位
float64双精度浮点数,包括:1 个符号位,11 个指数位,52 个尾数位
complex_complex128 类型的简写,即 128 位复数
complex64复数,表示双 32 位浮点数(实数部分和虚数部分)
complex128复数,表示双 64 位浮点数(实数部分和虚数部分)
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值