C/C++位域之我见
来源:优易学  2011-12-26 11:35:11   【优易学:中国教育考试门户网】   资料下载   IT书店

  <小端>
  那么输出是什么?
  换一下:
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  int main(int argc, char** argv)
  {
  union
  {
  struct
  {
  char a:1;
  char b:2;
  char c:3;
  }d;
  char e;
  } f;
  f.e = 1;
  printf("%d\n",f.d.a);
  return 0;
  }
  输出又是什么?
  小端的话,那么,再d.a上面分得1,而这个是无符号的char,那么前者输出是1,没有问题,第二个输出是-1。
  为什么?
  第二个是无符号的,就一个位分得1,那么就是最高位分得1,就是负数,负数用的补码,实际的值是取反加1,就是0+1=1,再取符号负数,就是-1.
  整型提升
  最后的打印是用的%d,那么就是对应的int的打印,这里的位域肯定要提升,这里有一点,不管是提升到有符号还是无符号,都是自己的符号位来补充,而不改变值的大小(这里说的不改变值大小是用相同的符号属性来读取),负数前面都补充1,正数都是用0来补充,而且也只有这样才能保证值不变,比如,char提升到int就是前面补充24个char的最高位,比如:
  char c = 0xf0;
  int p = c;
  printf("%d %d\n",c,p);
  输出:-16 -16
  p实际上就是0xfffffff0,是负数因此就是取反加1得到
  c是一个负数那么转化到x的时候就是最高位都用1来代替,得到的数不会改变值大小的。
  再看:
  char c = 0xf0;
  unsigned int x = c;
  printf("%u\n",x);
  得到的结果是4294967280,也就是0xfffffff0,记住,无符号用%u来打印。
  地址不可取
  最后说的一点就是位域是一个字节单元里面的一段,是没有地址的!
  附录
  最后附上《The C Book》这本书的一段说法:
  While we’re on the subject of structures, we might as well look at bitfields. They can only be declared inside a
  structure or a union, and allow you to specify some very small objects of a given number of bits in length. Their
  usefulness is limited and they aren’t seen in many programs, but we’ll deal with them anyway. This example should
  help to make things clear:
  struct {
  /* field 4 bits wide */
  unsigned field1 :4;
  /*
  * unnamed 3 bit field
  * unnamed fields allow for padding
  */
  unsigned :3;
  /*
  * one-bit field
  * can only be 0 or -1 in two’s complement!
  */
  signed field2 :1;
  /* align next field on a storage unit */
  unsigned :0;
  unsigned field3 :6;
  }full_of_fields;
  Each field is accessed and manipulated as if it were an ordinary member of a structure. The keywords signed and
  unsigned mean what you would expect, except that it is interesting to note that a 1-bit signed field on a two’s
  complement machine can only take the values 0 or -1. The declarations are permitted to include the const and
  volatile qualifiers.
  The main use of bitfields is either to allow tight packing of data or to be able to specify the fields within some
  externally produced data files. C gives no guarantee of the ordering of fields within machine words, so if you do
  use them for the latter reason, you program will not only be non-portable, it will be compiler-dependent too. The
  Standard says that fields are packed into ‘storage units’, which are typically machine words. The packing order, and
  whether or not a bitfield may cross a storage unit boundary, are implementation defined. To force alignment to a
  storage unit boundary, a zero width field is used before the one that you want to have aligned.
  Be careful using them. It can require a surprising amount of run-time code to manipulate these things and you can
  end up using more space than they save.
  Bit fields do not have addresses—you can’t have pointers to them or arrays of them.

上一页  [1] [2] [3] 

责任编辑:小草

文章搜索:
 相关文章
热点资讯
资讯快报
热门课程培训