大端小端及其union的练习题

看了这个例子,一定会有这样的疑问:应该是00 00 00 01,为什么会是这样的

vs2013是小端存储,下面的这个图从左到右地址是由低到高。

比如0x11223344在大端机上是11223344,在小端机上是44332211。

大端:低地址存高位

小端:低地址存低位 (小弟弟)

先来说清楚,32位内存地址的,虽然我们在看一个二进制数的时候比如01111011,是从后往前看的,这样看来从左到右是高地址到低地址,而在内存中,一般是由低地址到高地址的,可以看下面的这个图:

左边的0x0000000E从上到下是从小到大的,所以看存储的一个数在大端机上的是怎么样的,在小端机上是怎么样的。反正从左到右是低地址到高地址。

上面说的高位低位指的是权重,比如说1234这个数字,1的权重是千,1就是高位,高低位是相对的。

位指的是权重

如何判断数据的高位与低位因为位指的是权重,那么比如说1234这个数字,1的权重是千,1就是高位,高低位是相对的。

比如对于11223344来说,他的最低位就是4,最高位就是1,则在大端机器上是11223344,在小端机器上是44332211

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

#include<iostream> using namespace std;

union Un { short a;//2 char b;//实际对齐数是1 }un;//总体对齐数是2

int main() { char p[] = {2,1}; Un*n = (Un*)p;//这个是将p指针扩充为Un大小的(为两个子节),所以是 printf("%d,%d ",n->a,n->b);

return 0;

}

#include<iostream> using namespace std;

union Un { short a;//对齐数是2 char b;// 对齐数是1 }un;//总体对齐数是2

int main() {

char p[] = {2,1};//00000010,0000 0001 Un*n = (Un*)p;//扩充为两个字节的,,这样识别的16位就是一个数,这个其实是将char 数组里的赋值给联合体里的变量。 //00000010 00000001 //如果是小端机器,说明将 printf("%d,%d ",n->a,n->b);//联合体,所以a和b共用一块内存,所以是,所以用n指针去访问肯定是0000 0001 0000 0010。因为输出是%d,也就是4个子节,所以不用截断, //也就是258 而后面的b是一个字节,所以是需要截断的,所以是0000 0001 0000 0010的后八位,所以是2 //这个的之所以没有覆盖是因为,他实际访问的是p指向的那块内存,而不是通过赋值,所以是不会覆盖的

// 0000 0000 0000 0000 0000 0000 0000 0000 0000 0010

/* un.a = 1, un.b = 2; //0000 0001 0000 0010。 printf("%d,%d ", un.a, un.b);//输出为%d,是int类型的。所以肯定是2,然后将其扩充为4个子节 */ return 0;

}

经验分享 程序员 微信小程序 职场和发展