欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一看就懂的i++和++i示例代碼詳解

 更新時間:2023年03月01日 10:02:54   作者:song854601134  
這篇文章主要介紹了i++和++i區(qū)別詳解,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

一看就懂的i++和++i詳解

前言

我相信很多朋友可能之前已經(jīng)百度過i++和++i的相關(guān)文章了,也做過不少的練習,覺得自己已經(jīng)深刻掌握了它們之間的原理了,真的是這樣的嗎?來試試計算一下我下面提供的幾道練習,你就會發(fā)現(xiàn)你又不會了!

示例代碼

請先自己心算一下答案,然后找個本子記下來,然后再跟我后面的答案對比,看你能做對幾道題,能做對兩題以上的我喊你大哥??!

示例1

int i = 0;
i = i++; 
System.out.println("i = " + i); 

示例2

int a = 2; 
int b = (3 * a++) + a;
System.out.println(b);

示例3

int a = 2; 
int b = a + (3 * a++);
System.out.println(b);

示例4

int i = 1;
int j = 1;
int k = i++ + ++i + ++j + j++; 
System.out.println(k);

示例5

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 即前加加,原理是:先自增,然后返回自增之后的值
重點:這是一般人所不知道的,記?。翰徽撌乔?+還是后++,都有個共同點是先自增。
對于++i 就不說了,大多數(shù)人都懂,而對于 i++ 的原理,我用代碼模擬其原理,如下:

int temp = i;
i = i + 1;
return temp;  
123

這3句代碼就是上面所說的那樣:i++是先自增,然后才返回自增之前的值。

i++字節(jié)碼分析

有很多的人寫的文章上都是說i++是先返回i的值,然后再自增,這是錯誤,是先自增,然后再返回自增之前的值,你可能會問,這有區(qū)別嗎?答案:有的。只要這個沒理解對,則你在計算i++的相關(guān)問題時就有可能算錯。

有的人可能又會問了,我憑什么相信你,你有什么證據(jù)證明i++是先自增,然后再返回自增之前的值嗎?我還真去找過證據(jù),我們把class的字節(jié)碼搞出來,分析一下就知道了,證明如下:

public class Test {
    void fun() {
        int i = 0;
        i = i++;
    }
}

如上,我們寫了一個超級簡單的Test類。在cmd中輸入這個命令(javap -c Test.class)以查看其生成的字節(jié)碼,截圖如下:

1

我們關(guān)注fun()方法這一段就可以了,如下:

i++字節(jié)碼圖

這就是fun()函數(shù)對應的字節(jié)碼了,我們一行一行的來分析,首先我們要說兩個概念,一個是變量,一個是操作棧,fun()方法中有兩個變量,哎,不是只有一個變量i嗎?怎么會有兩個?要了解這個你需要去學習字節(jié)碼的相關(guān)知識,這里我們不深究,我畫圖如下:

在這里插入圖片描述

如上圖,變量有兩個,在位置0的變量是什么我們不要管,系統(tǒng)自動分配的,你要知道的是位置1的變量其實就是我們定義的變量i就行了,接下來,我們來一行行分析fun()方法對應的字節(jié)碼:
“ iconst_0 ” i代表int類型,const代表常量,0就代表整數(shù)0,整句話的意思就是把int類型的常量0放入操作棧的棧頂中,圖解如下:

在這里插入圖片描述

“ istore_1 ” i代表int類型,store代表存儲,1代表位置為1的變量,整句話的意思就是把操作棧中棧頂?shù)闹的米?,保存到位置?的變量上,圖解如下:

在這里插入圖片描述

“ iload_1 ” i代表int類型,load代表加載變量的值,1代表位置為1的變量,整句話的意思就是把位置為1的變量的值加載到操作棧的棧頂中,圖解如下:

在這里插入圖片描述

