大端法与小端法


一、什么是字节序
字节序,顾名思义字节的顺序,再多说两句就是大于一个字节类型的数据在内存中的存放顺序(一个字节的数据当然就无需谈顺序的问题了)。

高/低地址: 指的是内存的高、低地址,计算机在内存中存放数据的顺序都是从低地址到高地址

高/低字节:有些文章中称低位字节为最低有效位,高位字节为最高有效位。如果我们有一个32位无符号整型0x12345678,那么高位是什么,低位又是什么呢? 其实很简单。在十进制中我们都说靠左边的是高位,靠右边的是低位,在其他进制也是如此。就拿 0x12345678来说,从高位到低位的字节依次是0x12、0x34、0x56和0x78。

第一部分 基本概念

首先不管是大端法还是小端法存储,计算机在内存中存放数据的顺序都是从低地址到高地址,所不同的是首先取低字节的数据存放在低地址还是取高字节数据存放在低地址。

若首先取高字节的数据存放在低地址,则是大端法;

若首先取低字节的数据存放在低地址,则是小端法;

 

例如有数据0x01234567 (注意:左边是高字节,右边是低字节)

大端法存放:

存放的地址依次为:0x0001 0x0002 0x0003 0x0004

对应的数据依次为:0x01   0x23   0x45   0x67

小端法存放:

存放的地址依次为:0x0001 0x0002 0x0003 0x0004

对应的数据依次为:0x67    0x45   0x23   0x01

第二部分 判断一个机器是大端存放还是小端法存放

知道了大端和小端的定义,我们很容易写代码判断一个机器是大端还是小端:

int main(int argc, char* argv[])

{

       union w         

       {   

              int a;             

              char b;

             

       }c;

      

       c.a = 0x0001;

       if(c.b==1)

              printf("small endian\n");

       else if(c.b==0)

              printf("big endian\n");

       else

              printf("error\n");

       return 0;

}

注意:之所以可以这样写来判断是因为共用体中所有成员的存放顺序是从低地址开始的。

下面一个程序也可以来判断机器的字节序:

#include <iostream>
using namespace std;
int main()
{
 int x=0x00001234;//十进制为4660
 char tp=*((char*)&x);//取tp等于x的低地址部分

//char tp=(char)x;这样也是可以的。
 if (tp==0x00)//如果低地址部分取出的值是高字节的值,则为大端
 {
  cout<<tp<<"大端"<<endl;
 }
 else
 if (tp==0x34)//如果低地址部分取出的值是低字节的值,则为小端
 {
  cout<<tp<<"小端"<<endl;//0x34即十进制52,所以输出tp值为4
 }//注:本人电脑小端
 return 0;
}


### C语言中判断大端模式小端模式的方 在C语言中,可以通过编写简单的程序来判断系统的字节序(即大端小端)。以下是几种常见的方: #### 方一:使用指针偏移 这种方利用了`int`类型的整数其最低位字节的关系来进行判断。 ```c #include <stdio.h> int check_endianess() { int a = 1; return *(char *)&a; // 如果返回值为1,则表示系统采用的是小端模式;如果返回值为0,则表示系统采用的是大端模式。 } int main() { int ret = check_endianess(); if (ret == 1) { printf("当前系统为小端模式\n"); } else { printf("当前系统为大端模式\n"); } return 0; } ``` 这段代码定义了一个名为`check_endianess()`的函数[^1]。该函数内部创建了一个整型变量`a`并赋初值为1。接着它将这个整数的第一个字节取出作为结果返回给调用者。由于整数1只占用最右边的一个比特,在小端机器上读取第一个字节会得到非零的结果,而在大端机器上则相反。 #### 方二:联合体 此方借助于C语言中的联合体特性实现对同一块内存区域的不同解释方式。 ```c #include <stdio.h> typedef union { unsigned int num; unsigned char bytes[sizeof(unsigned int)]; } EndianChecker; void detect_endianness() { EndianChecker ec; ec.num = 0x12345678; for(size_t i=0;i<sizeof(ec.bytes);++i){ printf("%02X ",ec.bytes[i]); } puts(""); if (ec.bytes[0] == 0x78 && ec.bytes[1] == 0x56 && ec.bytes[2] == 0x34 && ec.bytes[3] == 0x12) { printf("当前系统为大端模式\n"); } else if (ec.bytes[0] == 0x12 && ec.bytes[1] == 0x34 && ec.bytes[2] == 0x56 && ec.bytes[3] == 0x78) { printf("当前系统为小端模式\n"); } else { printf("无识别的字节顺序\n"); } } int main(){ detect_endianness(); return 0; } ``` 这里定义了一个名为`EndianChecker`的联合体结构,其中包含了两个成员——一个是无符号整数`num`,另一个是指向四个字符数组的指针`bytes[]`。当我们将一个特定值赋予`num`时,我们就可以通过访问`bytes[]`来查看这些数据是如何被排列存储的。根据输出可以很容易地区分出是哪种字节序[^3]。 #### 字节序的概念说明 所谓的大端模式指的是多字节数值按照从最高有效位到最低有效位依次存放在较低地址至较高地址的方向;而小端模式则是反过来,先存放最低有效位再存放更高位置上的字节[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值