映月读书网 > C语言解惑 > 16.1 运算顺序错误 >

16.1 运算顺序错误

【例16.1】下面是判别输入的3个数字是否有序的程序,找出其错误并改正之。


#include <stdio.h>
void main
()
{
     int a
,b
,c
;
     printf
("
输入三个整数:"
);
     scanf
("%d%d%d"
,&a
,&b
,&c
);
     if
(a>b>c
) printf
("
输入的是三个有序数:%d>%d>%d\n"
,a
,b
,c
);
     if
((a<b
)<c
) printf
("
输入的是三个有序数:%d<%d<%d\n"
,a
,b
,c
);
     else printf
("
输入的是三个无序数:%d
,%d
,%d\n"
,a
,b
,c
);
}
  

这里假设了a>b>c的运算顺序是先比较b>c,取大者再与a比较。其实编译系统是先比较a>b。假设最简单的情况,三个数字符合结果a>b>c>1。当执行a>b时,结果为真,则用这个真(值为1)再与c比较,显然c>1不成立,程序就会输出错误结果。下面是运行实例。


输入三个整数:
8 5 3
输入的是三个有序数:8<5<3
  

由此可见,就是假设的顺序,也是不行的。因为a>b的结果只有两种:0或1。

改正后的程序如下所示。


#include <stdio.h>
void main
()
{
     int a
,b
,c
;
     printf
("
输入三个整数:"
);
     scanf
("%d%d%d"
,&a
,&b
,&c
);
     if
(a>b
){
           if
(b>c
)  printf
("
输入的是三个有序数:%d>%d>%d\n"
,a
,b
,c
);
           else     printf
("
输入的是三个无序数:%d
,%d
,%d\n"
,a
,b
,c
);
           return
;
     }
     if
(a<b
){
            if
(b<c
) printf
("
输入的是三个有序数:%d<%d<%d\n"
,a
,b
,c
);
            else    printf
("
输入的是三个无序数:%d
,%d
,%d\n"
,a
,b
,c
);
     }
     return
;
}
  

由于设计的主程序是void型,所以使用“return;”结束运行。

其实,主程序设计的类型是int,第1篇和本章之前使用void类型并不正规,只是为了节省行数而已。从这里开始,将main改用int类型,这个程序应该为如下形式。


#include <stdio.h>
int main
()
{
     int a
,b
,c
;
     printf
("
输入三个整数:"
);
     scanf
("%d%d%d"
,&a
,&b
,&c
);
     if
(a>b
){
           if
(b>c
)     printf
("
输入的是三个有序数:%d>%d>%d\n"
,a
,b
,c
);
           else    printf
("
输入的是三个无序数:%d
,%d
,%d\n"
,a
,b
,c
);
           return 0
;
     }
     if
(a<b
){
           if
(b<c
) printf
("
输入的是三个有序数:%d<%d<%d\n"
,a
,b
,c
);
           else    printf
("
输入的是三个无序数:%d
,%d
,%d\n"
,a
,b
,c
);
     }
     return 0
;
}
  

给出几个运行示范如下。


输入三个整数:
-2 4 8
输入的是三个有序数:-2<4<8
输入三个整数:
-5 7 -9
输入的是三个无序数:-5
,7
,-9
输入三个整数:
8 6 -2
输入的是三个有序数:8>6>-2
  

【例16.2】下面的程序没有找到元素-5,分析错误原因并改正之。


#include <stdio.h>
int main
()
{
     int a[6]={1
,2
,3
,-6
,-5
,8}
,*p
;
     int i
,sum=0
;
     p=a
;
     for
(i=0
;i<6
;i++
)
        if
(* p+i==-5
)
              printf
("a[%d]=-5\n"
,i
);
     return 0
;
}
  

*p+i的含义是把*p的内容加i,尽管*与p之间有空格,编译系统还是要从左往右先把它看做*p,然后把它当做操作数。要求它和i的加法运算,必须使用*(p+i),才是取指针指向下一个位置的值。

将if语句改为


if 
( *
( p+i
) == -5
)
  

的形式,就可得到正确的运行结果:


a[4]=-5
。
  

对运算顺序可用括号表示清楚。在第16.5节将会再次结合实例说明运算符优先级和求值顺序的区别。