C: อะไรคือความแตกต่างระหว่าง ++ i และ i ++?


888

ใน C อะไรคือความแตกต่างระหว่างการใช้++iและi++และสิ่งที่ควรใช้ในบล็อกการเพิ่มของforลูป?


10
ไม่แน่ใจว่าโปสเตอร์ดั้งเดิมมีความสนใจ แต่ใน C ++ ความแตกต่างของประสิทธิภาพอาจมีความสำคัญเนื่องจากการสร้างวัตถุชั่วคราวอาจมีราคาแพงสำหรับประเภทที่ผู้ใช้กำหนด
ใน Freund

คำตอบ:


1100
  • ++iจะเพิ่มค่าของiแล้วส่งคืนค่าที่เพิ่มขึ้น

     i = 1;
     j = ++i;
     (i is 2, j is 2)
  • i++จะเป็นการเพิ่มค่าของiแต่จะคืนค่าดั้งเดิมที่iเก็บไว้ก่อนที่จะเพิ่มขึ้น

     i = 1;
     j = i++;
     (i is 2, j is 1)

สำหรับการforวนซ้ำก็ใช้งานได้ ++iดูเหมือนกันมากขึ้นบางทีอาจเป็นเพราะนั่นคือสิ่งที่จะใช้ในK & R

ไม่ว่าในกรณีใดก็ตามให้ทำตามคำแนะนำ "ชอบ++iมากกว่าi++" และคุณจะไม่ผิดพลาด

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

คำถามประสิทธิภาพเป็นที่น่าสนใจ ... นี่คือความพยายามของฉันที่คำตอบ: มีความแตกต่างของประสิทธิภาพระหว่าง i ++ และ ++ i ใน C หรือไม่?

ในฐานะที่เป็น@OnFreundบันทึกมันแตกต่างกันสำหรับวัตถุ C ++ เนื่องจากoperator++()เป็นฟังก์ชั่นและคอมไพเลอร์ไม่ทราบว่าจะปรับการสร้างวัตถุชั่วคราวให้เหมาะสมเพื่อเก็บค่ากลาง


6
เอฟเฟกต์นี้จะไม่ทำให้สภาพอากาศวนซ้ำอีกครั้งเมื่อถึงสภาวะสิ้นสุด ตัวอย่างเช่นสิ่งนี้ for(int i=0; i<10; i++){ print i; } จะไม่แตกต่างจากfor(int i=0; i<10; ++i){ print i; } ความเข้าใจของฉันหรือไม่ว่าบางภาษาจะให้ผลลัพธ์ที่แตกต่างตามที่คุณใช้
aVeRTRAC

27
jonnyflash ทั้งสองจะทำงานเหมือนกันเนื่องจากการเพิ่มขึ้นของ i และการพิมพ์ที่อยู่ในงบที่แตกต่างกัน นี่ควรเป็นกรณีสำหรับภาษาใด ๆ ที่รองรับ C-style ++ ข้อแตกต่างระหว่าง ++ i และ i ++ เท่านั้นคือเมื่อใช้ค่าของการดำเนินการในคำสั่งเดียวกัน
Mark Harrison

16
เนื่องจากในกรณีส่วนใหญ่พวกเขาผลิตรหัสที่เหมือนกันฉันชอบi++เพราะมันเป็นของรูปแบบ "ตัวถูกดำเนินการ - ผู้ประกอบการ", การมอบหมาย "ตัวถูกดำเนินการ - มูลค่า" กล่าวอีกนัยหนึ่งตัวถูกดำเนินการเป้าหมายอยู่ทางด้านซ้ายของนิพจน์เหมือนกับที่อยู่ในคำสั่งการมอบหมาย
David R Tribble

2
@ MarkHarrison มันจะทำงานเหมือนกันไม่ใช่เพราะi++และprint iอยู่ในงบที่ต่างกัน แต่เพราะi++;และi<10เป็น คำพูดของ @ jonnyflash นั้นไม่ได้อยู่นอกฐาน สมมติว่าคุณมีและfor(int i=0; i++<10){ print i; } for(int i=0; ++i<10){ print i; }สิ่งเหล่านี้จะทำงานแตกต่างกันไปตามวิธีที่ @johnnyflash อธิบายไว้ในความคิดเห็นแรก
อดัม

