C细节:内存方面
栈上分配空间时的地址数值从大向小变化。
当int i(一般的)被分配4字节空间,那么变量所占内存空间的首地址——通常简称变量的地址,是最小的地址。假定32位的i分配为2000、2001、2002、2003地址,2000即为i的地址。很多书上画示意图的时候,把地址数值从小向大变化,以及将i的最高字节的地址作为首地址,是不是有点想当然。
例子:假定我们用int打包4个字符(位域处理),在big-endian机器上,在最低地址先存储高字节数据。i由javz构成,则分别分配为2000(存放j)、2001(存放a)、2002、2003地址。小端(little-endian)时&i地址编号2000保存的是(z)。
big endian是指低地址存放最高有效字节(MSB),而little endian则是低地址存放最低有效字节(LSB)。
x86系列采用little endian方式
[cpp]
void headP(void){
char j='J',a='a',v='v'/*,a2='z'*/;//对齐
printf("%p %p %p \n",&j,&a,&v);
unsigned int i=0;
i+=(j<<24)+(a<<16)+(v<<8);
printf("%p \n",&i);
char a2='z';//填空
i+=a2;
printf("%p \n",&a2);
char* cp=(char*)(&i);
printf("%p \n",(void*)(&cp));
*(cp+3)='j';
printf("%c%c%c%c\n",*cp,*(cp+1),*(cp+2),*(cp+3));//指向最后字节
printf("%c%c%c%c\n",*(cp+4),*(cp+5),*(cp+6),*(cp+7));
}
void headP(void){
char j='J',a='a',v='v'/*,a2='z'*/;//对齐
printf("%p %p %p \n",&j,&a,&v);
unsigned int i=0;
i+=(j<<24)+(a<<16)+(v<<8);
printf("%p \n",&i);
char a2='z';//填空
i+=a2;
printf("%p \n",&a2);
char* cp=(char*)(&i);
printf("%p \n",(void*)(&cp));
*(cp+3)='j';
printf("%c%c%c%c\n",*cp,*(cp+1),*(cp+2),*(cp+3));//指向最后字节
printf("%c%c%c%c\n",*(cp+4),*(cp+5),*(cp+6),*(cp+7));
}
输出:
0012ff83 0012ff82 0012ff81
0012ff7c
0012ff80
0012ff78
zvaj
zvaJ
内存对齐和分配顺序
例如例程中,大体按照程序文本顺序分配空间;对于char之外的数据类型,通常按字对齐。如果例程中修改为
[cpp] view plaincopyprint?char a2='z',c='c';//填空
char a2='z',c='c';//填空这时a2填空,但是c在i之前分配空间。
虽然可以测试,但是我不能够确定在其他情况下是否正确。
补充:软件开发 , C语言 ,