“ iinc 1, 1 ” i代表int類型,inc(increment)代表增加,這里還有兩個1,前面的1代表對位置為1的變量,第2個1代表增加1,因為有i += 3這種自增操作,這種情況的話第2個數(shù)字會是3,即自增3(iinc 1, 3)。“iinc 1, 1” 整句話的意思就是把位置為1的變量的值增加1,圖解如下:

在這里插入圖片描述

注:自增操作不會改變操作棧中的值,所以變量i的值自增后變成了1,而操作棧中的值還是0。

“ istore_1 ” i代表int類型,store代表存儲,1代表位置1的變量,整句話的意思就是:把棧頂中的值拿走,保存到位置為1的變量中,圖解如下:

在這里插入圖片描述

所以,這幾行字節(jié)碼合起來看,i++不就是先自增,然后才返回自增之前的值嘛??!所以大家千萬別搞錯順序了。 用代碼理解的話,就相當于下面的代碼:

int temp = i;
i = i + 1;
return temp;  

最后再把++i的字節(jié)碼圖也貼一下,大家可以根據(jù)我上面講解的知識分析一下,就會知道++i和i++的區(qū)別了:

void fun() {
    int i = 0;
    i = ++i;
}

++i字節(jié)碼圖

表達式原則

表達式有一個原則:一個變量也是表達式,多個表達式的加減法運算都是從左到右進行的

來看一下 if 語句的其中一種結(jié)構(gòu)定義:

if (條件表達式) 語句;

用這個結(jié)構(gòu)寫個代碼,如下:

boolean b = true;
int i = 0;
if(b) i++;

按照上面 if 語句的結(jié)構(gòu)定義,if括號中是一個表達式,但是上面代碼寫了一個變量b進去,這是一個變量啊,怎么也能當成一個表達式么?沒錯,一個變量也是表達式。

記住這個重點:一個變量也是表達式,多個表達式的加減法運算都是從左到右進行的

講到這里,估計有人會對這個運算順序和乘法這些搞混了,示例如下:

int a = 0;
int b = a + a * 2;

如上代碼,按著我的說法,一個變量也是一個表達式,“b = a + a * 2”這里a出現(xiàn)了兩次,就是有兩個a表達式,從左到右算的話先算a + a,這肯定不對啊,這不是我的意思哈,乘除法的優(yōu)先級還是不能亂的,那應該先算a * 2嗎?也不對,應該是這樣的:因為有乘法,所以a * 2優(yōu)先組成表達式,而不是a + a組成表達式,也就是說總體上可以分為兩個表達式:“a” 表達式 和 “a * 2” 表達式,這兩個表達式相加肯定從左到右計算嘛,先算完a表達式的結(jié)果,再算a * 2表達式的結(jié)果。你可能會想先算a和先算a * 2有區(qū)別嗎?答案是:有的,看完下面 的“示例3詳解” 你就清楚了。

示例答案詳解

示例1詳解

int i = 0;
i = i++;  
System.out.println("i = " + i);  // 結(jié)果:0

先看i++,根據(jù)原理“先自增,然后返回自增之前的值”,i 自增后,i = 1,但是接著返回自增之前的值0,此時表達式變成 i = 0,0沒有賦值給 i 時 i 的值是1,但是當把0賦值給 i 時,i 的值就又變成0了。因此 i = i++ 這句代碼是做無用功,因為 i 的值最終還是和原來一樣。

示例2詳解

int a = 2; 
int b = (3 * a++) + a;
System.out.println(b);   // 結(jié)果:9

int b = (3 * a++) + a;a++后,a = 3,并返回自增之前的值2,所以此時表達式為:

int b = (3 * 2) + a;此時a的值已經(jīng)是3了,表達式又變?yōu)椋?/p>

int b = (3 * 2) + 3; 所以b = 9

示例3詳解

int a = 2; 
int b = a + (3 * a++);
System.out.println(b); // 結(jié)果:8