3
@sam เนื่องจากในวงรอบปกติไม่มีผลข้างเคียง (เช่นการกำหนด) ในส่วน ++ i
Mark Harrison

175

i ++เรียกว่าPost Incrementในขณะที่++ iเรียกว่าPre Increment

i++

i++คือการเพิ่มขึ้นภายหลังเนื่องจากค่าที่เพิ่มขึ้นiเป็น 1 หลังจากการดำเนินการสิ้นสุดลง

ให้ดูตัวอย่างต่อไปนี้:

int i = 1, j;
j = i++;

ค่าของที่นี่แต่j = 1 i = 2ที่นี่ค่าของiจะถูกกำหนดให้jก่อนแล้วiจะเพิ่มขึ้น

++i

++iเป็นการเพิ่มค่าล่วงหน้าเนื่องจากค่าจะเพิ่มขึ้นi1 ก่อนการดำเนินการ มันหมายความว่าจะดำเนินการหลังจากที่j = i;i++

ให้ดูตัวอย่างต่อไปนี้:

int i = 1, j;
j = ++i;

ค่าของที่นี่แต่j = 2 i = 2นี่ค่าของiจะถูกกำหนดให้jหลังจากที่i incremention iของ ในทำนองเดียวกัน++iจะถูกประหารชีวิตก่อนj=i;จะได้รับการดำเนินการก่อน

สำหรับคำถามของคุณ ที่ควรใช้ในบล็อกการเพิ่มของ for for loop คำตอบคือคุณสามารถใช้สิ่งใดก็ได้ .. ไม่สำคัญ มันจะดำเนินการของคุณสำหรับวงเดียวไม่ ครั้ง

for(i=0; i<5; i++)
   printf("%d ",i);

และ

for(i=0; i<5; ++i)
   printf("%d ",i);

ลูปทั้งสองจะให้ผลลัพธ์เหมือนกัน 0 1 2 3 4กล่าวคือ

มันสำคัญเฉพาะที่ที่คุณใช้งาน

for(i = 0; i<5;)
    printf("%d ",++i);

1 2 3 4 5ในกรณีนี้จะมีการส่งออก


1
การเริ่มต้นตัวแปรหลังจากคำนำหน้าและการแก้ไขภายหลังช่วยให้เข้าใจได้ ขอบคุณ
Abdul Alim Shakir

42

โปรดอย่ากังวลเกี่ยวกับ "ประสิทธิภาพ" (ความเร็วจริง ๆ ) ที่เร็วกว่า เรามีคอมไพเลอร์ในทุกวันนี้ที่ดูแลสิ่งเหล่านี้ ใช้อย่างใดอย่างหนึ่งทำให้รู้สึกที่จะใช้ขึ้นอยู่กับที่แสดงให้เห็นถึงความตั้งใจของคุณอย่างชัดเจนมากขึ้น


1
ที่ฉันหวังว่าหมายถึง ' ใช้คำนำหน้า (inc | dec) rement เว้นแต่คุณต้องการค่าเก่าก่อน (inc | dec) จริง ๆ ซึ่งคนน้อยมากที่ทำ สร้างลัทธิขนส่งสินค้าของผู้ใช้ postfix ที่ไม่รู้ด้วยซ้ำว่า '.. !
underscore_d

ฉันไม่แน่ใจว่า "คอมไพเลอร์ทุกวันนี้ ... ดูแลสิ่งเหล่านี้" เป็นความจริงในระดับสากล ภายในกำหนดเองoperator++(int)(รุ่น postfix) รหัสสวยมากมีการสร้างชั่วคราวซึ่งจะถูกส่งกลับ คุณแน่ใจหรือไม่ว่าคอมไพเลอร์สามารถเพิ่มประสิทธิภาพให้อยู่เสมอ
ปีเตอร์ - Reinstate Monica

36

++i เพิ่มค่าจากนั้นส่งคืน

i++ ส่งคืนค่าแล้วเพิ่มขึ้น

มันเป็นความแตกต่างที่ลึกซึ้ง

