ตัวดำเนินการโพสต์ส่วนเพิ่ม (i ++) และส่วนเพิ่มก่อน (++ i) ทำงานอย่างไรใน Java


103

คุณช่วยอธิบายผลลัพธ์ของโค้ด Java นี้ให้ฉันฟังได้ไหม

int a=5,i;

i=++a + ++a + a++;
i=a++ + ++a + ++a;
a=++a + ++a + a++;

System.out.println(a);
System.out.println(i);

เอาต์พุตคือ 20 ในทั้งสองกรณี


9
หลีกเลี่ยงข้อความที่คลุมเครือเสมอ :)
Prasoon Saurav

9
@Prasoon Saurav แตกต่างจาก C และ C ++ Java และ C # ได้กำหนดลำดับการประเมินอย่างเคร่งครัดดังนั้นข้อความเหล่านี้จึงไม่คลุมเครือ
Pete Kirkham

12
ฉันรู้ว่า แต่ข้อความเหล่านั้นยังไม่ (ไม่สามารถใช้) เพื่อวัตถุประสงค์ในทางปฏิบัติได้ดังนั้นจึงต้องหลีกเลี่ยง
Prasoon Saurav


4
@PeteKirkham เวลาผ่านไปหกปีแล้ว แต่ฉันยังอยากจะชี้ให้เห็นว่า "คลุมเครือ" ในสถานการณ์นี้มีความคลุมเครือ - อาจหมายถึง "คอมไพเลอร์ไม่รู้ว่าจะใส่อะไร" หรืออาจหมายถึง "โปรแกรมเมอร์ ไม่รู้ว่ามันหมายถึงอะไร ".
คดีของ Fund Monica

คำตอบ:


156

สิ่งนี้ช่วยได้หรือไม่?

a = 5;
i=++a + ++a + a++; =>
i=6 + 7 + 7; (a=8)

a = 5;
i=a++ + ++a + ++a; =>
i=5 + 7 + 8; (a=8)

ประเด็นหลักคือการ++aเพิ่มค่าและส่งคืนทันที

a++ ยังเพิ่มค่า (ในพื้นหลัง) แต่ส่งกลับค่าที่ไม่เปลี่ยนแปลงของตัวแปรซึ่งดูเหมือนว่าจะถูกเรียกใช้ในภายหลัง


5
แน่ใจหรือว่า a == 9 ในอันที่สอง?
Pete Kirkham

1
ผม = ++ a + ++ a + a ++; => ฉัน = 7 + 8 + 5; (a = 8) เนื่องจากการเพิ่มโพสต์มีลำดับความสำคัญสูงสุดจึงมีการดำเนินการ ++ ก่อนหรือไม่
rsirs

2
ตัวอย่างที่ซับซ้อนไปสู่สิ่งที่ง่ายต่อการอธิบาย
oznus

คำตอบนี้เหมือนกันสำหรับ c # และ c ++ หรือไม่?
การทำงาน

ทำไม a, b และ c เท่ากับ 2 ที่นี่? int a = 1; int b = a++; int c = ++b;คาดหวังให้ b เป็น 1 เนื่องจากเป็นการเพิ่มโพสต์
Dennis

208

++aเพิ่มขึ้นแล้วใช้ตัวแปร
a++ใช้แล้วเพิ่มตัวแปร

ถ้าคุณมี

a = 1;

และคุณทำ

System.out.println(a++); //You will see 1

//Now a is 2

System.out.println(++a); //You will see 3

codaddict อธิบายตัวอย่างข้อมูลเฉพาะของคุณ


67

ในทั้งสองกรณีจะคำนวณมูลค่าก่อน แต่ในภายหลังการเพิ่มจะเก็บค่าเก่าและหลังจากคำนวณผลตอบแทนแล้ว

++ ก

  1. ก = a + 1;
  2. กลับ a;

a ++

  1. อุณหภูมิ = a;
  2. ก = a + 1;
  3. กลับอุณหภูมิ;

8
คำตอบที่ชัดเจนที่สุด
Kartik Chugh

2
นี่คือสิ่งที่ทำให้ฉันเข้าใจอย่างชัดเจน .. ขอบคุณ
rematnarab

22
i = ++a + ++a + a++;

คือ

i = 6 + 7 + 7

