linux kernel的一些写法

  #include   <stdlib.h>  
  #include   <stdio.h>  
  #include<string.h>  
  struct   tt{  
          int   num;  
          char   *str;  
  };  
  struct   cc{  
          int   i;  
          char   cstr[0];  
  };  
  main(){  
          struct   tt   mytt;  
          struct   tt   *myp,*myp1;  
          struct   cc   *cp;  
           
        cp=(struct   cc   *)malloc(sizeof(struct   cc)+sizeof(struct   tt));  
          memset(cp->cstr,   0,   sizeof(struct   tt));  
          myp   =   (struct   tt*)cp->cstr;

//这里没有用malloc来初始化myp,而是用cp->cstr,这样一举两得,既初始了myp,又让myp指向了cp->str  
//如果这时还有一个myp1,则可以用cp->cstr去初始化myp1,这时myp1就可以共享myp中的数据  
          myp->num=20;  
          myp->str="hello";  
          myp1   =   (struct   tt*)cp->cstr;//用这种方法让myp1指向myp中的数据  
  //问题就在这个地方,如果写成myp1=myp的话,也同样可以达到同样的效果呀,请问这里为什么要这样写  
        printf("num:%d,%s/n",myp1->num,myp1->str);  
  }

 

 

char   cstr[0];  
  这种写法是以前C程序员常用的一种trick,主要用于支持变长数组或者变长数据结构  
   
  当这样写时  
  struct   cc{  
          int   i;  
          char   cstr[0];  
  };  
  cstr不占空间,即sizeof(cstr)为0,sizeof(cc)为4。但cstr的地址却是有效的,为   (char*)&cc   +   sizeof(i);  
  这样后面就可以接任意数据,而通过cstr得到的就是后面数据的起始地址  
  同样,cstr的类型换成int等也未尝不可,反正它都不占内存,其作用仅仅是便于得到后面数据的起始地址  
   
  血精灵提到用void   *p,这是不一样的,因为p为指针,将占用4个字节的空间(32位系统中) 

你可能感兴趣的:(数据结构,c,linux,struct,include)