ฉันมีคำถามคอมไพเลอร์ทำงานบนรหัสต่อไปนี้
#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++
คือค่าปัจจุบันของc
11 แยกต่างหากc
จะเพิ่มขึ้นเป็น 12b == 11
เป็นเท็จเนื่องจากb
เป็น 12(b == c++)
เป็นเท็จ(c-1)
ใช้ นอกจากนี้การเพิ่มขึ้นของc
12 จะต้องเสร็จสิ้นในจุดนี้c
12 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