我们在刷题时可能会遇到程序需要支持多次输入、多组输入的情况。
这时我们可以用到 while(scanf()!=EOF)和(~scanf())。
例如:
int n=0; while((scanf("%d",&n)!=EOF) {};
while(~scanf("%d",&n) {};
EOF
这两个的作用是完全一致的。
先看前一个:EOF是End Of File的缩写,意为文件结束标志。
我们转到定义可以看到EOF被定义的值为**-1**。
int main()
{
int n = 0;
while (scanf("%d", &n) != EOF)
{
printf("%d\n", n);
}
return 0;
}
while(scanf()=EOF)
简单写个程序,我们输入什么就打印什么,直到scanf读取到EOF。
上面提到EOF的值是-1,那输入-1会怎样呢?
程序会继续运行,打印-1。因为scanf读取的时候,程序是按照“-”和“1”两个字符依次接收的。
那怎么输入EOF呢?Windows平台上一般是按组合键ctrl + z即可输入EOF,但我的是ctrl + c,大家可自行尝试。
while(~scanf())
这时候涉及一个操作符:位操作符,即“~”。C语言一共有6种位操作符,
分别是 “&”按位与 “|”按位或 “^”按位异或 “~”按位取反 “<<”左移 “>>”右移
我们这里只介绍按位取反。
(下面这段可以省略,直接看结论)
首先介绍一些概念:整数在内存中是以补码的形式存储的。一个整数的二进制数表示有三种:原码、补码和反码。例如-1的二进制数为
方式 | 二进制数 |
---|---|
原码 | 10000000000000000000000000000001 |
反码 | 1111111111111111111111111111111111110 |
补码 | 1111111111111111111111111111111111111 |
使用~按位取反时,原码符号位不变,其余位取反 ,即原来是0现取1,原来是1现取0,得到反码。再将反码补1得到补码。负数的补码再转为原码是同样符号位不变,按位取反后,并在最低位+1。
注意:正数的补码等于它的原码,负数的补码等于反码+1。
打印时打印原码,存储时存储补码。
结论
- 所有正整数的按位取反是其本身+1的负数
- 所有负整数的按位取反是其本身+1的绝对值
- 零的按位取反是 -1(0在数学界既不是正数也不是负数)
因为scanf函数的返回值是输入的值的个数,如果没有值就返回-1。而-1按位取反结果是0,while(~scanf(“%d”, &n)),所以当没有值输入时就为
while(0),即退出循环。