C/C++结构体的一个高级特性――指定成员的位数

来源:互联网 发布:让人喜欢的女生知乎 编辑:程序博客网 时间:2024/06/06 02:16
在大多数情况下,我们一般这样定义结构体:
struct student
{
       unsigned int sex;
       unsigned int age;
};
对于一般的应用,这已经能很充分地实现数据了的“封装”。
但是,在实际工程中,往往碰到这样的情况:那就是要用一个基本类型变量中的不同的位表示不同的含义。譬如一个cpu内部的标志寄存器,假设为16 bit,而每个bit都可以表达不同的含义,有的表示结果是否为0,有的表示是否越界等等。这个时候我们用什么数据结构来表达这个寄存器呢?
答案还是结构体!
为达到此目的,我们要用到结构体的高级特性,那就是在基本成员变量的后面添加:
数据位数
组成新的结构体:
struct xxx
{
       成员1类型成员1 : 成员1位数;
       成员2类型成员2 : 成员2位数;
       成员3类型成员3 : 成员3位数;
};
基本的成员变量就会被拆分!这个语法在初级编程中很少用到,但是在高级程序设计中不断地被用到!
例如:
struct student
{
       unsigned int sex : 1;
       unsigned int age : 15;
};
上述结构体中的两个成员sex和age加起来只占用了一个unsigned int的空间(假设unsigned int为16位)。
基本成员变量被拆分后,访问的方法仍然和访问没有拆分的情况是一样的,例如:
struct student sweek;
sweek.sex = MALE;
sweek.age = 20;
虽然拆分基本成员变量在语法上是得到支持的,但是并不等于我们想怎么分就怎么分,例如下面的拆分显然是不合理的:
struct student
{
       unsigned int sex : 1;
       unsigned int age : 12;
};
这是因为1+12 = 13,不能再组合成一个基本成员,不能组合成char、int或任何类型,这显然是不能“自圆其说”的。
在拆分基本成员变量的情况下,我们要特别注意数据的存放顺序,这还与CPU是Big endian还是Little endian来决定。Little endian和Big endian是CPU存放数据的两种不同顺序。对于整型、长整型等数据类型,Big endian认为第一个字节是最高位字节(按照从低地址到高地址的顺序存放数据的高位字节到低位字节);而Little endian则相反,它认为第一个字节是最低位字节(按照从低地址到高地址的顺序存放数据的低位字节到高位字节)。
我们定义IP包头结构体为:
struct iphdr {
#if defined(__LITTLE_ENDIAN_BITFIELD)
       __u8       ihl:4,
              version:4;
#elif defined (__BIG_ENDIAN_BITFIELD)
       __u8       version:4,
            ihl:4;
#else
#error       "Please fix <asm/byteorder.h>"
#endif
       __u8       tos;
       __u16       tot_len;
       __u16       id;
       __u16       frag_off;
       __u8       ttl;
       __u8       protocol;
       __u16       check;
       __u32       saddr;
       __u32       daddr;
       /*The options start here. */
};
在Little endian模式下,iphdr中定义:
       __u8       ihl:4,
              version:4;
其存放方式为:
第1字节低4位 ihl
第1字节高4位 version (IP的版本号)
若在Big endian模式下还这样定义,则存放方式为:
第1字节低4位 version (IP的版本号)
第1字节高4位 ihl
这与实际的IP协议是不匹配的,所以在Linux内核源代码中,IP包头结构体的定义利用了宏:
#if defined(__LITTLE_ENDIAN_BITFIELD)
#elif defined (__BIG_ENDIAN_BITFIELD)
#endif
来区分两种不同的情况。
由此我们总结全文的主要观点:
(1)       C/C++语言的结构体支持对其中的基本成员变量按位拆分;
(2)       拆分的位数应该是合乎逻辑的,应仍然可以组合为基本成员变量;

要特别注意拆分后的数据的存放顺序,这一点要结合具体的CPU的结构。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 退款申请关闭了怎么办 公众号图片侵权怎么办 qq没法发语音怎么办 139邮箱换号怎么办 qq号显示手机号怎么办 运动鞋大了怎么办妙招 鞋买小了挤脚怎么办 鞋子买太大了怎么办 买了nike betrue怎么办 手表蹭花了怎么办 迅雷登录太频繁怎么办 糖果手机声音小怎么办 产品出现了问题怎么办 插头螺丝太紧怎么办 宜家儿童乐园怎么办卡 泰国旅游有蚊子怎么办 啦泰国旅游拉肚子怎么办 电动车上不了牌怎么办 电动车电压低了怎么办 电车显示器不亮怎么办 电动车故障显示m怎么办 电动车上面出现m怎么办 佰仟乐购额度没有了怎么办 交易密码忘记了怎么办? 电脑打开没网怎么办 网络配适器无法运行怎么办 电脑dns没有响应怎么办 win7系统没有网上邻居怎么办 win10网络重置了怎么办 win7桌面没有网上邻居怎么办 win7电脑没有网上邻居怎么办 无线网连接受限怎么办 win7账户被锁定怎么办 贷款sdk授权失败怎么办 京东保价发票怎么办 淘宝购物出现质量问题怎么办 淘宝购物降价了怎么办 淘宝购物物流慢怎么办 在淘宝购物退货怎么办 淘宝购物未付款怎么办 淘宝购物余额不足怎么办