user-0 提问: 关于位运算

回复:
user: user-1
content: 引用 12 楼 sholber 的回复:[quote=引用 10 楼 my_live_123 的回复:] 这是C语言的一个特性，C89时候没有布尔类型，C认为非零即真，0即假。因此算术表达式就可以和逻辑表达式整合在一起了。 if(GPFDAT&(1<<4)) 等价于 if(GPFDAT&(1<<4) ！= 0)  1左移4位和GPFDAT与，则获取GPFDAT的第4位（从1数）上的bit，结果是0或0x8  为0和不为0，与真假无关，C99之前，C里没有这个概念。很多教材为了通俗起见，胡乱引入这个术语。 另外，那两个表达式并不等价。如果执行起来，则， 第一个表达式：如果GPFDAT&(1<<4)的结果不为0，执行语句1，否则执行语句2； 第二个表达式：如果GPFDAT&(1<<4) != 0的结果不为0，执行语句1，否则执行语句2。 显然，第二个表达式虽然好看，但实际上加重了编译器的负担。个人管见。[/quote]  好吧，你总是把我拉进编译的深渊！ 从编译角度讲，编译过程是不同的，前者没有经过equality-expression ！= relational-expression，后者需要这个操作。 殊途同归，到达expression时，第一种情况，它要么为0要么不为0，如果不为0认为逻辑真，为0则逻辑假；第二种情况，在中间代码过程中，编译器可以在equality-expression ！= relational-expression如果逻辑真选择对往上走的值是1，而不是像第1种情传递GPFDAT&(1<<4)的结果值。无论到达exp后的值是1还是其他非零值， 到达exp后，生成的条件调转指令都是以判断0执行的。因此，表现形式不同，结果一致，从这一点上而论，是等价的！你提出的“不等价”只是以形式而论，不符合“等价”含义——比如一个直线方程有多种表达方式，但是都是等价的！ 你觉得这样解释咋样？ 个人觉得对初学者讨论编译问题，对于他们益处不大！  你说的“为0和不为0，与真假无关，C99之前，C里没有这个概念。”，我想瞅瞅你的依据

user: user-2
content: 自动抓换成bool 类型 false 或 true

user: user-3
content: http://goobbe.com/questions/3901010/shift-operator-in-c

user: user-4
content: 引用 16 楼 my_live_123 的回复:[quote=引用 12 楼 sholber 的回复:] [quote=引用 10 楼 my_live_123 的回复:] 这是C语言的一个特性，C89时候没有布尔类型，C认为非零即真，0即假。因此算术表达式就可以和逻辑表达式整合在一起了。 if(GPFDAT&(1<<4)) 等价于 if(GPFDAT&(1<<4) ！= 0)  1左移4位和GPFDAT与，则获取GPFDAT的第4位（从1数）上的bit，结果是0或0x8  为0和不为0，与真假无关，C99之前，C里没有这个概念。很多教材为了通俗起见，胡乱引入这个术语。 另外，那两个表达式并不等价。如果执行起来，则， 第一个表达式：如果GPFDAT&(1<<4)的结果不为0，执行语句1，否则执行语句2； 第二个表达式：如果GPFDAT&(1<<4) != 0的结果不为0，执行语句1，否则执行语句2。 显然，第二个表达式虽然好看，但实际上加重了编译器的负担。个人管见。[/quote]  好吧，你总是把我拉进编译的深渊！ 从编译角度讲，编译过程是不同的，前者没有经过equality-expression ！= relational-expression，后者需要这个操作。 殊途同归，到达expression时，第一种情况，它要么为0要么不为0，如果不为0认为逻辑真，为0则逻辑假；第二种情况，在中间代码过程中，编译器可以在equality-expression ！= relational-expression如果逻辑真选择对往上走的值是1，而不是像第1种情传递GPFDAT&(1<<4)的结果值。无论到达exp后的值是1还是其他非零值， 到达exp后，生成的条件调转指令都是以判断0执行的。因此，表现形式不同，结果一致，从这一点上而论，是等价的！你提出的“不等价”只是以形式而论，不符合“等价”含义——比如一个直线方程有多种表达方式，但是都是等价的！ 你觉得这样解释咋样？ 个人觉得对初学者讨论编译问题，对于他们益处不大！  你说的“为0和不为0，与真假无关，C99之前，C里没有这个概念。”，我想瞅瞅你的依据 [/quote] 我认同你的这个解释。 另外，你问的依据嘛，我的依据是标准里的措辞，标准不说为真是怎样，为假时怎样，只是说同0比较是否相等。举例来说，对于if语句： the first substatement is executed if the expression compares unequal to 0 它只是说表达式的值在比较时等于0或者不等于0。 其实最好的证据就是C11才正式地引入了_Bool 和头文件<stdbool.h>