การทำงาน : เพิ่มขึ้น a ถึง 6 (ค่าปัจจุบัน 6) + เพิ่มขึ้น a ถึง 7 (ค่าปัจจุบัน 7) ตอนนี้ผลรวมคือ 13 เพิ่มเป็นค่าปัจจุบันของ a (= 7) จากนั้นเพิ่ม a ถึง 8 ผลรวมคือ 20 และค่าของ a หลังจากการกำหนดเสร็จสมบูรณ์คือ 8

i = a++ + ++a + ++a;

คือ

i = 5 + 7 + 8

การทำงาน : ที่ค่าเริ่มต้นของ a คือ 5 ใช้ในการบวกแล้วเพิ่มเป็น 6 (ค่าปัจจุบัน 6) เพิ่ม a จากค่าปัจจุบัน 6 เป็น 7 เพื่อรับตัวถูกดำเนินการอื่น ๆ ของ + ผลรวมคือ 12 และค่าปัจจุบันของ a คือ 7 เพิ่มครั้งต่อไป a จาก 7 ถึง 8 (ค่าปัจจุบัน = 8) และเพิ่มลงในผลรวม 12 ก่อนหน้าเพื่อรับ 20


ข้อความเหล่านี้ทำงานจากขวาไปซ้ายหรือซ้ายไปขวา?
Abhijeet

10

++aเพิ่มขึ้นaก่อนที่จะได้รับการประเมิน a++ประเมินaแล้วเพิ่มขึ้น

ที่เกี่ยวข้องกับการแสดงออกของคุณให้:

i = ((++a) + (++a) + (a++)) == ((6) + (7) + (7)); // a is 8 at the end
i = ((a++) + (++a) + (++a)) == ((5) + (7) + (8)); // a is 8 at the end

พาเรนต์ที่ฉันใช้ข้างต้นถูกใช้โดยปริยายโดย Java หากคุณดูคำศัพท์ด้วยวิธีนี้คุณจะเห็นได้ง่ายว่าทั้งสองคำเหมือนกันเนื่องจากมีการสับเปลี่ยน


1
@ KlasLindbäckการสับเปลี่ยนหมายความว่าคุณสามารถสลับทั้งสองนิพจน์และยังคงได้ผลลัพธ์เหมือนกัน ดังนั้น a ++ + ++ a == ++ a + a ++ (5 + 7 == 6 + 6; a == 7 ในตอนท้าย)
Aurril

8

ในตัวอย่างข้างต้น

int a = 5,i;

i=++a + ++a + a++;        //Ans: i = 6 + 7 + 7 = 20 then a = 8 

i=a++ + ++a + ++a;        //Ans: i = 8 + 10 + 11 = 29 then a = 11

a=++a + ++a + a++;        //Ans: a = 12 + 13 + 13 = 38

System.out.println(a);    //Ans: a = 38

System.out.println(i);    //Ans: i = 29

4

++ a เป็นตัวดำเนินการเพิ่มคำนำหน้า:

  • ผลลัพธ์จะถูกคำนวณและเก็บไว้ก่อน
  • จากนั้นตัวแปรจะถูกใช้

a ++ เป็นตัวดำเนินการส่วนเพิ่ม postfix:

  • ตัวแปรถูกใช้ก่อน
  • จากนั้นผลลัพธ์จะถูกคำนวณและจัดเก็บ

เมื่อคุณจำกฎ EZ สำหรับคุณเพื่อคำนวณทุกอย่าง!


4

สันนิษฐานว่าคุณหมายถึง

int a=5; int i;

i=++a + ++a + a++;

System.out.println(i);

a=5;

i=a++ + ++a + ++a;

System.out.println(i);

a=5;

a=++a + ++a + a++;

System.out.println(a);

สิ่งนี้ประเมินเพื่อ:

i = (6, a is now 6) + (7, a is now 7) + (7, a is now 8)

ดังนั้นฉันคือ 6 + 7 + 7 = 20 และพิมพ์ 20

i = (5, a is now 6) + (7, a is now 7) + (8, a is now 8)

ดังนั้นฉันคือ 5 + 7 + 8 = 20 และ 20 จึงถูกพิมพ์อีกครั้ง

a = (6, a is now 6) + (7, a is now 7) + (7, a is now 8)

