首页 » C语言解惑 » C语言解惑全文在线阅读

《C语言解惑》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节将会再次结合实例说明运算符优先级和求值顺序的区别。