从网上看到这样一段c代码,让我发觉我的C基本功还是不行啊~~

 
  
  1. typedef struct xp { 
  2.         int a:2; 
  3.         int b:2; 
  4.         unsigned int c:1; 
  5. } xp; 

   不知道大家对int声明中的这个":"熟悉吗?不过,我刚看到的时候有点懵。在网上查了些资料,才明白这是一种将int按位分配的方法。

   比如:int a:2;表示a为占2位的整数。

   通常的int为4字节,即占用32位的整数。

   同时 按位分配的int,也分有符号和无符号两种,如:

 
  
  1. typedef xp 
  2.     int a:2; 
  3.     unsigned int b:2; 
  4. }MyXp; 
  5.  
  6.  
  7. MyXp x; 
  8. x.a = 3; 
  9. x.b = 3; 

这样,输出的x.a为-1,x.b为3。

   同时,大家看到,这种分配方法是定义在struct中的。如果你在代码中直接定义:int a:2;编译时会导致错误,无法识别“:”。

   这是因为int是内建类型,它不能被改变内存分配的方式。所以单独的int,不能直接被声明为只占2位。

   而在struct中,对整个struct的内存分配,还是遵循c的内存分配方式,但在其中每一个内存位的表示含义,则可以由我们自己说明。如下:

 
  
  1. printf("%d\n"sizeof(x)); 
  2. printf("%d\n",sizeof(x.a)); 

   第一句能返回4,表示MyXp是占用4个字节的,其实其中的多个int,对系统来说只是将一个int截成了不同的段来使用,整个内存分配还是按照一个int来。当然,如果总位数超过了32位,那struct大小会以4字节为单位递增,即struct的大小为4字节、8字节、12字节等。

   而同时,第二句printf编译错误,是因为系统识别不出x.a的类型,因为他不是普通的int类型,系统无法识别x.a占用了2位。

   从内存上看,a和b占用了x的32位中的低4位,高位没有分配的会以0值填充。

   有兴趣的可以看一下运行时的内存分配。struct中的a、b是公用一个int的内存段,如果再添加新的变量,他们也是使用同一个int内存段,直到一个int段不够,则直接再开一个int段供使用。同时,如果反编译这段代码,也能发现,对a、b的赋值和访问和一般的int不同,是通过位操作来进行的。

    注意,共享内存段的只能是在struct中连续声明的按位分配的int变量,如下声明:

 
  
  1. typedef struct xp { 
  2.     int a:3; 
  3.     int b:2; 
  4.     int k; 
  5.     unsigned int c:2; 
  6. } xp; 

    则xp会占用3个int的内存段,因为a、b共享一个int的4字节,k自己单独占用一个int,c则需要开一个新的int内存段使用。而如果将k和c的声明互换,则xp只需要占用2个int的内存段。