สำหรับ a สำหรับ loop ให้ใช้++iเนื่องจากมันเร็วขึ้นเล็กน้อย i++จะสร้างสำเนาพิเศษที่เพิ่งถูกโยนทิ้งไป


23
ฉันไม่ได้ตระหนักถึงคอมไพเลอร์ใด ๆ ที่มันสร้างความแตกต่างสำหรับจำนวนเต็มอย่างน้อย
blabla999

4
มันเป็นไม่ได้เร็วขึ้น ค่าจะถูกละเว้น (เฉพาะผลข้างเคียงที่มีประสิทธิภาพ) และคอมไพเลอร์สามารถ / จะสร้างรหัสเดียวกันทั้งหมด
wildplasser

31

i++: ในภาพจำลองนี้จะมีการกำหนดค่าก่อนจากนั้นจึงเกิดการเพิ่มขึ้น

++i: ในสถานการณ์นี้ก่อนการเพิ่มจะทำแล้วกำหนดค่า

ด้านล่างคือการสร้างภาพและนี่เป็นวิดีโอที่ใช้งานได้ดีซึ่งแสดงให้เห็นเหมือนกัน

ป้อนคำอธิบายรูปภาพที่นี่


คุณจะเพิ่มขึ้นเล็กน้อยได้อย่างไร
kouty

@kouty คุณสามารถเพิ่มการลงทะเบียนที่ไม่ได้กำหนดให้กับตัวแปร
Polluks

20

เหตุผล++i อาจเร็วกว่าเล็กน้อยi++นั่นคือi++อาจต้องใช้สำเนาของค่า i ก่อนที่จะเพิ่มขึ้นในขณะที่++iไม่เคยทำ ในบางกรณีคอมไพเลอร์บางตัวจะปรับมันให้เหมาะสมถ้าเป็นไปได้ ... แต่มันก็เป็นไปไม่ได้เสมอไปและคอมไพเลอร์บางตัวก็ไม่ทำเช่นนี้

ผมพยายามที่จะไม่พึ่งพามากเกินไปในการคอมไพเลอร์เพิ่มประสิทธิภาพดังนั้นฉันทำตามคำแนะนำไรอันของฟ็อกซ์: ++iเมื่อฉันสามารถใช้ทั้งผมใช้


11
-1 สำหรับคำถาม C ++ สำหรับคำถาม C มีไม่มาก "คัดลอกท้องถิ่น" ของมูลค่าของiกว่ามีมูลค่า 1 1;เมื่อคุณเขียนคำสั่ง
. GitHub หยุดช่วยน้ำแข็ง

14

ผลลัพธ์ที่มีประสิทธิภาพของการใช้อย่างใดอย่างหนึ่งในลูปเหมือนกัน กล่าวอีกนัยหนึ่งการวนซ้ำจะทำสิ่งเดียวกันทั้งสองกรณี

ในแง่ของประสิทธิภาพอาจมีบทลงโทษที่เกี่ยวข้องกับการเลือก i ++ over ++ i ในแง่ของข้อมูลจำเพาะภาษาการใช้ตัวดำเนินการภายหลังการเพิ่มควรสร้างสำเนาเพิ่มเติมของค่าที่ตัวดำเนินการกำลังทำหน้าที่ นี่อาจเป็นแหล่งที่มาของการดำเนินการพิเศษ

อย่างไรก็ตามคุณควรพิจารณาปัญหาหลักสองข้อด้วยตรรกะก่อนหน้านี้

  1. คอมไพเลอร์สมัยใหม่นั้นยอดเยี่ยม คอมไพเลอร์ที่ดีทุกตัวนั้นฉลาดพอที่จะรู้ว่ามันเห็นการเพิ่มจำนวนเต็มใน for-loop และมันจะปรับทั้งสองวิธีให้เป็นโค้ดที่มีประสิทธิภาพเดียวกัน หากใช้การเพิ่มภายหลังการเพิ่มก่อนการเพิ่มจริงทำให้โปรแกรมของคุณมีเวลาทำงานช้าลงแสดงว่าคุณกำลังใช้คอมไพเลอร์แย่มาก

  2. ในแง่ของความซับซ้อนของเวลาในการปฏิบัติงานทั้งสองวิธี (แม้ว่าสำเนาจะถูกดำเนินการจริง) จะเทียบเท่ากัน จำนวนคำสั่งที่กำลังดำเนินการภายในลูปนั้นจะต้องควบคุมจำนวนการดำเนินการในการดำเนินการเพิ่มขึ้นอย่างมาก ดังนั้นในทุกขนาดที่มีนัยสำคัญการลงโทษของวิธีการเพิ่มจะถูกบดบังอย่างหนาแน่นโดยการดำเนินการของร่างกายลูป กล่าวอีกนัยหนึ่งคุณดีกว่ากังวลเกี่ยวกับการปรับรหัสในลูปแทนที่จะเพิ่มขึ้น

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

