C语言的struct的数据成员对齐(三)

2014-02-08 12:43:14 · 作者: · 浏览: 298

 

  /*********计算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;

  }

  五、排列成员顺序,使得结构体占有存储空间最小