老师们好
下面的代码,我怎么想也没有想明白会返回-1
0|0 = 0, 0|1 =1, 1|1 =1, 1|0 = 1,
怎么会出现-1呢,
#include <stdio.h>
#include <limits.h>
int main(){
int sign;
int v = -10;
sign = (v != 0) | (v >> (sizeof(int) * CHAR_BIT - 1)); // CHAR_BIT 宏定义在头文件limits.h中
printf("%d\n", sign);
return 0;
}
为了更好的理解这个问题,我们先讲讲一个基础的知识点,我在曾经的笔记里也写过:
小凯15天快速讲完c语言-简单学习第二课
根据C语言的规范,在做位运算时,整型的符号位是以补码的形式存在的。对于负数,它的符号位是1。对于正数和零,符号位是0。
好了,明白了这个知识点,我们再代入到代码里一起看看,在这个代码中,首先执行了 (v != 0) 的比较,这里是判断 v 是否等于0,结果是真,即1。然后执行 (v >> (sizeof(int) * CHAR_BIT - 1)),这里进行右移操作。
这里第二个知识点来了:在C语言中,对于带符号的整数,右移运算会将最高位的符号位进行复制,填充左侧的空位。
所以对于负数 v = -10,右移后符号位的值是1。对于正数和零,符号位的值是0。接下来进行按位或运算,
(v != 0) | (v >> (sizeof(int) * CHAR_BIT - 1))
。对于负数,第一个表达式 (v != 0) 的结果是1,而第二个表达式(v >> (sizeof(int) * CHAR_BIT - 1))
的结果是1。按位或运算后,结果是1。最后,将结果1打印出来,即 -1。因为 %d 是用来打印有符号整数的,所以将1作为有符号整数表示的话,它的补码形式是负数,因此打印出来的结果是-1。
所以,对于输入的 -10,代码将返回-1表示其符号位是负数。
希望我的回答能帮到你!