W3 school 菜鸟教程 我要自学网 信息学奥赛NOI 花哥的博客 不逼自己一把,怎知自己有多优秀——校长语录

运算优先级引发的错,你犯过吗?

  昨天给学生写一个快读程序,居然没成功,代码如下:

#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'),可能有些括号可以不用,但用了也不会错,更不会引发顺序不对而产生的错.

posted @ 2020-07-17 09:53  耍人  阅读(213)  评论(0编辑  收藏  举报