ฉันมีคำถามคอมไพเลอร์ทำงานบนรหัสต่อไปนี้
#include<stdio.h>
int main(void)
{
int b=12, c=11;
int d = (b == c++) ? (c+1) : (c-1);
printf("d = %i\n", d);
}
d = 11ผมไม่แน่ใจว่าทำไมผลที่ได้คือ
ฉันมีคำถามคอมไพเลอร์ทำงานบนรหัสต่อไปนี้
#include<stdio.h>
int main(void)
{
int b=12, c=11;
int d = (b == c++) ? (c+1) : (c-1);
printf("d = %i\n", d);
}
d = 11ผมไม่แน่ใจว่าทำไมผลที่ได้คือ
คำตอบ:
ในint d = (b == c++) ? (c+1) : (c-1);:
c++คือค่าปัจจุบันของc11 แยกต่างหากcจะเพิ่มขึ้นเป็น 12b == 11เป็นเท็จเนื่องจากbเป็น 12(b == c++)เป็นเท็จ(c-1)ใช้ นอกจากนี้การเพิ่มขึ้นของc12 จะต้องเสร็จสิ้นในจุดนี้c12 c-1คือ 11d ถูกเตรียมใช้งานกับค่านั้น 11ตามมาตรฐาน C (6.5.15 ตัวดำเนินการแบบมีเงื่อนไข)
4 ตัวถูกดำเนินการแรกถูกประเมิน; มีจุดลำดับระหว่างการประเมินกับการประเมินของตัวถูกดำเนินการที่สองหรือสาม (แล้วแต่จำนวนใดจะถูกประเมิน) ตัวถูกดำเนินการตัวที่สองจะถูกประเมินเฉพาะเมื่อตัวแรกเปรียบเทียบไม่เท่ากันกับ 0 ตัวถูกดำเนินการตัวที่สามจะถูกประเมินเฉพาะเมื่อตัวแรกเปรียบเทียบเท่ากับ 0; ผลที่ได้คือมูลค่าของตัวถูกดำเนินการที่สองหรือสาม (แล้วแต่จำนวนใดจะถูกประเมิน) แปลงเป็นประเภทที่อธิบายด้านล่าง 195
ดังนั้นในการเริ่มต้นการแสดงออกของการประกาศนี้
int d = (b == c++) ? (c+1) : (c-1);
ตัวแปรbจะถูกเปรียบเทียบกับค่าของตัวแปรcเนื่องจากตัวดำเนินการภายหลังการเพิ่มจะส่งคืนค่าของตัวถูกดำเนินการก่อนที่จะเพิ่มขึ้น
เนื่องจากค่าไม่เท่ากัน ( bตั้งค่าเป็น 12 ในขณะที่cตั้งค่าเป็น 11) ดังนั้นนิพจน์ย่อย(c-1)จะถูกประเมิน
ตามคำพูดมีจุดลำดับหลังจากการประเมินสภาพของผู้ประกอบการ มันหมายความว่าหลังจากการประเมินผลของสภาพcมีค่าหลังจากที่ใช้ประกอบการโพสต์ที่เพิ่มขึ้นให้กับตัวแปร12 cผลที่ตามมาคือตัวแปร d ถูกเตรียมใช้งานโดยค่า1( 12 - 1)
?:เฉพาะกรณีนี้จะต้องตอบโดยกล่าวถึงจุดลำดับ เพราะโดยปกติใน C การรวม++กับการดำเนินการอื่น ๆ ในตัวถูกดำเนินการเดียวกันคือพฤติกรรมที่ไม่ได้กำหนด และรหัสนี้ใช้งานได้อย่างคาดเดาได้เนื่องจาก?:มีกฎเกล็ดหิมะพิเศษหลายแบบ
เพราะว่าเงื่อนไขเป็นเท็จดังนั้นfalseกรณีที่จะเกิดขึ้นc-1แต่เนื่องจากคุณเพิ่มขึ้นcในสภาพโดยc++จึงอยู่ในขณะนี้c 12ผลลัพธ์จึง 12 - 1 ซึ่งคือ 11
แก้ไข: สิ่งที่ OP เข้าใจผิดคือการเพิ่มโพสต์
ดังนั้นสิ่งที่เกิดขึ้นจริงเป็นเช่นนี้:
#include<stdio.h>
int main(void)
{
int b=12, c=11;
int d;
if (b == c) { // 12 == 11 ? -> false
c = c + 1;
d = c + 1;
} else { // this executes since condition is false
c = c + 1; // post increment -> c++ -> c = 12 now
d = c - 1; // 12 - 1 = 11 -> d = 11
}
printf("d = %i\n", d);
}
c++ตามเงื่อนไข เงื่อนไขเป็นเท็จ แต่จากนั้นจะใช้ค่าเดิมของcการคำนวณc - 1ไม่ใช่เวอร์ชันที่เพิ่มขึ้น
c++และ++c
c++เป็นผู้ประกอบการหลังการขาย ค่าของc++11 c == 12กับผลข้างเคียงของการทำ ++cจะมีค่า 12
แปลเป็น if-statement แบบปกติแล้วโค้ดของคุณจะเป็นดังนี้:
int b=12, c=11;
int d;
if (b == c++)
d = c+1;
else
d = c-1;
เงื่อนงำที่นี่คือ c เพิ่มขึ้นหลังจากตรวจสอบเงื่อนไข คุณป้อนelseสถานะ แต่ c มีค่า 12 อยู่แล้ว
อ้างถึงผู้ประกอบการ Ternary
วากยสัมพันธ์
เงื่อนไข ? value_if_true: value_if_false
ดังนั้นคุณเขียน
int d = (b == c++) ? (c+1) : (c-1);
ในสถานการณ์นี้ผลลัพธ์จะเป็น 11 เนื่องจากหลังจากตรวจสอบค่า 'c' จะเพิ่มขึ้น (c + 1 = 12) และหลังจากนั้นจะตั้งค่า 'd' เป็น c (12) -1 ซึ่งเท่ากับ 11
ถ้าคุณใช้เช่น:
int d = (b == ++c) ? (c+1) : (c-1);
ค่า "c" จะเพิ่มขึ้นก่อนที่จะตรวจสอบคำสั่งดังนั้นจึงเป็นจริงและค่า "d" จะเป็น c (12) +1 ซึ่งเท่ากับ 13