大端小端

由于某个问题,最近突然联想到大端小端问题,时间久远,记忆有点模糊,所以又重新翻看了一下,做个记录,内容大都来源伟大的互联网。。。。。。

1.  大端小端概念

  大端小端其实是我们通俗意义上的叫法,实际上指的是计算机存储字节的顺序模式,根据数据在内存中的存储方式分为两种大端字节序模式和小端字节序模式

      大端字节序模式:是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中。符合我们的阅读习惯。

      小端字节序模式:是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中。这个比较符合逻辑思维习惯,高对高,低对低。

      直观见下图:(图片来源网络)

    记忆:----高尾端:尾端在高位,低尾端:尾端在地位--- 

2.  使用场景

    一般网络上的数据都是以大端数据模式进行交互的,而我们的主机大多数是以小端数据模式进行处理,所以在做网络通信的时候,往往需要进行转换。

    曾经就遇到过socket通信时两边对发二进制结构体,然后读出来的数据非常奇怪,查询下来发现是字节序问题。

    socket编程,下面的函数应该不会陌生

    htons()、htonl()分别将16位、32位主机数据转换为网络字节序,也称为大端字节序

    ntohs()、ntohl()则分别将16位、32位网络字节序转换为主机数据。

3.  编写程序判断大小端(面试中偶尔会遇到)

        1.  直接强转,匹配对应内存地址的值,简单明了。

-rwxr-xr-x1 rtmpteststaff     8432 Nov 16 09:37 test

-rw-r--r--1 rtmpteststaff      267 Nov 15 16:45 test.c

ch71mlp000277:~ rtmptest$ cat test.c 

#include <stdio.h>

int main(){

   int i = 0x12345678;

   char *c =(char *)&i;

   if(c[0] == 0x12 && c[1] == 0x34 && c[2] == 0x56 && c[3] == 0x78){

       printf("Big-Endian Mode\n");

   }

   else{

       printf("Little-Endian Mode\n");

   }

   return 0;

}

ch71mlp000277:~ rtmptest$ gcc -o test test.c 

ch71mlp000277:~ rtmptest$ ./test 

Little-Endian Mode

ch71mlp000277:~ rtmptest$ 

2. 通过联合体共用起始地址特性,来匹配对应的值。

#include <stdio.h>

typedef union{

   unsigned short a;

   unsigned char b[2];

}u_data;

int main(){

  u_data data;

  data.a = 0x1234;

  //union data struct: a&b own the same 2 bytes address.

  //b[0] is a's lower address

  //b[1] is a's higher address.

  if(data.b[0] == 0x12 && data.b[1] == 0x34) {

     printf("Big-Endian Mode\n");

  }

  else  {

     printf("Little-Endian Mode\n");

  }

  printf("b[0]=0x%x,b[1]=0x%x\n",data.b[0],data.b[1]);

  return 0;

}

ch71mlp000277:~ rtmptest$ gcc -o test1 test1.c 

ch71mlp000277:~ rtmptest$ ./test1

Little-Endian Mode

b[0]=0x34,b[1]=0x12

ch71mlp000277:~ rtmptest$ 

4. 为什么会有大小端模式之分呢?

  内容摘自:https://bbs.csdn.net/topics/390968161

       这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为 8bit。但是在C语言中除了8bit的char之外,还有16bit的short型,32bit的long型(要看具体的编译器)另外,对于位数大于 8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如何将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式

例如一个16bit的short型x,在内存中的地址为0x0010,x的值为0x1122,那么0x11为高字节,0x22为低字节。对于 大端模式,就将0x11放在低地址中,即0x0010中,0x22放在高地址中,即0x0011中。小端模式,刚好相反。我们常用的X86结构是小端模式,而KEIL C51则为大端模式。很多的ARM,DSP都为小端模式。有些ARM处理器还可以由硬件来选择是大端模式还是小端模式。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 大端: 小端:数据的 低 位保存在内存的低地址中,数据的 高 位保存在内存的高地址中。 上面是大小端的定义。定义总...
    河小龙阅读 4,196评论 0 4
  • 简介 在几乎所有的机器上,多字节对象都被存储为连续的字节序列。例如在C语言中,一个类型为int的变量x地址为0x1...
    啤酒找尿布阅读 5,655评论 0 2
  • 字节对齐 C语言字节对齐C语言字节对齐/7213465 大端小端 字节序(大小端)详解从高低地址和高低位开始理解(...
    杰米阅读 5,883评论 2 4
  • 夏天,一年中最适合减肥的季节。这个激情四射的季节不但能让你排汗解毒, 还盛产一种减肥神器:西瓜。 西瓜中的胺机酸,...
    瘦朵朵减肥健身馆阅读 2,405评论 0 1
  • 0809碎碎念100/7 看见玩具走不动路,是否是小孩子的通病了,想想自己小时候,或者现在,看到喜欢的商品也都会停...
    王彩琼阅读 1,382评论 0 0

友情链接更多精彩内容