การแปลงบูลเป็น int


131

การแปลงนี้เป็นแบบพกพาเพียงใด มั่นใจได้หรือไม่ว่าการยืนยันทั้งสองผ่าน

int x = 4<5;
assert(x==1);

x = 4>5;
assert(x==0);

อย่าถามว่าทำไม ฉันรู้ว่ามันน่าเกลียด ขอบคุณ.


ทำไมคุณไม่เปลี่ยนนิพจน์แรก assert(x!=0)คุณสามารถเขียน แม้ว่าบูล (จริง) จะแปลงแบบพกพาเป็น int (1) การยืนยัน "ไม่เท็จ" ก็มีนิพจน์ที่อ่านได้ง่ายกว่า
harper

1
ทำไมไม่: assert( 4 < 5);และassert(!( 4 > 5));
Martin York

4
@harper: การใช้ค่าที่ต้องการของนิพจน์การเปรียบเทียบนั้นสมเหตุสมผลอย่างยิ่ง
R .. GitHub STOP HELPING ICE

@ R._ เมื่อคำถามคือถ้าการแปลง bool-to-int ให้ผลลัพธ์ที่สมเหตุสมผลฉันจะไม่พึ่งพาสิ่งนี้ เมื่อผู้เขียนมีข้อสงสัยว่าข้อกำหนดนี้เต็มแล้วผู้อ่านอาจได้รับปัญหาเดียวกัน โดยเฉพาะอย่างยิ่งเนื่องจากค่าของ x ไม่ใช่เงื่อนไขในการตรวจสอบ แต่เป็นเพียงผลลัพธ์ระดับกลาง
harper

3
ฉันอาจจะเขียน(4 < 5) ? 1 : 0ว่าฉันต้องการแปลงบูลีนเป็น 0 หรือ 1 จริงๆคอมไพเลอร์ที่ดีน่าจะสร้างรหัสเครื่องเดียวกันและชัดเจนกว่าสำหรับผู้อ่านที่เป็นมนุษย์
ollb

คำตอบ:


205
int x = 4<5;

พกพาได้อย่างสมบูรณ์ ตามมาตรฐาน boolการintแปลงเป็นนัย!

§4.7 / 4 จากมาตรฐาน C ++ กล่าวว่า (Integral Conversion )

ถ้าชนิดมาเป็นบูลค่าที่falseจะถูกแปลงให้เป็นศูนย์และความคุ้มค่าจะถูกแปลงเป็นหนึ่งtrue


สำหรับ C เท่าที่ฉันรู้ว่าไม่มีboolใน C. (ก่อนปี 2542) ดังนั้นboolการintแปลงจึงเกี่ยวข้องกับ C ++ เท่านั้น ใน C, 4<5ประเมินintค่าในกรณีนี้มีค่าเป็น1, จะประเมิน4>5 0

แก้ไข: Jens ในความคิดเห็นกล่าวว่า C99 มี_Boolประเภท boolเป็นมาโครที่กำหนดไว้ในstdbool.hไฟล์ส่วนหัว trueและfalseยังกำหนดมาโครในstdbool.h.

§7.16จาก C99 พูดว่า

มาโครboolขยายเป็น _Bool

[ .. ] trueที่ขยายไปยังคงจำนวนเต็ม1, false ซึ่งจะขยายอย่างต่อเนื่องจำนวนเต็ม0[ .. ]


3
แน่ใจว่ามีboolใน C ตั้งแต่ปี 1999 เพียงใช้ส่วนหัว "stdbool.h" และควรรวมไว้ด้วย
Jens Gustedt

1
อันที่จริงฉันตรวจสอบในคอมไพเลอร์หลายตัวและดูเหมือนว่าจะพกพาได้
pic11

8
โดยไม่คำนึงถึงรุ่นของภาษา C และความพร้อมของbool/ _Boolประเภทผู้ประกอบการเชิงสัมพันธ์ใน C ผลิตไม่ได้int boolคือแม้ใน C99, intผู้ประกอบการเชิงสัมพันธ์ยังคงผลิต
AnT

51

คุณติดแท็กคำถาม [C] และ [C ++] พร้อมกัน ผลลัพธ์จะสอดคล้องกันระหว่างภาษา แต่โครงสร้างของคำตอบจะแตกต่างกันสำหรับแต่ละภาษาเหล่านี้