นี่คือตัวอย่างที่เป็นแก่นสารของการปรับให้เหมาะสมก่อนเวลาอันควรและปัญหาเช่นนี้มีศักยภาพที่จะเบี่ยงเบนความสนใจเราจากปัญหาร้ายแรงในการออกแบบ ยังคงเป็นคำถามที่ดีที่จะถามอย่างไรก็ตามเนื่องจากไม่มีความสม่ำเสมอในการใช้งานหรือฉันทามติใน "วิธีปฏิบัติที่ดีที่สุด"


13

พวกเขาทั้งสองเพิ่มจำนวน เทียบเท่ากับ++ii = i + 1

i++และ++iคล้ายกันมาก แต่ไม่เหมือนกันทุกประการ ทั้งสองเพิ่มจำนวน แต่++iเพิ่มจำนวนก่อนการแสดงออกปัจจุบันจะถูกประเมินในขณะที่i++เพิ่มจำนวนหลังจากการแสดงออกการประเมิน

ตัวอย่าง:

int i = 1;
int x = i++; //x is 1, i is 2
int y = ++i; //y is 3, i is 3

8

++i(คำนำหน้าการดำเนินงาน) ที่เพิ่มและจากนั้นกำหนดค่า
(เช่น) int i = 5, int b = ++i ในกรณีนี้ 6 ได้รับมอบหมายให้ b ก่อนแล้วเพิ่มขึ้นถึง 7 และอื่น ๆ

i++(การทำงาน Postfix): กำหนดแล้วเพิ่มค่า
(เช่น) int i = 5,int b = i++ ในกรณีนี้ 5 ได้รับมอบหมายให้ b ก่อนแล้วเพิ่มขึ้นถึง 6 และอื่น ๆ

Incase of for loop: i++ส่วนใหญ่จะใช้เพราะโดยปกติแล้วเราจะใช้ค่าเริ่มต้นของiก่อนที่จะเพิ่มขึ้นสำหรับวง แต่อาจแตกต่างกันไปขึ้นอยู่กับตรรกะของโปรแกรมของคุณ


7

++i: เป็นการเพิ่มขึ้นล่วงหน้าส่วนอีกอันคือการเพิ่มขึ้นภายหลัง

i++: รับองค์ประกอบแล้วเพิ่มขึ้น
++i: เพิ่มค่า i จากนั้นส่งคืนองค์ประกอบ

ตัวอย่าง:

int i = 0;
printf("i: %d\n", i);
printf("i++: %d\n", i++);
printf("++i: %d\n", ++i);

เอาท์พุท:

i: 0
i++: 0
++i: 2

5

