【例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節將會再次結合實例說明運算符優先級和求值順序的區別。