class DownlinkControlField { public: #if defined(__BIG_ENDIAN_BITFIELD) unsigned short res1:2; unsigned short ack:2; unsigned short res2:2; unsigned short dir:1; unsigned short sof:1; unsigned short mf:1; unsigned short packet_type:2; unsigned short transparent:1; #elif defined (__LITTLE_ENDIAN_BITFIELD) unsigned short ack:2; unsigned short res1:2; unsigned short transparent:1; unsigned short packet_type:2; unsigned short mf:1; unsigned short sof:1; unsigned short dir:1; unsigned short res2:2; #endif };
一、大小端
简而言之,大端是高对低,小端是高对高。后来一搜,说是大小端,居然是有个故事的。格列佛游记里一个故事,小人国的领导下了一道命令,规定人民在剥鸡蛋时必须从小的一段(little-end)开始。这规定惹恼了一群觉得应该从大端(big-end)开始剥的人,后来演变成纷争。支持little-end的人称为little-endian,支持big-end的人称为bid-endian。(来自http://bbs.c114.net/viewthread.php?tid=376162)
这样就好理解了,大端就是先放高位,放在低地址,小端就是先放小的,放在低地址。其实老外还是蛮有意思的。关于大小端讲的蛮不错的一篇文章http://my.oschina.net/alphajay/blog/5478?from=rss
大小端定义的头文件,在楼主ubuntu下为/usr/include/linux/typeoders目录下,一个little_endian.h一个big_endian.h;在楼主的vc6头文件中还有一个,C:\Program Files\Microsoft Visual Studio\VC98\Include目录下,endian.h。编译记得加上-D选项,如-D__LITTLE_ENDIAN_BITFIELD
有时候面试题会考到大小端的判断。应用到union的特性:union存储时,所有成员共用一个存储空间;union的存放顺序从低地址开始。于是如果判断cpu是大小端的c程序如下:
/*return 1 : little-endian, return 0:big-endian*/ int checkCPUendian(){ union { unsigned int a; unsigned char b; }c; c.a = 1; return (c.b == 1); }二、位字段
在存储空间宝贵的情况下,有时候需要将多个对象保存在一个机器字中。通常的方法是定义一个与相关位的位置对应的屏蔽码集合,如
#define KEYWORD 01 #define EXTERNAL 02 #define STATIC 04
这样,访问这些位就变味了移位运算、屏蔽运算以及补码运算等。尽管这方法简单可行,不过C语言还提供了另一种可替代的方法,来直接定义和访问一个字中的位字段的能力,不需要按位逻辑运算。
struct bytedata { unsigned a:2; /*位段a,占2位*/ unsigned:6; /*无名位段,占6位,但不能访问*/ unsigned:0; /*无名位段,占0位,表下一位段从下一字边界开始*/ unsigned b:10; /*位段b,占10位*/ int i; /*成员i,从下一字边界开始*/ } data;对于位字段,需要注意以下:
1)一个字段必须存储在同一存储单元(word)中,不能跨越2个单元。如果单元空间不够,则剩余空间不用,从下月单元开始存放。
2)字段的所有属性几乎都有具体实现有关(所以才有如上的大小端下不同 的情况)
3)特殊宽度0可以用来强制在下一个字边界上对齐
4)无名字段(只有一个冒号和宽度)起填充作用(感觉像哑元素?)
5)字段不是数组,且没有地址,所以不能用&符号
6)字段可以仅仅声明为int,为方便移植,需要显式声明该int为signed还是unsigned类型。
7) 位段名不是变量名,比如首先int i:3,再int j:5,并不是在2个单独int中,所以在计算sizeof结构体的时候注意下
以前总觉得好多面试题钻的方向挺诡异的,现在才发现,的确是应用到了一些工程的实践啊,只是敲点小代码玩,的确没这个需求
参考网址:http://www.cnblogs.com/xiaoliyu/archive/2008/11/18/1335711.html