ฉันคิดว่าคุณเข้าใจความแตกต่างในความหมายในขณะนี้ (แม้ว่าโดยสุจริตฉันสงสัยว่าทำไมผู้คนถามคำถาม 'ผู้ดำเนินการ X หมายถึง' ในกองล้นมากกว่าแทนที่จะอ่านคุณรู้หนังสือหรือเว็บกวดวิชาหรืออะไร

แต่อย่างไรก็ตามเท่าที่ควรใช้ให้เพิกเฉยต่อคำถามเกี่ยวกับประสิทธิภาพซึ่งไม่น่าจะมีความสำคัญแม้แต่ใน C ++ นี่คือหลักการที่คุณควรใช้เมื่อตัดสินใจว่าจะใช้:

พูดในสิ่งที่คุณหมายถึงในรหัส

หากคุณไม่ต้องการมูลค่าเพิ่มขึ้นก่อนในคำสั่งของคุณอย่าใช้รูปแบบของผู้ดำเนินการนั้น มันเป็นปัญหาเล็กน้อย แต่ถ้าคุณทำงานกับไกด์นำเที่ยวที่ห้ามแบนหนึ่งเวอร์ชั่นแทนอันอื่น ๆ (หรือที่รู้จักกันในนามไกด์นำกระดูก) คุณควรใช้แบบฟอร์มที่แสดงว่าคุณกำลังพยายามทำอะไรมากที่สุด

QED ใช้รุ่นเพิ่มล่วงหน้า:

for (int i = 0; i != X; ++i) ...

5

ความแตกต่างสามารถเข้าใจได้โดยรหัส C ++ แบบง่าย ๆ ด้านล่าง:

int i, j, k, l;
i = 1; //initialize int i with 1
j = i+1; //add 1 with i and set that as the value of j. i is still 1
k = i++; //k gets the current value of i, after that i is incremented. So here i is 2, but k is 1
l = ++i; // i is incremented first and then returned. So the value of i is 3 and so does l.
cout << i << ' ' << j << ' ' << k << ' '<< l << endl;
return 0;

5

ความแตกต่างหลักคือ

  • i ++ โพสต์ ( หลังเพิ่ม ) และ
  • ++ i พื้นฐาน ( ก่อนเพิ่ม )

    • โพสต์ถ้าi =1 ห่วงเพิ่มขึ้นเช่น1,2,3,4,n
    • ก่อนถ้าi =1 ห่วงเพิ่มขึ้นเช่น2,3,4,5,n

5

i ++ และ ++ i

รหัสเล็กน้อยนี้อาจช่วยให้เห็นภาพความแตกต่างจากมุมที่แตกต่างจากคำตอบที่โพสต์แล้ว:

int i = 10, j = 10;

printf ("i is %i \n", i);
printf ("i++ is %i \n", i++);
printf ("i is %i \n\n", i);

printf ("j is %i \n", j);
printf ("++j is %i \n", ++j);
printf ("j is %i \n", j);

ผลลัพธ์ที่ได้คือ:

//Remember that the values are i = 10, and j = 10

i is 10 
i++ is 10     //Assigns (print out), then increments
i is 11 

j is 10 
++j is 11    //Increments, then assigns (print out)
j is 11 

ให้ความสนใจกับสถานการณ์ก่อนและหลัง

สำหรับวง

สำหรับที่หนึ่งในนั้นควรใช้ในการเพิ่มบล็อกของ for for loop ฉันคิดว่าสิ่งที่ดีที่สุดที่เราสามารถทำการตัดสินใจคือใช้ตัวอย่างที่ดี:

int i, j;

for (i = 0; i <= 3; i++)
    printf (" > iteration #%i", i);

printf ("\n");

for (j = 0; j <= 3; ++j)
    printf (" > iteration #%i", j);

ผลลัพธ์ที่ได้คือ:

> iteration #0 > iteration #1 > iteration #2 > iteration #3
> iteration #0 > iteration #1 > iteration #2 > iteration #3 

ฉันไม่รู้เกี่ยวกับคุณ แต่ฉันไม่เห็นความแตกต่างในการใช้งานของมันอย่างน้อยก็ต่อเนื่อง


5

ส่วนรหัส C ต่อไปนี้แสดงให้เห็นถึงความแตกต่างระหว่างตัวเพิ่มก่อนและหลังตัวดำเนินการและตัวลดค่า:

int  i;
int  j;

ผู้ประกอบการที่เพิ่มขึ้น:

i = 1;
j = ++i;    // i is now 2, j is also 2
j = i++;    // i is now 3, j is 2

4

การสร้างล่วงหน้าหมายถึงการเพิ่มในบรรทัดเดียวกัน การเพิ่มขึ้นภายหลังหมายถึงการเพิ่มขึ้นหลังจากที่บรรทัดทำงาน

int j=0;
System.out.println(j); //0
System.out.println(j++); //0. post-increment. It means after this line executes j increments.

int k=0;
System.out.println(k); //0
System.out.println(++k); //1. pre increment. It means it increments first and then the line executes

เมื่อมาพร้อมกับตัวดำเนินการ OR และ AND มันจะน่าสนใจยิ่งขึ้น

int m=0;
if((m == 0 || m++ == 0) && (m++ == 1)) { //false
/* in OR condition if first line is already true then compiler doesn't check the rest. It is technique of compiler optimization */
System.out.println("post-increment "+m);
}

int n=0;
if((n == 0 || n++ == 0) && (++n == 1)) { //true
System.out.println("pre-increment "+n); //1
}

ในอาเรย์

System.out.println("In Array");
int[] a = { 55, 11, 15, 20, 25 } ;
int ii, jj, kk = 1, mm;
ii = ++a[1]; // ii = 12. a[1] = a[1] + 1
System.out.println(a[1]); //12

jj = a[1]++; //12
System.out.println(a[1]); //a[1] = 13

mm = a[1];//13
System.out.printf ( "\n%d %d %d\n", ii, jj, mm ) ; //12, 12, 13

for (int val: a) {
     System.out.print(" " +val); //55, 13, 15, 20, 25
}

ใน C ++ โพสต์ / การเพิ่มขึ้นของตัวแปรพอยน์เตอร์

#include <iostream>
using namespace std;

int main() {

    int x=10;
    int* p = &x;

    std::cout<<"address = "<<p<<"\n"; //prints address of x
    std::cout<<"address = "<<p<<"\n"; //prints (address of x) + sizeof(int)
    std::cout<<"address = "<<&x<<"\n"; //prints address of x

    std::cout<<"address = "<<++&x<<"\n"; //error. reference can't re-assign because it is fixed (immutable)
}

4

ไม่นาน:

++iและใช้i++งานได้เหมือนกันถ้าคุณไม่ได้เขียนมันในฟังก์ชั่น หากคุณใช้สิ่งที่ชอบfunction(i++)หรือfunction(++i)คุณสามารถเห็นความแตกต่าง

function(++i)กล่าวว่าการเพิ่มขึ้นครั้งแรกฉันโดย 1 หลังจากนั้นใส่สิ่งนี้iลงในฟังก์ชั่นด้วยค่าใหม่

function(i++)กล่าวว่าใส่ครั้งแรกiในฟังก์ชั่นหลังจากที่เพิ่มขึ้นi1

int i=4;
printf("%d\n",pow(++i,2));//it prints 25 and i is 5 now
i=4;
printf("%d",pow(i++,2));//it prints 16 i is 5 now

2
ความแตกต่างไม่ได้ผูกติดกับการเรียกใช้ฟังก์ชัน (และคุณสามารถเห็นความแตกต่างได้โดยไม่ต้องเรียกใช้ฟังก์ชัน) มีความแตกต่างระหว่างint j = ++i;และint k = i++;แม้เมื่อไม่มีการเรียกใช้ฟังก์ชันที่เกี่ยวข้อง
Jonathan Leffler

3

ข้อแตกต่างเพียงอย่างเดียวคือลำดับของการดำเนินการระหว่างการเพิ่มขึ้นของตัวแปรและค่าที่ผู้ประกอบการส่งกลับ

รหัสนี้และผลลัพธ์มันอธิบายความแตกต่าง:

#include<stdio.h>

int main(int argc, char* argv[])
{
  unsigned int i=0, a;
  a = i++;
  printf("i before: %d; value returned by i++: %d, i after: %d\n", i, a, i);
  i=0;
  a = ++i;
  printf("i before: %d; value returned by ++i: %d, i after: %d\n", i, a, i);
}

ผลลัพธ์คือ:

i before: 1; value returned by i++: 0, i after: 1
i before: 1; value returned by ++i: 1, i after: 1

ดังนั้นโดยทั่วไป++iจะคืนค่าหลังจากที่เพิ่มขึ้นในขณะที่++iคืนค่าก่อนที่จะเพิ่มขึ้น ในตอนท้ายทั้งสองกรณีiจะมีมูลค่าเพิ่มขึ้น

ตัวอย่างอื่น:

#include<stdio.h>

int main ()
  int i=0;
  int a = i++*2;
  printf("i=0, i++*2=%d\n", a);
  i=0;
  a = ++i * 2;
  printf("i=0, ++i*2=%d\n", a);
  i=0;
  a = (++i) * 2;
  printf("i=0, (++i)*2=%d\n", a);
  i=0;
  a = (++i) * 2;
  printf("i=0, (++i)*2=%d\n", a);
  return 0;
}

