您好,登錄后才能下訂單哦!
這篇文章主要講解了“C語言i++和++i示例代碼分析”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“C語言i++和++i示例代碼分析”吧!
我相信很多朋友可能之前已經百度過i++和++i的相關文章了,也做過不少的練習,覺得自己已經深刻掌握了它們之間的原理了,真的是這樣的嗎?來試試計算一下我下面提供的幾道練習,你就會發現你又不會了!
請先自己心算一下答案,然后找個本子記下來,然后再跟我后面的答案對比,看你能做對幾道題,能做對兩題以上的我喊你大哥!!
int i = 0; i = i++; System.out.println("i = " + i);
int a = 2; int b = (3 * a++) + a; System.out.println(b);
int a = 2; int b = a + (3 * a++); System.out.println(b);
int i = 1; int j = 1; int k = i++ + ++i + ++j + j++; System.out.println(k);
int a = 0; int b = 0; a = a++; b = a++; System.out.println("a = " + a + ", b = " + b);
示例1:0
示例2:9
示例3:8
示例4:8
示例5:a = 1, b = 0
i++ 即后加加,原理是:先自增,然后返回自增之前的值
++i 即前加加,原理是:先自增,然后返回自增之后的值
重點:這是一般人所不知道的,記住:不論是前++還是后++,都有個共同點是先自增。
對于++i 就不說了,大多數人都懂,而對于 i++ 的原理,我用代碼模擬其原理,如下:
int temp = i; i = i + 1; return temp; 123
這3句代碼就是上面所說的那樣:i++是先自增,然后才返回自增之前的值。
有很多的人寫的文章上都是說i++是先返回i的值,然后再自增,這是錯誤,是先自增,然后再返回自增之前的值,你可能會問,這有區別嗎?答案:有的。只要這個沒理解對,則你在計算i++的相關問題時就有可能算錯。
有的人可能又會問了,我憑什么相信你,你有什么證據證明i++是先自增,然后再返回自增之前的值嗎?我還真去找過證據,我們把class的字節碼搞出來,分析一下就知道了,證明如下:
public class Test { void fun() { int i = 0; i = i++; } }
如上,我們寫了一個超級簡單的Test類。在cmd中輸入這個命令(javap -c Test.class)以查看其生成的字節碼,截圖如下:
我們關注fun()方法這一段就可以了,如下:
這就是fun()函數對應的字節碼了,我們一行一行的來分析,首先我們要說兩個概念,一個是變量,一個是操作棧,fun()方法中有兩個變量,哎,不是只有一個變量i嗎?怎么會有兩個?要了解這個你需要去學習字節碼的相關知識,這里我們不深究,我畫圖如下:
如上圖,變量有兩個,在位置0的變量是什么我們不要管,系統自動分配的,你要知道的是位置1的變量其實就是我們定義的變量i就行了,接下來,我們來一行行分析fun()方法對應的字節碼:
“ iconst_0 ” i代表int類型,const代表常量,0就代表整數0,整句話的意思就是把int類型的常量0放入操作棧的棧頂中,圖解如下:
“ istore_1 ” i代表int類型,store代表存儲,1代表位置為1的變量,整句話的意思就是把操作棧中棧頂的值拿走,保存到位置為1的變量上,圖解如下:
“ iload_1 ” i代表int類型,load代表加載變量的值,1代表位置為1的變量,整句話的意思就是把位置為1的變量的值加載到操作棧的棧頂中,圖解如下:
“ iinc 1, 1 ” i代表int類型,inc(increment)代表增加,這里還有兩個1,前面的1代表對位置為1的變量,第2個1代表增加1,因為有i += 3這種自增操作,這種情況的話第2個數字會是3,即自增3(iinc 1, 3)。“iinc 1, 1” 整句話的意思就是把位置為1的變量的值增加1,圖解如下:
注:自增操作不會改變操作棧中的值,所以變量i的值自增后變成了1,而操作棧中的值還是0。
“ istore_1 ” i代表int類型,store代表存儲,1代表位置1的變量,整句話的意思就是:把棧頂中的值拿走,保存到位置為1的變量中,圖解如下:
所以,這幾行字節碼合起來看,i++不就是先自增,然后才返回自增之前的值嘛!!所以大家千萬別搞錯順序了。 用代碼理解的話,就相當于下面的代碼:
int temp = i; i = i + 1; return temp;
最后再把++i的字節碼圖也貼一下,大家可以根據我上面講解的知識分析一下,就會知道++i和i++的區別了:
void fun() { int i = 0; i = ++i; }
表達式有一個原則:一個變量也是表達式,多個表達式的加減法運算都是從左到右進行的
來看一下 if 語句的其中一種結構定義:
if (條件表達式) 語句;
用這個結構寫個代碼,如下:
boolean b = true; int i = 0; if(b) i++;
按照上面 if 語句的結構定義,if括號中是一個表達式,但是上面代碼寫了一個變量b進去,這是一個變量啊,怎么也能當成一個表達式么?沒錯,一個變量也是表達式。
記住這個重點:一個變量也是
表達式,多個表達式的加減法運算都是從左到右進行的
講到這里,估計有人會對這個運算順序和乘法這些搞混了,示例如下:
int a = 0; int b = a + a * 2;
如上代碼,按著我的說法,一個變量也是一個表達式,“b = a + a * 2”這里a出現了兩次,就是有兩個a表達式,從左到右算的話先算a + a,這肯定不對啊,這不是我的意思哈,乘除法的優先級還是不能亂的,那應該先算a * 2嗎?也不對,應該是這樣的:因為有乘法,所以a * 2優先組成表達式,而不是a + a組成表達式,也就是說總體上可以分為兩個表達式:“a” 表達式 和 “a * 2” 表達式,這兩個表達式相加肯定從左到右計算嘛,先算完a表達式的結果,再算a * 2表達式的結果。你可能會想先算a和先算a * 2有區別嗎?答案是:有的,看完下面 的“示例3詳解” 你就清楚了。
int i = 0; i = i++; System.out.println("i = " + i); // 結果:0
先看i++,根據原理“先自增,然后返回自增之前的值”,i 自增后,i = 1,但是接著返回自增之前的值0,此時表達式變成 i = 0,0沒有賦值給 i 時 i 的值是1,但是當把0賦值給 i 時,i 的值就又變成0了。因此 i = i++ 這句代碼是做無用功,因為 i 的值最終還是和原來一樣。
int a = 2; int b = (3 * a++) + a; System.out.println(b); // 結果:9
int b = (3 * a++) + a;a++后,a = 3,并返回自增之前的值2,所以此時表達式為:
int b = (3 * 2) + a;此時a的值已經是3了,表達式又變為:
int b = (3 * 2) + 3; 所以b = 9
int a = 2; int b = a + (3 * a++); System.out.println(b); // 結果:8
這題和示例2幾乎一樣啊,只是換了一下順序而已,為什么結果就不一樣了呢?這就需要用到“表達式原則 了”:一個變量也是表達式,多個表達式的加減法運算都是從左到右進行的
int b = a + (3 * a++);按一般人的想法是先算 3 * a++,a 先自增 a=3,然后返回自增之前的值2,所以此時表達式變為:
int b = a + (3 * 2); 此時a的值為3了,表達式又變為:
int b = 3 + (3 * 2);結果 b = 9
我們說一個變量也是表達式,多個表達式的加減法運算都是從左到右進行的,這個理論你可能不能深刻體會,但是如果我把代碼稍微改一下你就能理解了,如下:
int b = (a * 1) + (3 * a++) 這個代碼和 int b = a + (3 * a++) 是一樣的,沒有區別,但是看(a *1)你就很容易的知道要先算a * 1這個表達式,表達式的結果為2。
所以,雖然 int b = a + (3 * a++) 中前面的a只是一個變量,但他也是一個表達式,a這個表達式和(3 * a++)這個表達式進行相加,多個表達式的運算都是從左到右進行的,所以先算a這個表達式,a表達式計算結果為2,所以表達式變成:
int b = 2 + (3 * a++) 然后是a自增并返回自增之前的值2,所以表達式又變為:
int b = 2 + (3 * 2);所以結果為8。此時a的值為3
int i = 1; int j = 1; int k = i++ + ++i + ++j + j++; System.out.println(k); // 結果:8
有了前面3條示例的詳解,相信這一條大家就能自己解答了,可以先自己解答一下,看結果是不是8,不是的話,再來看我下面的講解:
表達式原則說多個表達式的加減法運算都是從左到右進行的,這里的表達式有:i++、++i、++j、j++,都是加法,那我們就從左到右計算這4個表達式就OK了,如下:
1、先算i++,i++之后i的值為2,并返回++之前的值1,所以整個表達式可以變為:
1 + ++i + ++j + j++; // 此時的i值為2
2、再計算++i,++i之后i的值為3,并返回3,所以整個表達式可以變為:
1 + 3 + ++j + j++; // 此時i的值為3
3、再計算++j,++j之后j的值為2,并返回2,所以整個表達式可以變為:
1 + 3 + 2 + j++; // 此時j的值為2
4、再計算j++,j++之后 j的值為3,并返回2,所以整個表達式可以變為:
1 + 3 + 2 +2; // 結果為8,此時j的值為3
int a = 0; int b = 0; a = a++; b = a++; System.out.println("a = " + a + ", b = " + b); // a = 1, b = 0
到了第5題,好像已經沒有難度了,大家應該都能解出來了,但是為了文章的完整性,我還是分解一下,大家應該自己先算一次,算不對再來看我的分解:
a = a++; a++之后a的值為1,并返回0,所以a的值由1又變回了0
b = a++; a++之后a的值為1,并返回0,0賦值給b,所以b為0,而a還是1哦!!
感謝各位的閱讀,以上就是“C語言i++和++i示例代碼分析”的內容了,經過本文的學習后,相信大家對C語言i++和++i示例代碼分析這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。