1. 問題
有人問:int a=5; 為什么++a=1能編譯通過a++=1編譯錯誤呢?
解釋:不管是++a=1還是a++=1在C編譯環(huán)境下都無法編譯通過,但在C++中,++a=1可以編譯通過,而a++=1無法編譯通過,這也是C和C++的一個不同。因此,這是一個關于C++的問題。
2. 分析
不管是C還是C++,語句a++=1;的行為是未定義的,因為它違反了“如果在沒有序列點的表達式中多次修改同一標量的行為是未定義行為”。
對于++a=1,等效于(a+=1)=1,對于C而已?(a+=1)不是左值,因此不能將1賦值給++a。因此,在C中編譯通不過,給出的錯誤信息是:
[Error] lvalue required as left operand of assignment
但對于C++而言,表達式++a=1是正確的,因為++a在C++ 標準中是左值,因此,語句++a=1;在C++中是正確的語句。雖然該語句在C++中是正確,但不建議這樣寫。
表達式a++=1在C或C++中都是錯誤的,因為它試圖兩次修改同一個對象,這是不允許的。討論這個話題就像討論一個錯誤的時鐘在一個小時后的時間是多少而已。
注:左值(Ivalue)這個詞最初源自賦值表達式E1=E2,其中左操作數(shù)E1必須是(可修改的)表達式。對象(object)是一塊內(nèi)存區(qū)域,可以讀取它的值或者向它存儲數(shù)據(jù)。一般將左值視為對象的“定位值(locator value)”,即左值是一種表達式,可以通過它讀取或修改它所引用的對象。例如,表達式a和b都是左值,但表達式3和b+3都不是左值。再如,若一元表達式E是一個指向對象的指針,則*E是一個左值,表示E指向的對象。
C99對左值的定義是:左值是具有對象類型或非void的不完整類型的表達式,如果左值在求值時沒有指定對象,則其行為是未定義的。
C11起對左值的定義是:左值是一個表達式,該表達式潛在地指示一個對象,且該對象類型不是void,如果左值在求值時沒有指定對象,則其行為是未定義的。
3. 進一步分析
在C標準中,由自增和自減運算符構成的表達式是右值(在C標準中,有時把右值(rvalue)描述為表達式的值),但在C++中,前綴形式的運算符構成的表達式是左值。因此,在C語言中,即a++和++a不是左值而是右值,因此無法為它們賦值。而在C++ 中++a是左值,因此可以給++a賦值,這就是為什么在C++中語句++a=1;?能編譯通過的原因。
注:在C標準中,賦值和復合賦值運算符構成的表達式是右值,但在C++中是左值。例如?表達式(a=3*4)=5+6在C中是錯誤的,但在C++ 中是正確的。對于表達式a=3*4來說,在C中不是左值,因此不能將表達式5+6賦值給它,但在C++ 中它是左值,因此,可以將5+6賦值給(a=3*4)。
4. 經(jīng)驗
如果一個變量出現(xiàn)在一個函數(shù)的多個參數(shù)中,不要對該變量使用遞增或遞減運算符。
如果一個變量多次出現(xiàn)在一個表達式中,不要對該變量使用遞增或遞減運算符。
C語言學習50
C語言學習 · 目錄文章來源:http://www.zghlxwxcb.cn/news/detail-792929.html
上一篇C 語言基本概念----序列點下一篇C語言辨析——深入理解格式字符的用法文章來源地址http://www.zghlxwxcb.cn/news/detail-792929.html
到了這里,關于C語言辨析——int a=5;為什么++a=1能編譯通過而a++=1不行呢?的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!