#include<stdio.h>typedef struct u{ char a; int b;}U1;int main(){ PRintf("%d/n",sizeof(U1)); return 0;}假设U1按如下方式内存方式布局(内存地址从左至右递增):因为U1中有最强对齐要求的是b字段(int),所以U1对象的首地址一定是4的倍数,那么上述内存的布局中的b字段能满足int类型的对齐要求吗?显然是不能的,于是有了如下的地址分配方案:
这个方案在a与b之间多分配了3个填充(padding)字节,这样当整个struct对象首地址满足4字节的对齐要求时,b字段也一定能满足int型的4字节对齐规定。那么sizeof(U1)显然就应该是8,而b字段相对于结构体首地址的便宜就是4。我们看一下程序给的结果吧:
那么下面这个呢?typedef struct u2{ int a; char b;}U2;其实和上例子是一样的,sizeof(U2)也是8。好的,现在你已经掌握了结构体内存布局的基本准则,尝试分析一个稍微复杂点的类型吧。例如:
typedef struct u{ char a[9]; int b; double d;}U1; 先来分析一下,a占9字节,b占4字节,d占8字节,这里最"宽"的变量是a,因此内存大小至少是9。像上面的例子一样,U1的地址最前面是9个字节,然后在a和b之间多分配了3个填充(padding)字节,在然后是b的4个字节,最后是d的8个字节。sizeof(U1)=24。看看程序运行的结果吧:#include<stdio.h>typedef struct u{ char a[9]; int b; double d;}U1;int main(){ printf("%d/n",sizeof(U1)); return 0;}下面来个有关union使用的测试程序加深理解:
#include<stdio.h>union un{ int i; short int si[2]; char c[4];}u;int main(){ u.c[0]='A'; u.c[1]='B'; u.c[2]='C'; u.c[3]='D'; printf("u.c[0]=%d,u.c[1]=%d,u.c[2]=%d,u.c[3]=%d/n",u.c[0],u.c[1],u.c[2],u.c[3]); printf("u.si[0]=%d,u.si[1]=%d/n",u.si[0],u.si[1]); printf("u.i=%d/n",u.i); return 0;}程序运行结果如下:在程序中,由于联合体的特点,变量x占4个字节。我们可以从3个角度观察这4个字节:(1)整体看,是一个int型数据;(2)分成2部分看,是两个短整型数据;(3)分成4部分看,是4个单字节的数据。但无论怎么看,就是这4个字节。无论用哪种形式操作数据,使用的也就是这4个字节。联合体为我们提供了从不同的角度使用这4个字节的方式。x.c[0]到x.c[3]的值分别为65/66/67/68,这好理解。x,si[0]占2字节,与x.c[0]和x.c[1]相同。验证一下:16961=66*256+65(66是'B'的ASCII值,65是'A'的ASCII值,是字符的存储形式)。注意,这里体现存储数据时低位在前,高位在后,低位是65,高位时66。正如十进制数98,高位时9,低位是8,所以98=9*10+8一样。因为是高位,所以乘以权位10,表示9这个符号代表的其实是90。66*256,因为存储66('B')的那一个字节的位置,比存储65('A')的那一字节的位置高8位,所以乘以2的8次方,即256。 概括讲,存储2字节的16961时,其低8位,是65,在前(x.c[0]),而其高8位,是66,在(x.c[1])。低位在前,高位在后。 请自行验证:17475=68*256+67,提现低位在前,高位在后。(x.si[1]占2字节,与x.c[2]和x.c[3]相同)。 再请验证:1145258561=17475*256*256+16961,也体现在低位在前,高位在后。(x.i占4字节,与x.si[0]和x.si[1]相同)。 再请验证:1145258561=68*256*256*256+67*256*256+66*256+65。同样的道理。
新闻热点
疑难解答