และหลังจากประเมินด้านขวามือทั้งหมดแล้ว (รวมถึงการตั้งค่า a ถึง 8) จากนั้นตั้งค่า a เป็น 6 + 7 + 7 = 20 และจะพิมพ์ 20 ครั้งสุดท้าย


3

เมื่อaเป็น 5 จากนั้นa++ให้ 5 กับนิพจน์และเพิ่มขึ้นaหลังจากนั้นในขณะที่++aเพิ่มขึ้นaก่อนที่จะส่งตัวเลขไปยังนิพจน์ (ซึ่งจะให้a6 เป็นนิพจน์ในกรณีนี้)

ดังนั้นคุณคำนวณ

i = 6 + 7 + 7
i = 5 + 7 + 8

3

อย่างไรก็ตามฉันเชื่อว่าหากคุณรวมคำสั่งทั้งหมดของคุณและเรียกใช้ใน Java 8.1 คุณจะได้รับคำตอบที่แตกต่างออกไปอย่างน้อยนั่นคือสิ่งที่ประสบการณ์ของฉันบอก

รหัสจะทำงานดังนี้:

int a=5,i;

i=++a + ++a + a++;            /*a = 5;
                                i=++a + ++a + a++; =>
                                i=6 + 7 + 7; (a=8); i=20;*/

i=a++ + ++a + ++a;           /*a = 5;
                                i=a++ + ++a + ++a; =>
                                i=8 + 10 + 11; (a=11); i=29;*/

a=++a + ++a + a++;            /*a=5;
                                a=++a + ++a + a++; =>
                                a=12 + 13 + 13;  a=38;*/

System.out.println(a);        //output: 38
System.out.println(i);         //output: 29

3

การเพิ่มขึ้นล่วงหน้าหมายความว่าตัวแปรจะเพิ่มขึ้นก่อนที่จะประเมินในนิพจน์ Post-Increment หมายความว่าตัวแปรจะเพิ่มขึ้นหลังจากที่ได้รับการประเมินเพื่อใช้ในนิพจน์

ดังนั้นดูให้ดีและคุณจะเห็นว่างานทั้งสามงานเทียบเท่ากันทางคณิตศาสตร์


2

การเพิ่มก่อนและการเพิ่มหลังจะเทียบเท่ากันหากไม่อยู่ในนิพจน์

int j =0;
int r=0         
for(int v = 0; v<10; ++v) { 
          ++r;
          j++;
          System.out.println(j+" "+r);
  }  
 1 1  
 2 2  
 3 3       
 4 4
 5 5
 6 6
 7 7
 8 8
 9 9
10 10

0
a=5; i=++a + ++a + a++;

คือ

i = 7 + 6 + 7

ที่ทำงาน: ก่อน / หลังเพิ่มขึ้นมี "ขวาไปซ้าย" (++a + ++a) => 7 + 6การเชื่อมโยงกันและก่อนมีความสำคัญมากกว่าการโพสต์เพื่อครั้งแรกของทั้งหมดที่เพิ่มขึ้นก่อนจะได้รับการแก้ปัญหาเป็น จากนั้นa=7มีไว้เพื่อโพสต์เพิ่ม => และ7 + 6 + 7 =20a =8

a=5; i=a++ + ++a + ++a;

คือ

i=7 + 7 + 6

ที่ทำงาน: ก่อน / หลังเพิ่มขึ้นมี "ขวาไปซ้าย" การเชื่อมโยงกันและก่อนมีความสำคัญมากกว่าการโพสต์เพื่อครั้งแรกของทั้งหมดที่เพิ่มขึ้นก่อนจะได้รับการแก้ปัญหาเป็น(++a + ++a) => 7 + 6จากนั้นa=7มีไว้เพื่อโพสต์เพิ่ม => และ7 + 7 + 6 =20a =8


0

ฉันเชื่อว่าคุณกำลังเรียกใช้คำสั่งเหล่านี้ทั้งหมดที่แตกต่างกัน
การดำเนินการร่วมกันจะได้ผลลัพธ์ => 38, 29

int a=5,i;
i=++a + ++a + a++;
//this means i= 6+7+7=20 and when this result is stored in i,
//then last *a* will be incremented <br>
i=a++ + ++a + ++a;
//this means i= 5+7+8=20 (this could be complicated, 
//but its working like this),<br>
a=++a + ++a + a++;
//as a is 6+7+7=20 (this is incremented like this)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.