《目录

  • 整数的存储方式
  • 思考题:大端模式符合计算机处理习惯的原因 ?
  • 思考题:如何判断一个系统是低位优先,还是高位优先 ?
  • 思考题:如何改变一个整数的存储方式 ?

整数的存储方式

整数的存储,是 CPU 决定,分为:

  • 大端(Big Endian),   低位字节存储在高地址, 又名高位优先.(计算机习惯)
  • 小端(Little Endian), 低位字节存储在低地址, 又名低位优先.(人类习惯)

如图所示:

整数的存储方式_小端模式

 

这俩种存储方式本身无区别,如同一些人是用右手写字,另一些人用左手写字,看个人习惯......

大端模式符合计算机处理习惯的原因 ?

 

思考题:大端模式符合计算机处理习惯的原因 ?

大端模式符合计算机处理习惯的原因 ?

  • 不需要考虑对应关系,
  • 按照字节, 把数据从左到右,
  • 按由低到高地址顺序直接读写,
  • 一般用于网络字节序. 各种编解码。

 

网络传输整数时(又名网络字节序),机器会调用 htons() 函数把整数转换为大端,也就是说网络传输是高位优先;而当数据传输到本地计算机时,系统会调用 ntohs() 函数把网络字节序转换为本机的存储方式(又名本机字节序)。

我们的 PC 机上使用的是 X86 结构的 CPU,是小端模式;51 单片机是大端模式;很多 ARM、DSP 也是小端模式(部分 ARM 处理器还可以由硬件来选择是大端模式还是小端模式)。

那如何判断一个系统是低位优先,还是高位优先呢 ?

 


思考题:如何判断一个系统是低位优先,还是高位优先 ?

      想一想,如何判断一个系统是低位优先,还是高位优先呢 ?

// 方法零
int main(){
   int a = 0x00 00 00 01;   //大卡车
   char b;                  //小卡车
   b = a;                   //小卡车只能装大卡车的四分之一。
      if( b == 0x1) 
         printf("%s\n","Little endian");
      else
         printf("%s\n","Big endian");
}

      

// 方法一:用指针
#include<iostream>
using namespace std;

bool judge_integer_storage(void) 
{
    int q = 0x1;  //0x 00 00 00 01
    //数学上,取一个适合计算的值很重要。
    char *p = (char *)&q; // *p指向低地址
    if ( 1 == *p )        // 低地址中是低字节
        return true; 
    else 
        return false; 
}

int main(void)
{
	if ( judge_integer_storage( ) )
	cout<<"Little Endian"<<endl;
	else
	cout<<"Big Endian"<<endl;
}

 

// 方法二:共用体
#include <stdio.h>
int main(){
    union{
        int n;
        char ch;
    } data;
    data.n = 0x1; 
     //可以直接写data.n = 1;
    if(data.ch == 1){
        printf("Little-endian\n");
    }else{
        printf("Big-endian\n");
    }
    return 0;
}

共用体的各个成员是共用一段内存的。

    1 是数据的低位,如果 1 被存储在 data 的低字节,就是小端模式,这个时候 data.ch 的值也是 1。

    如果 1 被存储在 data 的高字节,就是大端模式,这个时候 data.ch 的值就是 0.

   

我知道的还有一种呢,方法三:共用体指针,您可以试一下。

在机器传送时,如何改变一个整数的存储方式,即低位优先<-->高位优先 ?

 


思考题:如何改变一个整数的存储方式 ?

     在机器传送时,如何改变一个整数的存储方式,即低位优先<-->高位优先 ?

// 用宏实现16Bit大小端数据转换,32 位的也类似~
#define swap_endian_u16(A) ((A & 0xFF00>>8) | (A & 0x00FF<<8))

 

// 设计算法
int change_int_storage(int val) 
{ 
    int iRun = 0, i = 0; 
    char* pByte= (char*)&val; //指向整数的低地址,取一个字节
    i = sizeof(int)-1; 
    while (i >= 0) 
    { 
        iRun |= *pByte<<(i*8);//把整数的第1字节,第2字节,第3字节,第四4字节一次左移24位,16位,8位和0位 
        pByte++;//前进一个字节
        i--;
     } 
    return iRun; 
}