C++中的i++和++i你真的理解嗎?
本篇文章主要講解C++中的i++和++i的運算規則,原本,我以為自己已經掌握了這個知識點,但是,在接觸了類似(i++)+(++i)+(i++)的非規範運算時,卻卡了很長時間,下面我就來著重講解這個"事故"。
一.i++與++i的區別
1.i++
i++的意思是先賦值再自增,通俗講就是計算i++,先計算i,計算結束後i自增1。注意,自增的i不參與開始計算。在進行下一步計算時,自增的i為最新的i。
通過一個示例大家就能明白了。
int main(){
int i=0;
int j=i++;
cout<<"j的值為:"<<j<<endl;
cout<<"i的值為:"<<i<<endl;
return 0;
}
結果:
我們來分析一下:
1).首先i=0。
2).j=i++,根據先賦值後自增原則,先j=i;後i=i+1。
3).結果為:j=0.i=0+1=1。
剛剛也說了,自增的值不參與開始的計算,在後面的計算,自增後的值為最新的值。
再來舉個例子:
int main(){
int i=0;
int j=i++;
cout<<"j的值為:"<<j<<endl;
cout<<"i的值為:"<<i<<endl;
int k=i++;
cout<<"k的值為:"<<k<<endl;
cout<<"i的值為:"<<i<<endl;
return 0;
}
結果:
分析:此例子就利用了i自增後的值作為新值計算,步驟:
1).i=0;j=i++;
2).j=i=0,i=i+1=1,此時j=0,i=1(i自增的值)。
3).k=i++,k=i=1(此時的i為自增後的值為1),i=i+1=2。結果k=1,i=2。
2.++i
和i++不同的是,++i是自增後賦值。通俗講就是計算++i時,先計算i+1,然後將此值賦給i。
還是通過一個例子:
int main(){
int i=0;
int j=++i;
cout<<"j的值為:"<<j<<endl;
cout<<"i的值為:"<<i<<endl;
int k=++i;
cout<<"k的值為:"<<k<<endl;
cout<<"i的值為:"<<i<<endl;
return 0;
}
結果:
分析:
1).i=0,j=++i,此時按照先自增後賦值原則,i=i+1=1(j=i+1=1),i=i(將自增的i賦值給i),所以此時j=1,i=1。
2).k=++i,此時i為1,i=i+1=2(k=i+1=2),i=i(將自增的i賦值給i,此時自增的i為2),所以k=2,i=2。
二.i++與++i的混合運算----(i++)+(++i)或(i++)+(i++)
前面已經講解了i++和++i的區別,大家也理解了計算規則,可能很多人認為組合計算很簡單,但事實是否是這樣的呢?
先看i++和i++的混合運算示例:
int main(){
int i=0;
int j=(i++)+(i++);
cout<<"j的值為:"<<j<<endl;
cout<<"i的值為:"<<i<<endl;
return 0;
}
按照正常的分析思路:
1).i=0,j=(i++)+(i++)分開計算:i++先賦值為0,之後自增i=i+1=1。
2).第二個i++,先賦值為1,後自增i=i+1=2。
3).所以j=0+1=1,i=2
但結果是這樣的嗎?
通過執行程式發現竟然不一致:
再看下i++和++i的混合運算示例:
int main(){
int i=0;
int j=(i++)+(++i);
cout<<"j的值為:"<<j<<endl;
cout<<"i的值為:"<<i<<endl;
return 0;
}
按照正常思路為
1).i=0,先計算i++,賦值0,後i自增為i=i+1=1。
2).計算++i,i=i+1=2,i=i=2。
3).j=0+2=2,i=2。
運算結果:
發現一致,這就很奇怪,經過查閱資料發現:
C語言創始人明確指出:
自增與自減運算只能作用於變數,類似於(i+j)++是非法的,因為自增運算包含了賦值運算,而表示式不能作為賦值運算的左值。
表示式不能作為賦值運算的左值這句是什麼意思呢?
舉個例子:
int main(){
int j=0;
int k=1;
k++=j;
cout<<"j的值為:"<<j<<endl;
cout<<"k的值為:"<<k<<endl;
return 0;
}
結果出錯:
因為k++運算結果是一個臨時變數,且這個臨時變數並不是程式中定義的可定址變數的引用,不能被更改,所以不能作為左值表示式,總結就是,左值就是具有存放資料的空間。
而為什麼(i+j)++是非法的呢?
假設 int x=(i+j)++;那麼它會進行什麼操作呢?
x=i+j,i+j=(i+j)+1,很顯然表示式作為了賦值運算的左值,這是錯誤的。
所以,在這裡(i++)+(i++)也是非法的,因為在前一個i++的作用下,後面的i就已經是表示式了,表示式不能再做++操作
後面的i是在前面的i=i+1後得到的,也就是說i+1不能再做++操作,因此(i++)+(i++)也是非法的。
那麼。非法的表示式是否可以計算呢?
答案是可以的。
編譯器在無法做出正確計算步驟的情況下,會採取以下計算格式:
1).先將所有的i++改成i,然後在整個語句的最後新增i的自增次數(語句有幾個i++,就自增幾次)。
2).先將左邊前兩項相加,如果前兩項中含有++i,則先算++i。
3).前兩項的和作為一項,與第三項相加,以此類推。
那麼,將以上的(i++)+(i++)來分析,步驟為:
j=i+i;i++;i++
j=0,i=2
將以上的(i++)+(++i)來分析,步驟為:
i+(++i);i++;
j=(++i)+i;//先計算++i
i=i+1=1,i=i=1,j=1+1=2,i自增1為2。
綜上:(i++)+(++i)我們的思路結果確實是碰巧和計算機結果一樣
不同的是,我們的思路是0+2,而計算機的是1+1。
看完本篇文章,你會對i++和++i有更深刻的認識。
相關文章
- 你真的理解==和===嗎
- C++複習整理---i++和++iC++
- jvm是如何執行i = i++ + ++i的,你知道嗎?JVM
- 關於java中的i++和++iJava
- 你真的理解this嗎
- Java中 i=i++ 問題底層原理解析Java
- 你真的理解T-sql中的NULL嗎?SQLNull
- 你真的理解setState嗎?
- 圖解i++和++i圖解
- java中i=i++的問題Java
- 你真的懂C++嗎?C++
- 你真的理解 getLocationInWindow 了嗎?
- [譯]你真的理解grok嗎
- 你真的理解 new 了嗎?
- 你真的理解 Spring Boot 專案中的 parent 嗎?Spring Boot
- 你真的理解Python中的賦值、傳參嗎?Python賦值
- JAVA的i++, i+=1, i=i+1有區別嗎?Java
- 你真的理解 flex 佈局嗎?Flex
- 三層,你真的理解了嗎?
- 你真的理解JS的繼承了嗎?JS繼承
- 你真的理解機器學習中偏差 - 方差之間的權衡嗎?機器學習
- synchronized下的 i+=2 和 i++ i++執行結果居然不一樣synchronized
- 每天學點C++知識:用 ++i 替代 i++C++
- 位元組碼指令分析 ++i 和 i++
- MVP模式(2):你真的理解下抽象類和介面嗎??MVP模式抽象
- 你真的理解@import和link引入樣式的區別嗎Import
- C++的那些事:你真的瞭解引用嗎C++
- 你真的理解什麼是死鎖嗎?
- python 中的i++ ,邏輯表示式Python
- 高併發,你真的理解透徹了嗎?
- 你真的理解反向傳播嗎?面試必備反向傳播面試
- 你真的知道 == 和 equals 的區別嗎?
- 你真的懂 == 和 equals 的區別嗎?
- 你真的理解javascript中的預編譯麼?JavaScript編譯
- 你真的瞭解 Cookie 和 Session 嗎?CookieSession
- 你真的瞭解 Cookie 和 Session 嗎CookieSession
- 你真的瞭解 Session 和 Cookie 嗎?SessionCookie
- 你真的理解函數語言程式設計嗎?函數程式設計