二级考试C++基础:C/C++位域之我见

发布时间:2011-08-29 共3页

  很早想说说这个问题了,经常也会有很多公司拿位域出来考人,呵呵要真的想弄清楚还要一点点的分析。
  这里先看看网宿的一道笔试题目:
  //假设硬件平台是intel x86(little endian)
  char *inet_ntoa(uint32_t in)
  {
  static char b[18];
  register char *p;
  p = (char *)in;
  #define UC(b) (((int)b)&0xff)
  (void) snprintf(b, sizeof(b),
  "%d. %d. %d", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]));
  return (b);
  }
  int main()
  {
  printf("%s, %s", inet_ntoa(0x12345678), inet_ntoa(87654321));
  }
  有点难度的一道题目,其实理解的也很简单。
  位域分析
  位域是c++和c里面都有的一个概念,但是位域有一点要注意的有很多问题我们一样样的看:
  大端和小端字节序
  这个很简单,就是起始点该怎么确定。
  先看一个程序:
  union {
  struct
  {
  unsigned char a1:2;
  unsigned char a2:3;
  unsigned char a3:3;
  }x;
  unsigned char b;
  }d;
  int main(int argc, char* argv[])
  {
  d.b = 100;
  return 0;
  }
  那么x的a1,a2,a3该怎么分配值,100的二进制是:0110 0100,那么a1到a3是不是就是依次取值恩?
  不是!
  我们先看看100分配位的低端是左边的0还是右边的0?很明显是右边的0,那么我们再看a1到a3的分配是从低端到高端的
  那么,对应的应该是
  <<<<<<--内存增大
  a3 a2 a1
  011 001 00
  内存增大之所以这么写是因为,011是在高位!
  而不是通常认为的的:
  a1 a2 a3
  011 001 00
  还有一个情况多见就是一个二进制的数字转化为点分十进制数值,如何进行,这里涉及到大端还是小端的问题,上面没有涉及,主要是因为上面是一个字节,没有这个问题,多个字节就有大端和小端的问题了,如下:
  int main(int argc, char* argv[])
  {
  int a = 0x12345678;
  char *p = (char *)&a;
  char str[20];
  sprintf(str,"%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
  printf(str);
  return 0;
  }
  这个程序假设是小端字节序,那么结果是什么?
  我们看看应该怎么放置呢?
  每个字节8位,0x12345678分成4个字节,就是从高位字节到低位字节:12,34,56,78,那么这里该怎么放?如下:
  ---->>>>>>内存增大
  78 56 34 12
  因为这个是小端,那么小内存对应低位字节,就是上面的结构。

百分百考试网 考试宝典

立即免费试用