C++基礎(chǔ):賦值表達(dá)式和逗號(hào)表達(dá)式

字號(hào):

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