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