运算优先级引发的错,你犯过吗?
昨天给学生写一个快读程序,居然没成功,代码如下:
#include<iostream>
#include<cstdio>
using namespace std;
int readint()
{
char ch=0;
int zs=0,fh=1;
do
{
ch=getchar();
}
while(ch!='-'&&(ch>'9'||ch<'0'));
if(ch=='-')fh=-1;
else zs=ch-'0';
while(ch=getchar()&&ch>='0'&&ch<='9')
{
zs=zs*10+ch-'0';
}
zs=zs*fh;
return zs;
}
int main()
{
int a;
a=readint();
cout<<a;
return 0;
}
经多方跟踪、调试、复查均未找到错因。根据以往经验,这种错很难发现,但有一个不太靠谱的方法解决:换个时间重写一个。今天一大早马上重写快读,基本思路不变,竟然真的成功了。然后把两个程序一比对便找到了原因----都是运算优先级惹的祸。
在运算优先级里,数值运算高于逻辑运算,逻辑运算高于赋值运算,在ch=getchar()&&ch>='0'&&ch<='9'的优先级时,“=”赋值语句的优先级比&&的优先级低,所以,系统把把这一句解释为ch=(getchar()&&ch>='0'&&ch<='9'),而正确的运算逻辑是(ch=getchar())&&ch>='0'&&ch<='9',这两者有质的差异,故而出错。
本例给我们的启示:1.尽量不要写太长的运算,确有很多运算,可改为多步判断.2.不太确定的优先级问题可以用括号强制提升优先级,以免出错.比如此例中表达式可写为(ch=getchar())&&(ch>='0')&&(ch<='9'),可能有些括号可以不用,但用了也不会错,更不会引发顺序不对而产生的错.