這題和示例2幾乎一樣啊,只是換了一下順序而已,為什么結(jié)果就不一樣了呢?這就需要用到“表達式原則 了”:一個變量也是表達式,多個表達式的加減法運算都是從左到右進行的

int b = a + (3 * a++);按一般人的想法是先算 3 * a++,a 先自增 a=3,然后返回自增之前的值2,所以此時表達式變?yōu)椋?/p>

int b = a + (3 * 2); 此時a的值為3了,表達式又變?yōu)椋?/p>

int b = 3 + (3 * 2);結(jié)果 b = 9

我們說一個變量也是表達式,多個表達式的加減法運算都是從左到右進行的,這個理論你可能不能深刻體會,但是如果我把代碼稍微改一下你就能理解了,如下:

int b = (a * 1) + (3 * a++) 這個代碼和 int b = a + (3 * a++) 是一樣的,沒有區(qū)別,但是看(a *1)你就很容易的知道要先算a * 1這個表達式,表達式的結(jié)果為2。

所以,雖然 int b = a + (3 * a++) 中前面的a只是一個變量,但他也是一個表達式,a這個表達式和(3 * a++)這個表達式進行相加,多個表達式的運算都是從左到右進行的,所以先算a這個表達式,a表達式計算結(jié)果為2,所以表達式變成:

int b = 2 + (3 * a++) 然后是a自增并返回自增之前的值2,所以表達式又變?yōu)椋?/p>

int b = 2 + (3 * 2);所以結(jié)果為8。此時a的值為3

示例4詳解

int i = 1;
int j = 1;
int k = i++ + ++i + ++j + j++;  
System.out.println(k);  // 結(jié)果:8

有了前面3條示例的詳解,相信這一條大家就能自己解答了,可以先自己解答一下,看結(jié)果是不是8,不是的話,再來看我下面的講解:

表達式原則說多個表達式的加減法運算都是從左到右進行的,這里的表達式有:i++、++i、++j、j++,都是加法,那我們就從左到右計算這4個表達式就OK了,如下:

1、先算i++,i++之后i的值為2,并返回++之前的值1,所以整個表達式可以變?yōu)椋?/p>

1 + ++i + ++j + j++; // 此時的i值為2

2、再計算++i,++i之后i的值為3,并返回3,所以整個表達式可以變?yōu)椋?/p>

1 + 3 + ++j + j++; // 此時i的值為3

3、再計算++j,++j之后j的值為2,并返回2,所以整個表達式可以變?yōu)椋?/p>

1 + 3 + 2 + j++; // 此時j的值為2

4、再計算j++,j++之后 j的值為3,并返回2,所以整個表達式可以變?yōu)椋?/p>

1 + 3 + 2 +2; // 結(jié)果為8,此時j的值為3

示例5詳解

int a = 0;
int b = 0;
a = a++;
b = a++;
System.out.println("a = " + a + ", b = " + b); // a = 1, b = 0

到了第5題,好像已經(jīng)沒有難度了,大家應該都能解出來了,但是為了文章的完整性,我還是分解一下,大家應該自己先算一次,算不對再來看我的分解:

a = a++; a++之后a的值為1,并返回0,所以a的值由1又變回了0
b = a++; a++之后a的值為1,并返回0,0賦值給b,所以b為0,而a還是1哦!!

總結(jié)

  • i++ 即后加加,原理是:先自增,然后返回自增之前的值
  • ++i 即前加加,原理是:先自增,然后返回自增之后的值
  • 一個變量也是表達式,多個表達式的加減法運算都是從左到右進行的
  • 真實開發(fā)中,我們不會寫這些復雜的i++代碼,但是為什么還要掌握這些細節(jié)呢?答:筆試,萬一筆試的時候遇到這樣的題目呢?回答對了就可以加分了,因為這種題很多人是答不出來的,而你回答出來了,那可是很加分的哦!

相關(guān)文章

最新評論