運算式的副作用

來源:互聯網
上載者:User

          C++語言中的運算式可分為算術運算式,關聯運算式和邏輯運算式等多種類型,但從運算式中變數所起的作用角度來看可分為兩類:有副作用的運算式和無副作用的運算式.

     1 有關運算式的副作用的概念一般說計算一個運算式的值需要引用一些變數,在運算式求值過程中,需要提取這些變數的值,但並不改變這些變數的值,這樣的運算式稱為無副作用的運算式.從傳統意義上講,運算式的作用就是計算,它除了產生一個計算結果外,不應該改變參與計算過程的任何變數的值或產生其它的效應.換句話說,傳統意義上的運算式是不應該有副作用的.因此,絕大多數的進階語言中的運算式都是無副作用的運算式.C++語言兼有進階語言和低級語言的特點,是一種典型的全面支援物件導向特性的語言,為了運行效率的提高,引用了具有副作用的運算式.一個運算式在求值過程中,對使用的變數不但引用,對它們的值還加以改變,這樣的運算式稱為有副作用的運算式,或者稱這個運算式是有副作用的.

2 對錶達式的副作用的分析與理解,有如下四個運算式:1、5*X;2、X+Y;3、X++;4、Y-=18*2.其中運算式1和運算式2是無副作用的運算式,因為在運算式求值過程中,所引用的變數X和Y的值均未發生變化,例如:已知X=5,Y=10,運算式1的值為25,運算式2的值為15,但X的值仍為5,Y的值仍為10,而運算式3和運算式4是有副作用的運算式, 因為在求運算式值的過程中,所引用的變數X和Y的值均發生了變化.例如:x和Y的值初始狀態下分別是5和10 經計算後,運算式3的值為5,X的值變為6,運算式4的值為一26,Y的值變為一26.

      對於給出的運算式,怎樣才能正確地判斷出它是有副作用的運算式還是無副作用的運算式?主要原因取決於運算式中出現的操作符.C++語言中的操作符可分為兩類:無副作用的操作符和有副作用的操作符.如果一個運算式中引用了具有副作用的操作符,該運算式就是有副作用的運算式.C++語言引入的具有副作用的操作及相應的操作符包括: (1)賦值(=). (2)複合賦值(+=,一:, *=,/=,%=,《=,》=,!=,&=,一). (3)前增1,前減1(++, 一一).(4)後增1,後減1(++, 一一).這些操作所作用的對象必須是變數,因此這些操作也可稱作用於變數的操作.對於作用於變數的操作,除後增1和後減1以,還有這樣一個特點:作為操作結果的運算式的值就是所作用的變數獲得的值.例如執行語句序列:int i=5;count<< (i+=3);count<<i,後兩個輸出結果均為8.也就是說運算式的值就存放在所作用的變數中.而對於後增1和後減1操作符,運算後儘管變數的值和運算式的值不同(運算式的值不能通過變數來表示),但是通過計算運算式的值,確使變數的值發生了變化,例如執行語句序列:int i=5;cout<<i++;count<<i;後兩個輸出結果分別是5和6,因此從有副作用的運算式的概念出發,後增1和後減1操作符仍是有副作用的操作符. .區別一個運算式是否是有副作用的運算式還可以從計算順序上進行比較.不帶副作用的幾個運算式的值,不會因計算順序不同而不同,例如:設X=3,Y=2,則3*x與運算式X+Y 的值一定是3*2=6與3+2=5;但是帶副作用的運算式與其它運算式之間計算的順序將非常重要,順序不同結果也不同,例如:X=3,Y=2,則(++X)+Y與X+Y++依次計算後,運算式的值分別為6與6,而把兩個運算式改變計算次序,先計算,X+Y++,後計算(++X) +Y,則運算式的值分別為5和7.因此在對多個有副作用的運算式進行計算時,一定要注意運算式的計算次序.

3 指標運算式的副作用有的指標運算式也有副作用,而產生副作用的原因也是因為使用了具有副作用的操作符.在與指標有關的操作中,++ (前增1)、一一(前減1)、+=、-=以及=這5種操作符用於變數並改變它的值,變數所獲得的新值也就是指標運算式的值,因而運算式的值就間接地以變數形式提供.也就是說,這5種操作符的操作結果(即指標運算式的值)視同變數,可繼續對之進行只能對變數才能實施的操作(包括上述5種操作以及取地址、後增1、後減1),因此象++ (++pk),pk+=&k這樣的運算式都是合法的(其中pk是指標變數).對於++ (後增1)和一一(後減1)操作,雖然也作用於變數而且改變它的值,但指標運算式的值與變數所獲得的新值不相同,因而運算式的值就不可能以變數形式提供,而只能以數值的這種更直接的形式提供.也就是說,後增1(或後減1)的操作結果視同常量的數值形式的地址值,因此象(pk++) ++,pk一一十=&k這樣的運算式都是非法的(pk是指標變數).* (間接訪問)操作結果視同變數,可繼續對之進行只能對變數才能實施的操作;而& (取地址)作用於變數,但不改變變數的值,其操作的結果視同常量的數值形式的地址值,不可對之進行只能對變數才能實施的操作.對於這兩種操作符,都是不具有副作用的操作符.總之,與數值運算式的副作用有關的結論,對於指標運算式同樣適用.在指標運算式中具有副作用的操作符與數值運算式中的具有副作用的操作符相同. 

4 運算式副作用的應用
4.1 逗號運算式 由逗號操作符(即,)將各個運算式串連起來就構成了逗號運算式,即運算式1,運算式2,? ? ,運算式n,逗號運算式的求值順序是:先計算運算式1的值,然後計算表達2的值,依此類推,最後計算運算式n的值,最後計算出的運算式n的值就作為整個逗號運算式的值.例如:w--,j+=3,k++,P=w+j+k是一個逗號運算式,若初始狀態下w=5,j=6,k=7,那麼該逗號表達的值為21(5+9+7).對於逗號運算式中的每個運算式,除最後一個外,必須是具有副作用的運算式才有意義,如上例.而像X=5,6+18,72*9,Y=10這個逗號運算式中的運算式6+18和72*9是無副作用的運算式,計算時毫無意義.

4.2 運算式語句 在C++中,任何一個運算式都可以作為一個語句來使用,稱為運算式語句,方法是在運算式後加上語句結束符(即;).C++運算式之所以可以作為語句使用,是因為C++拓展了運算式的概念,把賦值等具有副作用的操作也歸入運算式的範疇.一切輸入、輸出操作都通過函數實現;並無專門的輸入、輸出語句,而函數調用也是運算式的一種形式.因此,除了流程式控制制語句外,其它如賦值、輸入、輸出等都只能通過運算式實現.運算式作為語句使用時,它的值被捨棄不用,其語句功能通過它的副作用體現, 因而把無副作用的運算式作為語句使用是毫無意義的,如運算式語句K+19;運算式的值(K與19之和)被捨棄不用,它是無意義的語句;只有把具有副作用的運算式作為語句使用才有意義,像運算式語句x+=5;運算式的值被捨棄不用,但由於+=是有副作用的操作符,經計算後運算式的值實際已儲存在變數X中,因此該運算式語句是有意義的.總之,C++語言中運算式的副作用並不一定是壞東西,理解好它的概念,掌握有副作用的操作符,這樣才能處理好它,給自己設計的程式帶來較高的運行效率.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.