問題 :
C語言的書籍的附錄都要說一個問題,就是優先性和結合方向。
我的理解是這些是建立在表達式的基礎之上的,寫一個c語言的表達式或者看一個C語言的表達式,先看優先性,在優先性相同的情況下,再根據結合方向,判斷表達式的那個部分先運算,那個後運算。如:
1. a=b=c=0,只有一個=,因此優先性相同,因此看結合方向,結合方向是從右到左,因此,整個表達是從右開始計算,上面等價與a=(b=(c=0)),這是正確地,但是下面這個問題該怎麼解釋哪?
2. a=*p++;
=,優先級低於*,++,也就是等價於a=(*p++);但是*p++,這個部分是怎麼運算哪?寫過C的都知道*先,++後,可是在C語言附錄中,*(取地址),++是同優先級的,2級,結合方向是從右到左,按照這個理解就應該*(p++),這才是從右到左吧,不知道理解有沒有問題,但是這個和實際應用的相反的嘛?
解答:
關於a = *p++;
首先,“後自增”運算符的優先級是高於“*”的,“前自增”才跟“*”平級。這一點樓主沒有看仔細。
然後,為什麼優先級高於“*”,結果還是取出了原來的指針指向的內容呢?
有很多書上說“後自增”是先“用”值,再加1,這種說法是很不嚴格很不確切的。正是這種不嚴格和不確切,才導致了許多初學者在*p++上絆倒。
再看一個更簡單的例子:
int i = 10;
int j = i++;
現在j等於多少?大家都知道是10,問原因,很多人都會說是“在後自增的情況下,是先賦值再加1”。這中說法完全不負責任,賦值運算賦“=”的優先級比“後自增”低好幾個級別,怎麼可能發生“先賦值”這樣的事?
正確的語義解釋是:“前自增”和“後自增”都是先將變量加1,然後區別在於加1後返回值,後自增在加1後返回的是原來的,而前自增返回的是加1後新值。
從效果上,i++相當於一個逗號表達式:“tmp = i, ++i, tmp”