为了账号安全,请及时绑定邮箱和手机立即绑定

用C语言进行位域操作

用C语言进行位域操作

C
开心每一天1111 2019-12-21 11:17:18
在C中测试和设置单个整数的经典问题可能是最常见的中级编程技能之一。您可以设置和测试简单的位掩码,例如unsigned int mask = 1<<11;if (value & mask) {....} // Test for the bitvalue |= mask;    // set the bitvalue &= ~mask;   // clear the bit一篇有趣的博客文章认为这是容易出错的,难以维护的并且是错误的做法。C语言本身提供了类型安全和可移植的位级别访问:typedef unsigned int boolean_t;#define FALSE 0#define TRUE !FALSEtypedef union {        struct {                boolean_t user:1;                boolean_t zero:1;                boolean_t force:1;                int :28;                /* unused */                boolean_t compat:1;     /* bit 31 */        };        int raw;} flags_t;intcreate_object(flags_t flags){        boolean_t is_compat = flags.compat;        if (is_compat)                flags.force = FALSE;        if (flags.force) {                [...]        }        [...]}但这让我畏缩了。我和我的同事对此颇有意思的争论仍未解决。两种样式都可以使用,并且我认为经典的位掩码方法简单,安全且清晰。我的同事都认为这是普通且容易的,但是位域联合方法值得用额外的几行内容来使其变得更加便携和安全。双方还有其他论点吗?特别是可能存在字节序方法可能遗漏但可能采用字节序的错误,但结构方法是否安全?
查看完整描述

3 回答

?
心有法竹

TA贡献1866条经验 获得超5个赞

位域并不像您想象的那样可移植,因为“ C不能保证机器字内的字段顺序”(The C book)


忽略这一点,正确使用任何一种方法都是安全的。两种方法都允许符号访问整数变量。您可以争辩说,位域方法更易于编写,但也意味着需要查看更多代码。


查看完整回答
反对 回复 2019-12-21
?
胡子哥哥

TA贡献1825条经验 获得超6个赞

如果问题在于设置和清除位容易出错,那么正确的做法是编写函数或宏以确保正确执行。


// off the top of my head

#define SET_BIT(val, bitIndex) val |= (1 << bitIndex)

#define CLEAR_BIT(val, bitIndex) val &= ~(1 << bitIndex)

#define TOGGLE_BIT(val, bitIndex) val ^= (1 << bitIndex)

#define BIT_IS_SET(val, bitIndex) (val & (1 << bitIndex)) 

如果您不介意val必须是左值(除BIT_IS_SET以外),这将使代码可读。如果那不能使您满意,那么您可以取出作业,用括号括起来并用作val = SET_BIT(val,someIndex); 这将是等效的。


确实,答案是考虑将您想要的东西与想要的方式脱钩。


查看完整回答
反对 回复 2019-12-21
?
哈士奇WWW

TA贡献1799条经验 获得超6个赞

您必须从作家的角度考虑这一点-了解您的听众。因此,需要考虑几个“受众”。


首先是经典的C程序员,他们掩饰了自己的一生,并且可以在睡眠中做到这一点。


第二个是新手,他不知道||和东西是什么。他们在上一份工作中编程php,现在为您工作。(我说这是做PHP的newb)


如果您写的是要满足第一批读者(全天都是位掩码)的话,那么会让他们感到非常高兴,并且他们将能够被蒙住眼睛。但是,新手可能需要克服庞大的学习技巧,才能维护您的代码。他们将需要了解二进制运算符,如何使用这些操作来设置/清除位,等等。您几乎肯定会因为newb引入了bug,因为他/她需要所有的技巧才能使其正常工作。


另一方面,如果您为了满足第二个读者而写作,则新手将可以更轻松地维护代码。他们会有更轻松的时光


 flags.force = 0;


 flags &= 0xFFFFFFFE;

最初的听众会变得脾气暴躁,但是很难想象他们将无法理解和维护新的语法。搞砸起来要困难得多。不会有新的错误,因为newb可以更轻松地维护代码。您将获得有关“如何回想起我今天需要稳定的手和磁化的针来设置位...我们什至没有位罩!”的讲座。(感谢XKCD)。


因此,我强烈建议使用位掩码上的字段来使代码安全。


查看完整回答
反对 回复 2019-12-21
  • 3 回答
  • 0 关注
  • 581 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信