C++基礎:賦值表達式和逗號表達式

字號:

C++把賦值運算符連接而成的式子叫做賦值表達式,例如:a=b、a=b+c、a=3等。賦值運算符是一個雙目運算符,必須兩個參與運算的值,其左邊的值叫做l-value,通常是變量或賦值表達式,常量和常變量不可以作為賦值表達式的左值。賦值運算符右端的值叫做r-value,通常一個常量、變量或表達式。
    C++把逗號運算符連接的式子叫做逗號表達式,例如:“a,a*3”,“b+3,d/4”等。逗號表達式右被稱為順序求值表達式,它的值是最右端的表達式的值。例如,有如下逗號表達式:
    a*=5,a+2
    假設a=3,該逗號表達式的求值步驟是,先計算左側的表達式a*=5,結果是a=15,然后計算右側的表達式a+2,值是17,整條逗號表達式的值為17。
    把賦值符和逗號連接的式子作為表達式看待是C++的特點之一,引入賦值表達式和逗號表達式使C++的語句變得十分靈活豐富。合理的使用賦值表達式和逗號表達式可以大大精簡代碼,使程序更緊湊。下面,我們來看一看使用這兩種表達式時的技巧和應當注意到問題。
    程序1:
    #include
    using namespace std;
    int main()
    {
    unsigned short a;
    short b=-1;
    a=b;
    cout<  return 0;
    }
    大家可以先猜測一下程序的運行結果。
    運行結果為65535。為什么是這個結果呢?其實,仔細想一想很容易得出答案:我們知道,short型變量在內存中是占兩個字節(jié)的,即16個二進制位。因此,用-1給b賦值以后,b中的值就是1111,1111,1111,1111 【注】,然后將其賦給a, a所占內存也是16位,原封不動全部搬過去, a的值也變成1111,1111,1111,1111 ,a是無符號數(shù),它的所有位都表示數(shù)值,1111,1111,1111,1111對應的十進制數(shù)即使65535,因此,輸出結果就是65535。
    【注】:所謂補碼,就是將該負的數(shù)絕對值的原碼取反后最低位加1得到的二進制編碼。例如,求取-3的補碼步驟如下:
    第一步:計算出3的原碼:0000,0000,0000,0011
    第二步:將3的原碼取反:1111,1111,1111,1100
    第三步:將取反后的原碼加1:1111,1111,1111,1101
    1111,1111,1111,1101即是-3的補碼。
    例1的運行結果給了我們一個警示——不同類型的變量相互賦值時一定要考慮他們的編碼形式即值域范圍,否則可能得到與我們的期望相差十萬八千里的結果。
    例2:
    #include
    using namespace std;
    int main()
    {
    int a=3;
    a+=4;
    cout<  return 0;
    }
    這個例子無甚特別之處,它僅僅說明了賦值運算符可以跟基本運算符組合成為符合賦值運算符。常見到組合方式有+=、-=、*=、/=、%=、<<=、>>=、&=、|=、∧=,關于這些符合賦值運算符的用法,此處不作介紹,大部分教授C++基礎的書上都有,不清楚的可以自己去查看。下面,我們來看一個有趣的問題。有如下表達式:
    a=5*8,a*10
    問,該表達式的值是多少?
    討論對該表達式的求解,可能會有兩種不同的聲音:其一認為a=5*8是一個賦值表達式,它跟后面的a*10一起構成了一個逗號表達式,所以求解時先算出a=5*8的值,然后計算a*10的值;另一種聲音認為5*8,a*10是個逗號表達式,應當先求這個逗號表達式的值,然后將逗號表達式的值賦給a。倒底那種理解對呢?這就需要查考兩種運算符的運算優(yōu)先級了。賦值運算符的優(yōu)先級要高于逗號運算符,因此,對表達式a=5*8,a*10的求解應該是先計算a=5*8,然后計算逗號表達式的值。
    例3:
    #include
    using namespace std;
    int main()
    {
    int a;
    a=3;
    cout<<(a+=a=a+=a)<    return 0;
    }
    問,輸出結果是多少?
    很多人見到諸如a+=a=a+=a這樣的表達式時,還沒思考,先就頭腦發(fā)暈了。其實,大可不必這么惶恐,冷靜下來,仔細想一想,這個表達式還是很容易求解的。要求解這個表達式,需要知道一個先決條件——賦值運算的求值順序。賦值運算都是從右至左求值的。知道了這一點,問題就迎刃而解了。下面是對該表達式的求解過程:
    第一步:計算最右端的a+=a,結果為6;
    第二步:將a+=a的值賦給前一個a,a變?yōu)?;
    第三步:計算最左端的a+=a,結果為12,12即為整個表達式的值。
    好了,現(xiàn)在大家對連續(xù)多次賦值的賦值表達式的求解應該沒有問題了。不過,上例中還有個需要注意的地方,不知道大家有沒有留意, cout語句中 “a+=a=a+=a”是加括號的。在用cout輸出賦值表達式或逗號表達式的值時一定要用括號將整個表達式括起來,否則,編譯會出錯,這主要是因為C++的輸出流對象ostream中沒有處理賦值運算符和逗號運算符的機制,如果你重載了<<運算符,實現(xiàn)了這個機制,就可以不要括號了(不過,要重載<<實現(xiàn)輸出賦值表達式是個比較復雜的問題,遠不如加個括號來得輕快,因此,牢記,輸出賦值或逗號表達式時一定要用括號把正個表達式括起來)。
    總結賦值表達式和逗號表達式的通常用法:
    一、賦值表達式的用法:
    1. 用于對多個變量賦值,如:a=b=c=d=3;
    2. 用于條件語句的條件,如:if(a=fun(x,y)){},這時相當于執(zhí)行
    a=fun(x,y);
    if(a){}
    賦值表達式通常用于以上兩種情況,但不限于此,靈活運用賦值表達式可以極大精簡程序代碼,使程序更加緊湊,更多用法,請自己去研究。
    二、逗號表達式的用法:
    1.用于順序求值,如:a=b,b=c,c=d; 相當于執(zhí)行:
    a=b;
    b=c;
    c=d;
    3. 用于條件語句,如:if(a=fun(x,y),a>0){},這時相當于執(zhí)行
    a=fun(x,y);
    if(a>0){}
    條件表達式通常用于以上兩種情況,但不限于此,逗號語句的特點在于它可以在一條語句中整合多種不同類型的表達式,用一條語句實現(xiàn)多個功能。例如,有如下可編譯執(zhí)行程序:
    #include
    using namespace std;
    int main()
    {
    int i;
    cout<<3<    return 0;
    }
    逗號表達式極大的增強了C++語句的靈活性,使用逗號表達式可以精簡程序代碼,希望大家在編程過程中靈活的使用逗號表達式,簡化自己從程序代碼,使代碼更緊湊,更具可讀性