参考: www.nowcoder.com/kaoyan b站:看不懂算导的炉灰 语言选择:C with STL
为什么发生阻塞? 简单点说,程序在scanf处发生了I/O请求,需要数据,而scanf需要从输入缓冲区读取数据,程序刚运行的时候,这个缓冲区是空的,所以scanf得不到数据,就会阻塞程序,一直等待缓冲区内出现数据,此时我们从控制台输入内容,敲下回车,输入的内容便会传送给程序输入缓冲区,被scanf阻塞的程序发现缓冲区里有内容了,就会让scanf继续执行,读入数据。
为什么要敲回车? 默认情况下,我们在控制台的输入内容是不会立刻同步到缓冲区的,也许是为了防止误输入或效率问题,只有敲下回车的时候,输入内容连同换行符才会被一起传送至缓冲区,但实际上,被传送至缓冲区的换行符通常是我们所不需要的,它只是我们从控制台输入内容时所要按下的一个键而已,并不是我们需要的数据。
我们回看之前的例子,单步解读程序,格式内容"%d %d",我们输入11 66敲回车后,输入缓冲区内容变为11 66\n(用\n代表换行符),scanf先尝试读取格式内容里的第一个%d,也就是读整数,从缓冲区里成功读到了11,此时缓冲区剩下66\n(注意开头有个空格),然后尝试读取第二个%d,由于此时缓冲区开头的内容是空格,%d不理睬 ,忽略开头若干空白字符,然后遇到66,成功读入,此时scanf没有别的要读的了,结束,函数返回2(读入的数量),此时缓冲区剩余\n,然后程序执行printf,再执行scanf("%c", &c);,由于此时缓冲区有内容\n,所以不阻塞,直接读取,开头说到%c会读取一切字符,所以换行符自然而然被读到了 ,所以变量c的内容是'\n',带入printf("char=%c\n", c);,就可以明白为什么会出现图示的现象了。
如何解决?方案就是在每次使用scanf之后,调用fflush(stdin);来清空输入缓冲区(也就是清掉那个恼人的换行符),然而这样做很麻烦并且几乎所有oj都拒绝这种危险的操作,所以一般使用getchar();来消除换行符(实际就是读入但不赋值给变量)。
int a = 4; printf("%03d",a); 输出:004
printf("%3.0f",floatNum):不保留小数 printf("%6.2f".floatNum):保留两位小数 %6.2f 表明待打印的数(floatNum)至少占6个字符宽度(包括两位小数和一个小数点),且小数点后面有2位小数,小数点占一位,所以整数部分至少占3位。
switch case 要break,否则后面的case语句不经判断会全部执行。
2 暴力求解 2.1 枚举 e2-4 内存超限