user: user-5
content: 需要的改正下 ，if(GPFDAT&(1<<4)),  是表示GPFDAT寄存器地址里的数据的第五位是否是 1， 而不是第四位， #define GPFDAT  (*((unsigned long *)0x7F0080A4))   if(GPFDAT&(1<<4)),  {         如果GPFDAT的第五位是一，则进入if  （& 是按位与的意思）  ; } 1<<4 ==    0x0000 0000 0000 0000 0000 0000 0001 0000

user: user-4
content: 引用 4 楼 wysdaomei 的回复:[quote=引用 2 楼 user-10 的回复:] 表达式被隐式转换成bool类型了   谢谢，这个表达式是不是就只对第4位进行了判断！[/quote]  居然还谢谢。没证据表明被隐式转换为bool类型。自己想像的吧。

user: user-4
content: 引用 10 楼 my_live_123 的回复:这是C语言的一个特性，C89时候没有布尔类型，C认为非零即真，0即假。因此算术表达式就可以和逻辑表达式整合在一起了。 if(GPFDAT&(1<<4)) 等价于 if(GPFDAT&(1<<4) ！= 0)  1左移4位和GPFDAT与，则获取GPFDAT的第4位（从1数）上的bit，结果是0或0x8  为0和不为0，与真假无关，C99之前，C里没有这个概念。很多教材为了通俗起见，胡乱引入这个术语。 另外，那两个表达式并不等价。如果执行起来，则， 第一个表达式：如果GPFDAT&(1<<4)的结果不为0，执行语句1，否则执行语句2； 第二个表达式：如果GPFDAT&(1<<4) != 0的结果不为0，执行语句1，否则执行语句2。 显然，第二个表达式虽然好看，但实际上加重了编译器的负担。个人管见。

user: user-6
content: 先对GPFDAT&（1《4）求值，再if

user: user-0
content: 谢谢，之前想的有点混乱

user: user-7
content: 理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 （Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。）

user: user-8
content: 如5楼说说 GPFDAT的第四位没变 --------------------------- 你想想 a= 10;  if(a - 8)  这样a变了吗?

user: user-8
content: 引用 3 楼 wysdaomei 的回复:[quote=引用 1 楼 jiht594 的回复:] GPFDAT&(1<<4) 这叫表达式, 表达式结果是0为假, 非0真  3*2-6是假, 3*2-1是真  这个我知道，只是不明白，对于GPFDAT&（1《4）这个表达式来说，现在只明白GPFDAT的第4位变成了1，按照原来的理解，只要不是0都是真的话，那这边显然为真了，如果是这样的话与GPFDAT&（1《5）比较，这2个不就没区别了么。而实际是对第4位和第5位分别做了判断。[/quote] hi  如果GPFDAT是 0110 1010,  1《4 是0000 1000 那么GPFDAT&（1《4）是非0. (0110 1010 & 0000 1000 = 0000 1000 )  如果GPFDAT是 0111 0111,  1《4 是0000 1000 那么GPFDAT&（1《4）就是0啊 (0110 1010 & 0000 1000 = 0000 0000 )  这就可以判断第四位是不是1了啊. ----------------------------------------------------------------------- 后面对GPFDAT&（1《5）对描述看不明白

user: user-9
content: 引用 3 楼 wysdaomei 的回复:这个我知道，只是不明白，对于GPFDAT&（1《4）这个表达式来说，现在只明白GPFDAT的第4位变成了1，按照原来的理解，只要不是0都是真的话，那这边显然为真了，如果是这样的话与GPFDAT&（1《5）比较，这2个不就没区别了么。而实际是对第4位和第5位分别做了判断。  bit4没有变成1，只是判断bit4是不是1. if(0x51 &(1 <<4))  0101 0001 & 0001 0000 结果是1， if成立

user: user-0
content: 引用 2 楼 user-10 的回复:表达式被隐式转换成bool类型了   谢谢，这个表达式是不是就只对第4位进行了判断！

user: user-0
content: 引用 1 楼 jiht594 的回复:GPFDAT&(1<<4) 这叫表达式, 表达式结果是0为假, 非0真  3*2-6是假, 3*2-1是真  这个我知道，只是不明白，对于GPFDAT&（1《4）这个表达式来说，现在只明白GPFDAT的第4位变成了1，按照原来的理解，只要不是0都是真的话，那这边显然为真了，如果是这样的话与GPFDAT&（1《5）比较，这2个不就没区别了么。而实际是对第4位和第5位分别做了判断。

user: user-1
content: 这是C语言的一个特性，C89时候没有布尔类型，C认为非零即真，0即假。因此算术表达式就可以和逻辑表达式整合在一起了。 if(GPFDAT&(1<<4)) 等价于 if(GPFDAT&(1<<4) ！= 0)  1左移4位和GPFDAT与，则获取GPFDAT的第4位（从1数）上的bit，结果是0或0x8

user: user-10
content: 表达式被隐式转换成bool类型了

user: user-8
content: GPFDAT&(1<<4) 这叫表达式, 表达式结果是0为假, 非0真  3*2-6是假, 3*2-1是真