從一個很簡單的程序瞭解運算符優先級

從一個程序說起

今晚,同學寫了一個簡單的遞歸程序,但是總得不到理想的結果,來問我,我看了半天沒有找到哪裏出錯了。而且這個遞歸程序運算結果總是少了第一個數(5!會算成4!,3!會算成2!)。

#include<stdio.h>

int f(int a)
{
    if(a == 1) return 1;
    else return a*f(-- a); 
} 

int main()
{
    int x = 3;
    printf("%d\n", f(x));
    return 0;
} 

運行結果:2

運算符優先級問題

括號成員第一; //括號運算符 成員運算符. ->
全體單目第二; //所有的單目運算符比如++ – +(正) -(負) 指針運算*&
乘除餘三,加減四; //這個”餘”是指取餘運算即%
移位五,關係六; //移位運算符:<< >> ,關係:> < >= <= 等
等於(與)不等排第七; //即== !=
位與異或和位或; //這幾個都是位運算: 位與(&)異或(^)位或(|)
“三分天下”八九十;
邏輯或跟與; //邏輯運算符:|| 和 &&
十二和十一; //注意順序:優先級(||) 底於 優先級(&&)
條件高於賦值, //三目運算符優先級排到 13 位只比賦值運算符和”,”高//需要注意的是賦值運算符很多!
逗號運算級最低! //逗號運算符優先級最低

運算符的結合性

C語言中各運算符的結合性分爲兩種,即左結合性(自左至右)和右結合性(自右至左)。

  • 例如算術運算符的結合性是自左至右,即先左後右。如有表達式 x-y+z則 y 應先與“-”號結合,執行 x-y 運算,然後再執行+z 的運算。這種自左至右的結合方向就稱爲“左結合性”。

C語言運算符中有不少爲右結合性,應注意區別,以避免理解錯誤。

恍然大悟

瞭解了以上運算符優先級的問題,我才發現原來–輸入單目運算符,*屬於雙目運算符,程序運行a*f(–a)時, 單目運算符優先級較高,a的值先減一,因此會出現階乘少一項的情形。

改正

將–a 改爲 a-1 即可。

參考資料

  1. http://blog.chinaunix.net/uid-27710926-id-3337801.html
  2. http://blog.xieyc.com/pointer-and-operator-precedence-in-c-programming-language/
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章