最近在刷杭电的题目 在此记录下自己踩过的坑 希望即将到来的比赛能取得好成绩
话不多说下面是我自己AC的C++代码
#include <iostream>
using namespace std;
int main()
{int a, b;while (cin >> a >> b) {cout << a + b<<'\n';}return 0;
}
起因:在看讨论区的时候看到了这个代码
#include<stdio.h>
int main()
{int a,b;while(~scanf("%d%d",&a,&b)){printf("%d\n",a+b);}return 0;
}
就有点不理解其中~scanf("%d%d",&a,&b)
表示什么意思
考据:
-
~表示按位取反
位:二进制数系统中,位简记为b,也称为比特,每个二进制数字0或1就是一个位(bit)。位是数据存储的最小单位,其中8 bit 就称为一个字节(Byte)。
-
C++提供了一种灵活的标准,它确保了最小长度(从C语言借鉴而来),如下所示
- short至少16位;
- int至少与short一样长;
- long至少32位,且至少与int一样长;
- long long至少64位,且至少与long一样长;
目前在一般的电脑中,int占用4字节,32比特,数据范围为-21474836482147483647[-2^312^31-1]
-
scanf()函数
3.1. scanf函数返回成功读入的数据项数
读入数据时遇到了“文件结束”则返回EOF。
#include <stdio.h> int main(void) {int a,b,c;printf("Give me the value of a,b seperated with whitespaces:\n");scanf("%d%d",&a,&b);printf("a=%d,b=%d\n",a,b);return 0; }
- 如果a和b都被成功读入,那么scanf的返回值就是2;
- 如果只有a被成功读入,返回值为1;
- 如果a和b都未被成功读入,返回值为0;
- 如果遇到错误或遇到end of file,返回值为EOF,实际上 EOF 的值通常被定义为是int类型的一个负数-1。end of file为Ctrl+z 或者Ctrl+d。
所以:上面语句表示当没有输入时退出循环
另外:~scanf("%d%d",&a,&b)与scanf("%d %d",&a,&b)!=EOF没有区别3.2. 如果a、b均赋值成功返回值为2,取反之后结果为-3。
计算机中的数都是以补码形式存在的
-
正数的原码=反码=补码。
-
负数的反码=该数的原码除符号位外各位取反。
-
负数的补码=该数的原码除符号位外各位取反,然后在最后一位加1
2的补码:0000 0000 0000 0000 0000 0000 0000 0010取反:1111 1111 1111 1111 1111 1111 1111 1101 再取反:1000 0000 0000 0000 0000 0000 0000 0010 再+1得到:1000 0000 0000 0000 0000 0000 0000 0011 便得到十进制的-3。
注意:
在高版本的 Visual Studio 编译器中,scanf 被认为是不安全的,被弃用,应当使用scanf_s代替 [scanf](https://baike.baidu.com/item/scanf_s)。
3.3. ~scanf("%d%d",&a,&b)输入字母的时候有时会变成死循环
- 如果输入4 6,那就会返回2;
- 如果输入4 a,返回1;
- 如果输入a 6,则返回0;
- 只要碰到格式不匹配的输入,就把不匹配的输入留在缓冲区并且拒绝读取
如果怕出现这种情况改成
scanf("%d %d",&a,&b)==2
就会表示只有a b都正确输入了才进入循环