/*********计算linux的对齐长度*********/
int getLinuxAlign(int *lens, int n){
int i=0;
int align = 1;
for(i = 0;i< n;i++){
if(align < 2 && *(lens +i) == 2)
align = 2;
if(align <4 && *(lens +i) >= 4)
align = 4;
}
return align;
}
/*********计算windows的对齐长度*********/
int getWindowsAlign(int *lens, int n){
int i=0;
int align = 1;
for(i = 0;i< n;i++){
if(align < 2 && *(lens +i) == 2)
align = 2;
if(align <4 && *(lens +i) == 4)
align = 4;
if(align <8 && *(lens +i) == 8)
align = 8;
}
return align;
}
/******
递归计算各个变量的数据偏移以及结构体大小
i表示正在处理第i个变量,curAddr表示当前地址
size表示结构体的大小,n表示变量个个数
******/
void getStart(int i,int *curAddr, int *size, int n){
if(i >= n)
return;
start[i] = *curAddr;//第i个变量的首地址为当前地址
*curAddr += lens[i];
*size += lens[i];
if( *curAddr % ALIGN ==0)//当前地址能被对齐长度整除,直接递归处理下一个变量
getStart(i+1,curAddr,size,n);
else{//当前地址不能被对齐长度整除
int blank = ALIGN - (*curAddr % ALIGN);//需要填充的大小
if(i == n-1){//已经是最后一个变量,只需将结构体大小扩充一下
*size += blank;
return;
}else if(lens[i+1] > blank){//下一个变量的大小大于填充大小,填充后,递归处理下一个变量
*curAddr += blank;
*size += blank;
getStart(i+1,curAddr,size,n);
}else{
i++;
while(lens[i] <= blank){//只要下一个变量的大小小于填空空白大小
start[i] = *curAddr;
*curAddr += lens[i];
*size += lens[i];
blank = ALIGN -(*curAddr % ALIGN);
if(i == n-1){
*size += blank;
return ;
}
i++;
}
getStart(i,curAddr,size,n);
}
}
}
void printStart(int n){
int i=0;
for(i=0; i
printf("%s(%d):%d\n",vars[i],lens[i],start[i]);
}
int main(){
int n;
int curAddr = 0;
int size = 0;
n = scanfStruct();
//ALIGN = getLinuxAlign(lens,n);
ALIGN = getWindowsAlign(lens,n);
getStart(0,&curAddr,&size,n);
printf("align:%d\n",ALIGN);
printf("\nsize:%d\n",size);
printStart(n);
return 0;
}
五、排列成员顺序,使得结构体占有存储空间最小