《目录》
- 整数的存储方式
- 思考题:大端模式符合计算机处理习惯的原因 ?
- 思考题:如何判断一个系统是低位优先,还是高位优先 ?
- 思考题:如何改变一个整数的存储方式 ?
整数的存储方式
整数的存储,是 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;
}