เอาท์พุท:

i=0, i++*2=0
i=0, ++i*2=2
i=0, (++i)*2=2
i=0, (++i)*2=2

หลายครั้งที่ไม่มีความแตกต่าง

ความแตกต่างนั้นชัดเจนเมื่อค่าที่ส่งคืนถูกกำหนดให้กับตัวแปรอื่นหรือเมื่อมีการดำเนินการเพิ่มขึ้นในการต่อเชื่อมกับการดำเนินการอื่น ๆ ที่มีการใช้การดำเนินการก่อนหน้านี้ ( i++*2ต่างจาก++i*2แต่(i++)*2และ(++i)*2ส่งกลับค่าเดียวกัน) ในหลาย ๆ กรณี ตัวอย่างคลาสสิกเป็นไวยากรณ์สำหรับห่วง:

for(int i=0; i<10; i++)

มีผลเหมือนกันของ

for(int i=0; i<10; ++i)

กฎที่ต้องจำ

เพื่อไม่ให้เกิดความสับสนระหว่างผู้ให้บริการสองรายฉันได้ใช้กฎนี้:

เชื่อมโยงตำแหน่งของโอเปอเรเตอร์ที่++เกี่ยวข้องกับตัวแปรiตามลำดับของการ++ดำเนินการที่เกี่ยวข้องกับการมอบหมาย

