当前位置: 首页 > 科技观察

七年了,还没看到代码里有两个感叹号

时间:2023-03-12 19:03:06 科技观察

半个多月没更新笔记了。广告很少,动力明显不足。事业很重要。感谢您一直以来的关注!今天继续更新一篇小文,希望对大家有所帮助。intfunc(inttemp){return!!temp;}不知道大家有没有看到上面类似的代码,代码中出现了两个感叹号,是不是代码也有思想,需要表达情绪?初学C语言的时候,应该经常看到感叹号吧,比如:if(one!=two){...}---------------------------------------如果(!温度){...}------------------------------typedefenum{RESET=0,SET=!RESET}FlagStatus,ITStatus;--------------------------------------one=!temp;但是两个感叹号估计很难看出来。鱼鹰大学四年,工作三年,没见过这种文风。直到前段时间看了Linux源码才接触到它。当我第一次看到它时,我感到非常惊讶。为什么会有这样的写法呢?为什么要用两个感叹号,功能是什么,难道只是为了炫耀C语言的把戏吗?仔细一想,不禁惊叹其巧思。假设一个byte变量byte可以表示范围0~255,0代表一种意思,1~255代表另一种意思(你可能会问,为什么不直接用0和1,因为这个变量本身不仅有0和1,只有二进制meaningisusedwhichisusedwhereotherused,反正会有这样的情况)。如果我想用另一个变量位来表示这两种含义,一般我们会这样做:intfunc(unsignedcharbyte){unsignedcharbit;if(byte==0){bit=0;}else{bit=1;}returnbit;}这样写比较优雅简单:intfunc(unsignedcharbyte){bit=byte?1:0;returnbit;}但是无论哪一种,都不如第一种简单高效。简单易懂,效率如何?不需要判断语句(判断语句在单片机中可能影响不大,但是在多级缓存的情况下,影响可能会很大,这也是Linux为什么使用likely()之类的原因优化)。这样无论原字节的值是多少,都会变成0或1。这样,如果调用者使用如下方法:if(func()==1){}或if(func()){},不会有问题的。负数也是一样,只要是把0自己隔开,都可以用这个方法。这在底层开发中也很实用。比如GPIO有个管脚号需要判断是0还是1,一般是这样的:bit=(GPIOB->IDR&GPIO_Pin_4)>>4;或bit=(GPIOB->IDR&GPIO_Pin_4)?1:0;前面那个确实不错选择,但是这里需要修改两个地方,修改的时候容易忘记,所以不是下面这么简单:bit=!!(GPIOB->IDR&GPIO_Pin_4);如果换了IO,当需要修改代码的时候,只需要修改一次就可以了,相当的方便,所以推荐大家使用上面的方法来获取位的值。从组装的角度来看,只需一条指令就可以完成两次!效率不亚于shift法!