ในภาษาซีตัวอย่างของคุณไม่มีความสัมพันธ์กับboolสิ่งใด ๆ (ซึ่งใช้กับ C99 ด้วย) ในตัวดำเนินการเชิงสัมพันธ์ภาษาซีไม่ได้สร้างboolผลลัพธ์ ทั้งสอง4 > 5และ4 < 5มีการแสดงออกที่จะให้ผลลัพธ์จากประเภทintที่มีค่าหรือ0 1ดังนั้นจึงไม่มี "การแปลงบูลเป็น int" ใด ๆ เกิดขึ้นในตัวอย่างของคุณใน C

ในตัวดำเนินการเชิงสัมพันธ์ C ++ ให้boolผลลัพธ์แน่นอน boolมีค่าแปลงสภาพให้แก่intพิมพ์ด้วยtrueการแปลง1และแปลงไปfalse 0สิ่งนี้ได้รับการรับรองจากภาษา

ภาษา PS C ยังมีประเภทบูลีนโดยเฉพาะ_Bool(มาโครนามแฝงเป็นbool) และกฎการแปลงที่สำคัญก็เหมือนกับใน C ++ แต่อย่างไรก็ตามสิ่งนี้ไม่เกี่ยวข้องกับตัวอย่างเฉพาะของคุณใน C อีกครั้งตัวดำเนินการเชิงสัมพันธ์ใน C จะสร้างผลลัพธ์int(ไม่ใช่bool) เสมอโดยไม่คำนึงถึงเวอร์ชันของข้อกำหนดภาษา


2
ถูกต้องไม่มีบูลใน K&R C ฉันติดแท็กคำถามของฉันใหม่เป็น C99
pic11

@ pic11: ไม่จำเป็นต้องติดแท็กใหม่ มันมีอะไรจะทำอย่างไรกับ K & R หรือซีอื่น ๆ แม้ว่าจะมีboolใน C99, ผู้ประกอบการเชิงสัมพันธ์ยังคงผลิตintใน C99 boolไม่ ดังนั้นถ้ามันเป็นโดยเฉพาะผู้ประกอบการเชิงสัมพันธ์คุณมีความสนใจใน (ในขณะที่ตัวอย่างของคุณ) boolปัญหายังคงมีอะไรจะทำอย่างไรกับ
AnT

ตอนนี้ฉันเข้าใจแล้ว ผลลัพธ์ของตัวดำเนินการความสัมพันธ์แปลงโดยปริยายเป็น int นี่เป็นจริงใน C, C99 และ C ++ คิดใหม่อีกครั้ง
pic11

3
@ pic11: ไม่คุณไม่เข้าใจ ใน C รวมถึง C99 ผลลัพธ์ของตัวดำเนินการเปรียบเทียบคือinta ไม่ใช่ a bool. ไม่มีการแปลงเกิดขึ้น
R .. GitHub STOP HELPING ICE

มีวิธีใดบ้างที่เป็นไปตามมาตรฐานที่ภาษาอาจมีลักษณะที่คล้ายกันboolแต่ไม่อนุญาตให้นำที่อยู่ไปใช้? ระบบฝังตัวจำนวนมากใช้ประโยชน์จากประเภทดังกล่าว (มักประกาศโดยใช้ตัวระบุbit) เช่น PIC ระดับกลางif (bitVar1) bitVar2=1;จะเป็นสองคำสั่ง การเข้ารหัสที่ดีที่สุดif (byteVar1) byteVar2=1;คืออย่างน้อยสี่ตัว (ในคอมไพเลอร์หลายตัวอาจเป็นห้า) ประเภทดังกล่าวสามารถเพิ่มประสิทธิภาพที่สำคัญได้
supercat

17

มาตรา 6.5.8.6 ของมาตรฐาน C กล่าวว่า:

แต่ละตัวดำเนินการ <(น้อยกว่า),> (มากกว่า), <= (น้อยกว่าหรือเท่ากับ) และ> = (มากกว่าหรือเท่ากับ) จะให้ผล 1 ถ้าความสัมพันธ์ที่ระบุเป็นจริงและ 0 ถ้าเป็น เท็จ) ผลลัพธ์มีประเภท int


ขอบคุณสำหรับข้อมูลอ้างอิง ดูเหมือนว่าจริง == 1 ด้วยเหตุผลทางประวัติศาสตร์
pic11

2

ดูเหมือนว่าจะไม่มีปัญหาเนื่องจาก int to bool cast เสร็จสิ้นโดยปริยาย ใช้งานได้ในคอมไพเลอร์ Microsoft Visual C ++, GCC และ Intel C ++ ไม่มีปัญหาใน C หรือ C ++


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