กล่าวอีกนัยหนึ่ง:

  • ++ ก่อนที่จะ iหมายถึงการเพิ่มจะต้องดำเนินการก่อนที่จะได้รับมอบหมาย;
  • ++ หลังจาก iหมายถึงการเพิ่มจะต้องดำเนินการหลังจากที่ได้รับมอบหมาย:

3

คุณสามารถคิดของการแปลงภายในของที่เป็นงบหลาย ;

  • กรณีที่ 1
i++;

คุณสามารถคิดว่ามันเป็น

i;
i = i+1;
  • กรณีที่ 2
++i;

คุณสามารถคิดว่ามันเป็น

i = i+i;
i;

-3

a = i ++ หมายถึง a ประกอบด้วยค่า i ปัจจุบัน a = ++ i หมายถึง a ประกอบด้วยค่า i ที่เพิ่มขึ้น


10
คำตอบนี้ไม่ถูกต้อง a = i++;หมายถึงค่าที่เก็บไว้ในaจะเป็นค่าของiก่อนที่จะเพิ่มขึ้น แต่ 'โดยไม่ต้องเพิ่ม' หมายถึงที่iไม่ได้เพิ่มขึ้นซึ่งเป็นความผิดที่สมบูรณ์ - iจะเพิ่มขึ้น แต่ค่าของการแสดงออกเป็นมูลค่าก่อนที่จะเพิ่มขึ้น
Jonathan Leffler

-6

นี่คือตัวอย่างเพื่อทำความเข้าใจความแตกต่าง

int i=10;
printf("%d %d",i++,++i);

เอาท์พุท: 10 12/11 11(ขึ้นอยู่กับลำดับของการประเมินผลการขัดแย้งกับprintfฟังก์ชั่นซึ่งแตกต่างกันไปในคอมไพเลอร์และสถาปัตยกรรม)

คำอธิบาย: i++-> iถูกพิมพ์จากนั้นเพิ่มขึ้น (พิมพ์ 10 แต่iจะกลายเป็น 11) ++i-> การiเพิ่มค่าและพิมพ์ค่า (พิมพ์ 12 และค่าเท่ากับi12)


11
สิ่งนี้ทำให้เกิดพฤติกรรมที่ไม่ได้กำหนดเนื่องจากไม่มีจุดลำดับระหว่างi++และ++i
MM

@Lundin นั้นถูกต้องแม้ว่า LHS, RHS ของเครื่องหมายจุลภาคจะมีจุดลำดับอยู่ระหว่างกัน แต่การแสดงออก 2 รายการยังคงไม่เกิดขึ้นพร้อมกัน
Antti Haapala
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.