本文最后更新于626 天前,其中的信息可能已经过时,如有错误请发送邮件到echobydq@gmail.com
while(~scanf(“%d%d“,&a,&b))详解
按位取反
1. 原码、反码、补码
原码
:符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值。
反码
:正数的反码是其本身;负数的反码是在其原码的基础上, 符号位不变,其余各个位取反。
补码
:正数的补码就是其本身;负数的补码是在原码的基础上, 符号位不变, 其余各位取反, 最后+1。 (即在反码的基础上+1)
十进制数 | 原码 | 反码 | 补码 |
---|---|---|---|
85 | 0101 0101 | 0101 0101 | 0101 0101 |
-85 | 1101 0101 | 1010 1010 | 1010 1011 |
9 | 0000 1001 | 0000 1001 | 0000 1001 |
-9 | 1000 1001 | 1111 0110 | 1111 0111 |
2. 取反符号:~
~
取反运算,0 则变为 1,1 则变为 0,如
~ 1 0 0 1 1
-----------------------------
0 1 1 0 0
3. 按位取反
而按位取反
需要涉及以上概念。要弄懂这个运算符的计算方法,首先必须明白二进制数在内存中的存放形式,二进制数在内存中是以补码的形式存放的。
下面以计算正数 9 的按位取反为例,计算步骤如下(注:前四位为符号位):
- 原码 : 0000 1001
- 算反码 : 0000 1001 (正数反码同原码)
- 算补码 : 0000 1001 (正数补码同反码)
- 补取反 : 1111 0110 (全位0变1,1变0)
- 算反码 : 1111 0101 (末位减1)
- 算原码 : 1111 1010 (其他位取反)
总结:
- 所有正整数的按位取反是其本身+1的负数
- 所有负整数的按位取反是其本身+1的绝对值
- 零的按位取反是 -1(0在数学界既不是正数也不是负数)
scanf( ) 的返回值
对于scanf("%d%d%d",&a,&b,&c)
;
- 如果a、b 和c 都被成功读入,则scanf的返回值为3
- 如果 a 和 b 被成功读入,那么返回值为2
- 如果只有a被成功读入,那么返回值为1
- 如果遇到错误或遇到end of file,返回值为EOF
其中,EOF
是 End Of File
的缩写,在 C 语言标准库中的定义为:#define EOF (-1)
可参考此篇文章:字符输入输出和输入验证 – Echo (liveout.cn)
总结
当 scanf
成功读取至少一个数时,scanf 的返回值是1或2,
1按位取反为-2, 2按位取反为-3,都会进入while循环内部。
当输入读取结束后,scanf的返回值是EOF
,EOF即-1,-1按位取反为0,此时会跳出while循环。
即
//这个意思一样
while(~scanf("%d%d",&a,&b))
while(scanf("%d%d",&a,&b) != EOF)