我们都知道,内存中存储的是各种变量,各种奇葩东西,不用的变量占用不用的字长,例如在intel X86环境下,一个int占用两个字
节,即16位。然后在这16位上用0或1来表示这个int类型的变量到底是什么数值。那么这样就有两种写法了,在这16位上是从左往右写呢,还是从右往左写呢。这就好比现代人写字从左往右,古人写字从右往左。根据这样两种不同的写法,计算机中就产生了两种模式:小端模式和大端模式。具体来看一个例子:
假设在intel X86环境下,有一个数字,是1539,用二进制就表示为:0000 0110 0000 0011(两个字节)
既然计算机以字节为单位,如果这里的一个字节相当于写一个汉字的话,那这个1539在计算机内部就相当于要写两个汉字。怎么写呢,不着急,先介绍
小端模式:按照从低地址到高地址的顺序,依次存放数据的低字节到高字节。
插入一句:一个数的原数,是高字节在左,低字节在右,当然是这样,因为左边的权值高,2的次方高。学习本篇的时候,要始终记住吧一个个字节作为一个个单位,而不要着眼于位。
我这里高八位标在左边,低八位标在右边,很多地方低八位标左,高八位标右,这个其实是完全一样的,怎么看得舒服就怎么写。
按照定义,低地址放低字节,高地址放高字节,所以低八位放1539的低字节,高八位放1539的高字节。
接下来是 大端模式:按照从低地址到高地址的顺序,依次存放数据的高字节到低字节。
现在再回头看看,不过就是正着写反着写而已。╮(╯_╰)╭
一般来说,x86 系列 CPU 都是小端模式的字节序,PowerPC 通常是大端模式字节序,还有的CPU能通过跳线来设置CPU工作于小端模式还是大端模式模式。基本上要考察都是intel x86 x64环境,都是小端模式,不会那么坑考冷门的大端模式。。
练习:
0x1234abcd
低地址 高地址
小端模式:0xcd 0xab 0x34 0x12
大端模式:0x12 0x34 0xab 0xcd
写出下列程序的执行结果
int *p = (int*)sz; 这句话的意思是说把这块内存当做int来对待。可以这样理解,数据就在内存中摆着,就看你当成什么来用了。
不管32位还是64位,int都占四个字节,printf那边有个++p,这个p是int型的指针,所以按照int的大小走四个字节
即现在p指向的是:
这块内存区域。还记得吗,用的是小端模式,那这个int变量该怎么写?
很明显是:0x37363534(低地址存低字节)
所以用%X输出的话就看到了37363534这个结果了。
写出下列程序执行结果
判断计算机是大端还是小端:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
0x30 | 0x31 | 0x32 | 0x33 | 0x34 | 0x35 | 0x36 | 0x37 | 0x38 | 0x39 |
假设在intel X86环境下,有一个数字,是1539,用二进制就表示为:0000 0110 0000 0011(两个字节)
高八位 | 低八位 |
0000 0110 | 0000 0011 |
高八位 | 低八位 | |
小端模式: | 0000 0110 | 0000 0011 |
插入一句:一个数的原数,是高字节在左,低字节在右,当然是这样,因为左边的权值高,2的次方高。学习本篇的时候,要始终记住吧一个个字节作为一个个单位,而不要着眼于位。
我这里高八位标在左边,低八位标在右边,很多地方低八位标左,高八位标右,这个其实是完全一样的,怎么看得舒服就怎么写。
按照定义,低地址放低字节,高地址放高字节,所以低八位放1539的低字节,高八位放1539的高字节。
接下来是 大端模式:按照从低地址到高地址的顺序,依次存放数据的高字节到低字节。
高八位 | 低八位 | |
大端模式: | 0000 0011 | 0000 0110 |
一般来说,x86 系列 CPU 都是小端模式的字节序,PowerPC 通常是大端模式字节序,还有的CPU能通过跳线来设置CPU工作于小端模式还是大端模式模式。基本上要考察都是intel x86 x64环境,都是小端模式,不会那么坑考冷门的大端模式。。
练习:
0x1234abcd
低地址 高地址
小端模式:0xcd 0xab 0x34 0x12
大端模式:0x12 0x34 0xab 0xcd
写出下列程序的执行结果
#include<stdio.h>答案是37363534
main()
{
char *sz = "0123456789";
int *p = (int*)sz;
printf("%x\n",*++p);
}
'0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' |
0x30 | 0x31 | 0x32 | 0x33 | 0x34 | 0x35 | 0x36 | 0x37 | 0x38 | 0x39 |
不管32位还是64位,int都占四个字节,printf那边有个++p,这个p是int型的指针,所以按照int的大小走四个字节
即现在p指向的是:
'0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' |
0x30 | 0x31 | 0x32 | 0x33 | 0x34 | 0x35 | 0x36 | 0x37 | 0x38 | 0x39 |
很明显是:0x37363534(低地址存低字节)
所以用%X输出的话就看到了37363534这个结果了。
写出下列程序执行结果
int a = 0x12345678;答案是0x56
char *p = (char*)(&a);
printf("%x\n",*(p+1));
判断计算机是大端还是小端:
int i=1;
char *p=(char *)&i;
if(*p==1)
printf("小端模式");
else // (*p == 0)
printf("大端模式");