การใช้ค่าบูลีนใน C


703

C ไม่มีบูลีนในตัวชนิดใด ๆ วิธีที่ดีที่สุดที่จะใช้ใน C คืออะไร?


73
C มีประเภทบูลีน อย่างน้อยก็มีหนึ่งในมาตรฐานล่าสุด
AraK

คำตอบ:


1050

จากดีที่สุดถึงแย่กว่า:

ตัวเลือก 1 (C99)

#include <stdbool.h>

ตัวเลือก 2

typedef enum { false, true } bool;

ตัวเลือก 3

typedef int bool;
enum { false, true };

ตัวเลือก 4

typedef int bool;
#define true 1
#define false 0

คำอธิบาย

  • ตัวเลือก 1 จะใช้งานได้ต่อเมื่อคุณใช้ C99 และเป็น "วิธีมาตรฐาน" ในการดำเนินการ เลือกรายการนี้ถ้าเป็นไปได้
  • ตัวเลือกที่ 2, 3 และ 4 จะมีพฤติกรรมเหมือนกันในทางปฏิบัติ # 2 และ # 3 ไม่ได้ใช้ #defines แต่ในความคิดของฉันดีกว่า

หากคุณยังไม่แน่ใจให้ไปที่ # 1!


1
คุณช่วยอธิบายได้ไหมว่าทำไมพวกเขาถึงดีที่สุดถึงตัวเลือกที่แย่ที่สุด?
endolith

1
@endolith การจัดตำแหน่งการปรับให้เหมาะสมและวิธีการจัดเก็บ<stdbool.h> boolคอมไพเลอร์เลือกอาจเหมาะสมกว่าสำหรับวัตถุประสงค์ที่ตั้งใจไว้ของค่าบูลีนมากกว่าการใช้int(เช่นคอมไพเลอร์อาจเลือกใช้งานที่boolแตกต่างจากint) นอกจากนี้ยังอาจส่งผลให้การตรวจสอบประเภทที่เข้มงวดยิ่งขึ้นในเวลารวบรวมหากคุณโชคดี
blubberdiblub

1
ทำไมต้องใช้intสำหรับbool? นั่นช่างสิ้นเปลือง unsigned charใช้ _Boolหรือใช้ในตัวของ C
user12211554

@NoBody การใช้ตัวพิมพ์ขนาดเล็กลงสามารถบันทึกลงในหน่วยความจำได้ แต่อาจไม่ทำให้เร็วขึ้น บ่อยครั้งที่เร็วกว่าที่จะใช้ขนาดคำดั้งเดิมของโปรเซสเซอร์แทนขนาดที่เล็กลงเนื่องจากอาจต้องใช้คอมไพเลอร์เพื่อทำการเลื่อนบิตเพื่อจัดตำแหน่งอย่างถูกต้อง
Ted Klein Bergman

241

ความคิดเล็กน้อยเกี่ยวกับบูลีนใน C:

ฉันแก่พอที่ฉันจะใช้ints ธรรมดาเป็นประเภทบูลของฉันโดยไม่มีการพิมพ์หรือกำหนดหรือ enums พิเศษสำหรับค่าจริง / เท็จ หากคุณทำตามคำแนะนำของฉันด้านล่างนี้อย่าเปรียบเทียบกับค่าคงที่บูลีนคุณจะต้องใช้ 0/1 เพื่อเริ่มต้นค่าสถานะอย่างไรก็ตาม อย่างไรก็ตามวิธีการดังกล่าวอาจถือว่าเป็นปฏิกิริยาเกินไปในยุคปัจจุบันเหล่านี้ ในกรณีนี้เราควรใช้อย่างแน่นอน<stdbool.h>เพราะอย่างน้อยก็มีประโยชน์ในการเป็นมาตรฐาน

ไม่ว่าค่าคงที่บูลีนจะถูกเรียกให้ใช้มันเพื่อการเริ่มต้นเท่านั้น ไม่เคยเขียนอะไรเช่น

if (ready == TRUE) ...
while (empty == FALSE) ...

สิ่งเหล่านี้สามารถถูกแทนที่ได้โดยชัดเจนยิ่งขึ้น

if (ready) ...
while (!empty) ...

โปรดทราบว่าสิ่งเหล่านี้สามารถอ่านออกมาได้อย่างสมเหตุสมผลและสมเหตุสมผล

ให้ตัวแปรบูลของคุณชื่อในเชิงบวกคือแทนfull notfullหลังนำไปสู่รหัสที่อ่านยาก เปรียบเทียบ

if (full) ...
if (!full) ...

กับ

if (!notfull) ...
if (notfull) ...

คู่ก่อนหน้าทั้งคู่อ่านอย่างเป็นธรรมชาติในขณะ!notfullที่อ่านได้ไม่สะดวกเท่าที่ควร

โดยทั่วไปแล้วควรหลีกเลี่ยงการโต้แย้งบูลีน พิจารณาฟังก์ชั่นที่กำหนดเช่นนี้

void foo(bool option) { ... }

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

foo(TRUE);
foo(FALSE):

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

typedef enum { OPT_ON, OPT_OFF } foo_option;
void foo(foo_option option);

หรือ

#define OPT_ON true
#define OPT_OFF false
void foo(bool option) { ... }

ไม่ว่าในกรณีใดไซต์โทรจะมีลักษณะเช่นนี้

foo(OPT_ON);
foo(OPT_OFF);

fooซึ่งผู้อ่านมีอย่างน้อยโอกาสของความเข้าใจโดยไม่ต้องขุดลอกขึ้นความหมายของการเป็น


1
และคุณจะเปรียบเทียบตัวแปรสองตัวเพื่อความเท่าเทียมกันได้อย่างไร ไม่เคยใช้ค่าคงที่บูลีนทำงานได้ดี แต่ก็ไม่ได้แก้ปัญหาเมื่อเปรียบเทียบกับค่าคงที่
บารุค

ยกโทษให้ฉัน แต่ฉันไม่เข้าใจคำถาม คุณกำลังถามว่าฉันจะเปรียบเทียบตัวแปรบูลีนสองตัวเพื่อความเท่าเทียมกันอย่างไร ถ้าเป็นเช่นนั้นไม่a == bทำงาน
Dale Hagglund

5
@Kenji สิ่งที่คุณพูดนั้นเป็นความจริงแม้ว่าฉันเชื่อว่าการใช้ค่าอื่นที่ไม่ใช่ค่าที่เทียบเท่ากับความจริงนั้นเป็นความคิดที่เลว ในตัวอย่างของคุณสมมติว่า aและbนับจากศูนย์ฉันขอแนะนำa > 0 == b > 0แทน หากคุณยืนยันในการใช้ประโยชน์จากความเป็นจริงของค่าที่ไม่เป็นศูนย์โดยพลการให้ค่า!!varบูลีน 0/1 เทียบเท่ากับvarดังนั้นคุณสามารถเขียน!!a == !!bแม้ว่าผู้อ่านจำนวนน้อยจะรู้สึกสับสน
Dale Hagglund

3
!a == !bก็เพียงพอสำหรับการทดสอบความเท่าเทียมกันไม่ใช่ศูนย์กลายเป็นศูนย์และศูนย์กลายเป็นหนึ่ง
ryanpattison

5
@ rpattiso คุณพูดถูก แต่ฉันคิดว่าฉันจะอ่าน!!aว่า "แปลงไม่ใช่บูลีนเป็นค่าความจริงที่เทียบเท่ากัน" ในขณะที่ฉันอ่าน!aว่า "เปลี่ยนตรรกะบูลีนเป็นตรรกะ" โดยเฉพาะฉันต้องการเหตุผลบางอย่างที่ต้องการการผกผันแบบตรรกะ
Dale Hagglund

88

บูลีนใน C เป็นจำนวนเต็ม: ศูนย์สำหรับเท็จและไม่เป็นศูนย์สำหรับจริง

ดูเพิ่มเติมชนิดข้อมูลแบบบูลส่วนC, C ++, Objective-C, AWK


มันทำงานได้ดีกับตัวดำเนินการเชิงตรรกะเช่นกัน (&& และ ||)
Vultrao

74

นี่คือรุ่นที่ฉันใช้:

typedef enum { false = 0, true = !false } bool;

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

สิ่งนี้จะดูแลปัญหาของคนที่เข้ารหัสสิ่งที่จะลงมา:

if (true == !false)

ฉันคิดว่าเราทุกคนเห็นด้วยว่านั่นไม่ใช่วิธีปฏิบัติที่ดี แต่สำหรับค่าใช้จ่ายครั้งเดียวในการทำ "true =! false" เรากำจัดปัญหานั้น

[แก้ไข] ในที่สุดฉันใช้:

typedef enum { myfalse = 0, mytrue = !myfalse } mybool;

เพื่อหลีกเลี่ยงการชนชื่อกับแผนการอื่นที่กำหนดtrueและfalseและแต่แนวคิดยังคงเหมือนเดิม

[แก้ไข] วิธีแสดงการแปลงจำนวนเต็มเป็นบูลีน:

mybool somebool;
int someint = 5;
somebool = !!someint;

ครั้งแรก (ขวาสุด)! แปลงจำนวนเต็มที่ไม่ใช่ศูนย์เป็น 0 จากนั้นเป็นวินาที (เหลือมากที่สุด)! แปลง 0 เป็น amyfalseค่า ฉันจะปล่อยให้มันเป็นแบบฝึกหัดให้ผู้อ่านแปลงจำนวนเต็มเป็นศูนย์

[แก้ไข] มันเป็นสไตล์ของฉันที่จะใช้การตั้งค่าที่ชัดเจนของค่าใน enum เมื่อจำเป็นต้องใช้ค่าเฉพาะแม้ว่าค่าเริ่มต้นจะเหมือนกัน ตัวอย่าง: เพราะเท็จต้องเป็นศูนย์ฉันใช้false = 0,มากกว่าfalse,


5
นอกจากนี้ยังได้รับประโยชน์อื่นเพื่อใช้ enums เป็นการบูรณาการของ IDE - true, falseและboolเป็นไฮไลต์ใน IDE มากที่สุดเพราะพวกเขามีค่า enum และ typedef เป็นตรงข้ามกับ#definesที่ไม่ค่อยเคยไวยากรณ์ที่ไฮไลต์

อยากรู้อยากเห็น: ไม่สนใจว่าจะใช้งานได้จริงหรือไม่มันเป็น C (99+) ที่อนุญาตให้ enum อ้างอิงค่าก่อนหน้าในการแจงนับเดียวกันได้หรือไม่

@ tgm1024 gcc -ansi -pedantic -Wallให้คำเตือนใด ๆ ดังนั้นฉันไว้วางใจgcc; หากใช้งานได้แม้c89จะใช้งานc99ได้ก็ตาม
yyny

1
"เพราะเท็จมีเพียงค่าเดียว แต่ตรรกะจริงอาจมีหลายค่า แต่เทคนิคกำหนดให้เป็นสิ่งที่คอมไพเลอร์จะใช้สำหรับตรงกันข้ามกับเท็จ" ผู้ประกอบการปฏิเสธ!เท่านั้นที่สามารถคืนค่า0และ1ดังนั้นtrue = !falseมักจะคุ้มค่ากำหนด 1. typedef enum { false, true } bool;วิธีการนี้ไม่ได้ให้ความปลอดภัยพิเศษใด
694733

1
เร็วที่สุดที่ฉันพบคือจาก C90 (6.3.3.3 ตัวดำเนินการทางคณิตศาสตร์แบบเอกนารี): "ผลลัพธ์ของตัวดำเนินการเชิงลบตรรกะ! คือ 0 ถ้าค่าของตัวถูกดำเนินการเปรียบเทียบไม่เท่ากันกับ 0 1 ถ้าค่าของตัวถูกดำเนินการเปรียบเทียบเท่ากับ 0 ผลลัพธ์มีประเภท int นิพจน์! E เทียบเท่ากับ (O == E) " ควรครอบคลุมคอมไพเลอร์ใด ๆ ที่เคยอ้างว่าสนับสนุนมาตรฐาน C. คอมไพเลอร์สามารถละเว้นกฎนี้ได้อย่างถูกกฎหมายในกรณีที่มันไม่สำคัญสำหรับพฤติกรรมที่สังเกตได้ (เช่นif(!value)) แต่ข้อยกเว้นนั้นไม่สามารถใช้ได้ในกรณีเฉพาะนี้
user694733


30

สิ่งแรกก่อน C คือมาตรฐาน ISO / IEC 9899 ได้มีชนิดบูลีนสำหรับ19 ปีในขณะนี้ นั่นคือเวลาที่นานกว่าความยาวที่คาดหวังของอาชีพการเขียนโปรแกรม C กับส่วนสมัครเล่น / วิชาการ / มืออาชีพรวมกันเมื่อเยี่ยมชมคำถามนี้ ฉันทำได้ดีกว่านี้เพียง 1-2 ปีเท่านั้น หมายความว่าในช่วงเวลาที่ผู้อ่านโดยเฉลี่ยได้เรียนรู้อะไรเกี่ยวกับ C, C จริง ๆ แล้วมีชนิดข้อมูลบูลีนจริงมีชนิดข้อมูลแบบบูล

สำหรับประเภทข้อมูล, #include <stdbool.h>และการใช้งานtrue, และfalse boolหรือไม่รวมมันและการใช้งาน_Bool, 1และ0แทน


มีวิธีปฏิบัติที่เป็นอันตรายต่าง ๆที่ได้รับการส่งเสริมในคำตอบอื่น ๆ ของหัวข้อนี้ ฉันจะอยู่พวกเขา:

typedef int bool;
#define true 1
#define false 0

นี่ไม่ใช่ไม่เพราะผู้อ่านทั่วไปที่เรียนรู้ C ภายใน 19 ปีนั้นคาดว่าboolจะอ้างอิงกับชนิดข้อมูลจริง boolและจะทำงานในลักษณะเดียวกัน แต่ไม่ใช่! ตัวอย่างเช่น

double a = ...;
bool b = a;

ด้วย C99 bool/ _Bool, bจะได้รับการตั้งค่าให้false IFF aเป็นศูนย์และtrueเป็นอย่างอื่น C11 6.3.1.2p1

  1. เมื่อค่าสเกลาร์ใด ๆ ถูกแปลง_Boolเป็นผลลัพธ์จะเป็น 0 หากค่าเปรียบเทียบเท่ากับ 0 มิฉะนั้นผลลัพธ์คือ 1. 59)

เชิงอรรถ

59) NaNs ไม่เปรียบเทียบเท่ากับ 0 จึงแปลงเป็น 1

กับtypedefในสถานที่ที่doubleจะได้รับการข่มขู่ไปยังint- ถ้าค่าของคู่ไม่ได้อยู่ในช่วงของintการพฤติกรรมจะไม่ได้กำหนด

ธรรมชาติเช่นเดียวกับถ้าtrueและถูกประกาศในfalseenum

สิ่งที่อันตรายยิ่งกว่านั้นก็คือการประกาศ

typedef enum bool {
    false, true
} bool;

เพราะตอนนี้ค่าทั้งหมดที่อยู่นอกเหนือจาก 1 และ 0 นั้นไม่ถูกต้องและหากค่าดังกล่าวถูกกำหนดให้กับตัวแปรประเภทนั้นพฤติกรรมจะไม่ได้ถูกกำหนดไว้อย่างสมบูรณ์

ดังนั้นถ้าคุณไม่สามารถใช้ C99 ด้วยเหตุผลบางอย่างที่อธิบายไม่ได้สำหรับตัวแปรบูลีนที่คุณควรใช้:

  • ประเภทintและค่า0และ1 ตามที่เป็น ; และทำการแปลงโดเมนอย่างระมัดระวังจากค่าอื่น ๆ ถึงสิ่งเหล่านี้ด้วยการปฏิเสธคู่!!
  • หรือถ้าคุณยืนยันคุณจำไม่ได้ว่าเป็น 0 falsy และไม่ใช่ศูนย์ truish ที่ใช้งานไม่น้อยกว่ากรณีบนเพื่อให้พวกเขาไม่ได้รับการสับสนกับแนวคิด C99 นี้BOOL, TRUEและFALSE!

1
ส่วนใดของมาตรฐาน C ที่จะ จำกัด ออบเจ็กต์ประเภทที่ระบุเพื่อเก็บค่าที่ระบุไว้อย่างชัดเจน หากค่าที่ใหญ่ที่สุดสำหรับค่าคงที่แจกแจงน้อยกว่า UCHAR_MAX หรือ USHRT_MAX การใช้งานอาจใช้ชนิดที่เล็กกว่าintหรือunsigned intถือการแจงนับ แต่ฉันรู้ว่าไม่มีอะไรใน Standard ที่จะทำให้การแจงนับเป็นสิ่งอื่นที่ไม่ใช่จำนวนเต็ม ชนิด
supercat

18
typedef enum {
    false = 0,
    true
} t_bool;

2
2 ถึง MAX_INT ควรประเมินเป็นจริงเช่นกัน
technosaurus

2
@technosaurus การใช้วิธีการนี้ไม่รับประกัน! false == จริงตั้งแต่! false อาจเป็นหมายเลขที่ไม่ใช่ศูนย์ก็ได้ วิธีแก้ไขง่ายๆคือกำหนดจริงให้กับ! false
Andrew

3
@Andrew นั่นไม่ใช่ความจริง !0 = 1โดยมาตรฐาน C และ!a = 0สำหรับการใด ๆ aค่าที่ไม่ใช่ศูนย์ ปัญหาคือการใด ๆ ที่ไม่ใช่ศูนย์ถือเป็นจริง ดังนั้นถ้าaและbทั้งคู่เป็น "จริง" มันไม่จำเป็นต้องเป็นกรณีที่ `a == b`
Jeremy West

14

C มีประเภทบูลีน: บูล (อย่างน้อยสำหรับ 10 (!) ปี)

รวม stdbool.h และจริง / เท็จจะทำงานตามที่คาดไว้


12
10 ปีในมาตรฐาน แต่ไม่ใช่ 10 ปีสำหรับคอมไพเลอร์! การคอมไพล์ C ของ MSVC ++ ไม่รองรับ C99 เลยนอกจากการอนุญาต // ความคิดเห็นและไม่น่าจะเป็นเช่นนั้น นอกจากนี้ _Bool ถูกกำหนดใน C99 เป็นชนิดในตัวในขณะที่บูลเป็น typedef ในส่วนหัว <stdbool.h>
Clifford

5
@Clifford 4 ปีที่ผ่านมาตั้งแต่ความคิดเห็นของคุณ ... ไม่มีอะไรเปลี่ยนแปลง MSVC เป็นคอมไพเลอร์ C ++ และฉันเชื่อว่า MS บอกว่าพวกเขาไม่กระตือรือร้นที่จะสนับสนุนฟีเจอร์ C ใหม่ทั้งหมด (C99 & C11) แต่ฉันไม่สามารถรับได้ว่า MSVC ไม่สนับสนุนคุณสมบัติ C ใหม่เนื่องจากเหตุผล (โดยเฉพาะเมื่อคุณพูดกับคำตอบ10 ปี ) 10 ปีเป็นเวลานานในโลกแห่งการเขียนโปรแกรม ผู้รวบรวมที่ดีควรได้รับการสนับสนุนในเวลาน้อยกว่า 10 ปีหากผู้ขายตั้งใจให้การสนับสนุน
PP

2
@KingsIndian: ฉันไม่แน่ใจว่าทำไมคุณถึงส่งความคิดเห็นของคุณมาให้ฉันหรือรู้สึกถึงความต้องการที่จะแสดงความคิดเห็นเลย ฉันแค่บอกสถานการณ์ขณะที่มันยืนอยู่ในช่วงเวลาของการเขียน ฉันไม่สนับสนุนสถานการณ์นั้นเพียงแค่ชี้ให้เห็นว่า "คำตอบ" อาจไม่สามารถใช้ได้ในทุกสถานการณ์
Clifford

@Clifford: อย่างเคร่งครัดมาตรฐานต้องที่จะแมโครที่ขยายเพื่อbool _Boolเรื่องความแตกต่างเพราะคุณสามารถ#undefมาโคร (และว่าได้รับอนุญาตอย่างน้อยเป็นวัดคลองท่อม) แต่คุณไม่สามารถuntypedeftypedef แม้ว่ามันจะไม่เปลี่ยนแรงผลักดันหลักของความคิดเห็นแรกของคุณ
Jonathan Leffler

2
VS2015 และใหม่กว่า (อาจเป็นไปได้ก่อนหน้านี้จนถึงจุดหนึ่ง) ไม่มีปัญหากับการคอมไพล์boolผ่าน<stdbool.h>C _Boolมันหายไป

11

สิ่งใดที่ไม่ใช่ศูนย์จะถูกประเมินเป็นจริงในการดำเนินการบูลีนดังนั้นคุณสามารถทำได้

#define TRUE 1
#define FALSE 0

และใช้ค่าคงที่


10
แต่ใช้ด้วยความระมัดระวัง: เนื่องจากผลลัพธ์ที่แท้จริงอาจเป็นค่าที่ไม่เป็นศูนย์การทดสอบว่า (t == TRUE) {... } และถ้า (t) ซึ่งเทียบเท่าในภาษาอื่น ๆ จะไม่เทียบเท่าใน C .
Fortega

1
คุณพูดถูก แต่ก็เป็นจริงใน C ++ ซึ่งมีประเภทบูลใช่ไหม ระหว่างการดีบักฉันเคยเห็นตัวแปรบูลด้วยค่า 5837834939 ...
ggambett

1
ใน C ++ การทดสอบ if (t == จริง) เท่ากับการทดสอบ if (t) เนื่องจาก C ++ ทำการแปลงบางอย่าง (ทุกอย่างที่ไม่ใช่ 0 หรือค่าตัวชี้โมฆะถูกแปลงเป็นจริง)
Fortega

6
สิ่งที่คุณควรพิจารณาเกี่ยวกับค่าบูลีนที่แท้จริงคือมันไม่เป็นศูนย์ ดังนั้นรหัสเช่นถ้า (b) ปลอดภัยในขณะที่ถ้า (b == TRUE) ไม่; หลังคือการปฏิบัติที่ไม่ดี (และไม่มีจุดหมาย)
Clifford

5

เป็นเพียงส่วนเติมเต็มให้กับคำตอบอื่น ๆ และชี้แจงหากคุณได้รับอนุญาตให้ใช้ C99

+-------+----------------+-------------------------+--------------------+
|  Name | Characteristic | Dependence in stdbool.h |        Value       |
+-------+----------------+-------------------------+--------------------+
| _Bool |   Native type  |    Don't need header    |                    |
+-------+----------------+-------------------------+--------------------+
|  bool |      Macro     |           Yes           | Translate to _Bool |
+-------+----------------+-------------------------+--------------------+
|  true |      Macro     |           Yes           |   Translate to 1   |
+-------+----------------+-------------------------+--------------------+
| false |      Macro     |           Yes           |   Translate to 0   |
+-------+----------------+-------------------------+--------------------+

บางส่วนของการตั้งค่าของฉัน:

  • _Boolหรือbool? ทั้งคู่ใช้ได้ แต่boolดูดีกว่าคำหลัก_Boolรูปลักษณ์ที่ดีกว่าคำหลัก
  • ค่าที่ยอมรับสำหรับboolและ_Boolมีดังนี้: หรือfalse trueการกำหนด0หรือ1แทนfalseหรือtrueใช้ได้ แต่เป็นการยากที่จะอ่านและเข้าใจการไหลของลอจิก

ข้อมูลบางส่วนจากมาตรฐาน:

  • _Boolไม่ใช่unsigned intแต่เป็นส่วนหนึ่งของกลุ่มที่ไม่มีการลงชื่อประเภทจำนวนเต็ม มันมีขนาดใหญ่พอที่จะเก็บค่า0หรือ1หรือ
  • ทำไม่ได้ แต่ใช่คุณสามารถกำหนดใหม่bool trueและfalseแต่แน่ใจว่าไม่ใช่ความคิดที่ดี ความสามารถนี้ถือว่าล้าสมัยและจะถูกลบออกในอนาคต
  • การกำหนดประเภทสเกลาร์ (ประเภทเลขคณิตและประเภทตัวชี้) ไป_Boolหรือboolถ้าเกลาค่าเท่ากับ0หรือเปรียบเทียบเพื่อ0มันจะเป็น0มิฉะนั้นผลที่ได้คือ1: _Bool x = 9; 9จะถูกแปลงเป็นเมื่อได้รับมอบหมายให้1x
  • _Boolคือ 1 ไบต์ (8 บิต) โดยปกติแล้วโปรแกรมเมอร์มักถูกล่อลวงให้พยายามใช้บิตอื่น แต่ไม่แนะนำเพราะสิ่งเดียวที่รับประกันคือมีเพียงหนึ่งบิตเท่านั้นที่ใช้ในการเก็บข้อมูลไม่เหมือนชนิดcharที่มี 8 บิตที่มี


2

คุณสามารถใช้ถ่านหรือภาชนะขนาดเล็กจำนวนหนึ่งได้

หลอกรหัส

#define TRUE  1
#define FALSE 0

char bValue = TRUE;

นอกจากนี้ใน C ก็มักจะเป็น int และมันสามารถทำให้เกิดการสูญเสียของคำเตือนที่มีความแม่นยำตามรหัสอื่น ๆ ที่ใช้ int ..
โทมัส Bonini

นอกจากว่าคุณกำลังปรับพื้นที่ให้เหมาะสมด้วยมือควรใช้ขนาดคำปกติของฮาร์ดแวร์ (เช่น: ปกติและint) เนื่องจากบนสถาปัตยกรรมบางตัวที่คุณได้รับประสิทธิภาพที่สำคัญจากการตรวจสอบตัวแปร / แพ็คมาสก์
Kingsley

2

คุณสามารถใช้ _Bool ได้ แต่ค่าส่งคืนจะต้องเป็นจำนวนเต็ม (1 สำหรับจริง, 0 สำหรับเท็จ) อย่างไรก็ตามขอแนะนำให้รวมและใช้บูลเช่นเดียวกับใน C ++ ดังที่ได้กล่าวไว้ใน คำตอบนี้จากฟอรัม daniwebและคำตอบนี้จากคำถาม stackoverflow อื่น ๆ นี้:

_Bool: ประเภทบูลีนของ C99 แนะนำให้ใช้ _Bool โดยตรงในกรณีที่คุณรักษารหัสดั้งเดิมที่กำหนดมาโครสำหรับบูลจริงหรือเท็จแล้ว มิฉะนั้นมาโครเหล่านั้นจะได้มาตรฐานในส่วนหัว รวมส่วนหัวนั้นและคุณสามารถใช้บูลเหมือนใน C ++


2

นิพจน์แบบมีเงื่อนไขจะถือว่าเป็นจริงหากไม่ใช่ศูนย์ แต่มาตรฐาน C กำหนดให้ตัวดำเนินการเชิงตรรกะกลับมาเป็น 0 หรือ 1

@Tom: #define TRUE! FALSE ไม่ดีและไม่มีจุดหมายอย่างสมบูรณ์ หากไฟล์ส่วนหัวทำให้มันกลายเป็นรหัส C ++ รวบรวมแล้วมันสามารถนำไปสู่ปัญหา:

void foo(bool flag);

...

int flag = TRUE;
foo(flag);

คอมไพเลอร์บางตัวจะสร้างคำเตือนเกี่ยวกับการแปลง int => bool บางครั้งผู้คนหลีกเลี่ยงสิ่งนี้โดยทำ:

foo(flag == TRUE);

เพื่อบังคับให้นิพจน์เป็นบูล C ++ แต่ถ้าคุณกำหนด # TRUE! FALSE คุณจะได้:

foo(flag == !0);

ซึ่งสิ้นสุดการทำการเปรียบเทียบแบบ int-to-bool ที่สามารถทริกเกอร์คำเตือนได้


1

หากคุณใช้ C99 คุณสามารถใช้_Boolประเภท ไม่#includeจำเป็น คุณไม่จำเป็นต้องรักษามันเช่นจำนวนเต็ม แต่ที่1เป็นtrueและ0เป็นfalseเป็น

จากนั้นคุณสามารถกำหนดและTRUEFALSE

_Bool this_is_a_Boolean_var = 1;


//or using it with true and false
#define TRUE 1
#define FALSE 0
_Bool var = TRUE;

หรือคุณสามารถ#include <stdbool.h>และการใช้งานbool, trueและfalseเช่นมาตรฐานต้องการให้คุณ
SS Anne

1

ปัจจุบันC99สนับสนุนชนิดบูลีน #include <stdbool.h>แต่คุณจำเป็นต้อง

ตัวอย่าง:

#include <stdbool.h>

int main() 
{ 
    bool arr[2] = {true, false}; 

    printf("%d\n", arr[0] && arr[1]);
    printf("%d\n", arr[0] || arr[1]);

    return 0; 
} 

เอาท์พุท:

0
1

0

นี่คือสิ่งที่ฉันใช้:

enum {false, true};
typedef _Bool bool;

_Bool เป็นชนิดในตัวใน C. มันมีไว้สำหรับค่าบูลีน


-2

คุณสามารถใช้#defineคำสั่งดังต่อไปนี้:

#define TRUE 1
#define FALSE 0
#define NOT(arg) (arg == TRUE)? FALSE : TRUE
typedef int bool;

และใช้ดังนี้:

bool isVisible = FALSE;
bool isWorking = TRUE;
isVisible = NOT(isVisible);

และอื่น ๆ


5
แมโครไม่ควรได้รับการป้องกันโดยวงเล็บรอบ ๆargและนิพจน์โดยรวม: #define NOT(arg) (((arg) == TRUE) ? FALSE : TRUE). อย่างไรก็ตามจะเป็นการดีกว่าที่จะทดสอบความผิดพลาด (จะให้คำตอบที่ถูกต้องแม้ว่าจะargเป็น 23 แทนที่จะเป็น 0 หรือ 1: #define NOT(arg) (((arg) == FALSE) ? TRUE : FALSE)แต่แน่นอนว่าการแสดงออกทั้งหมดสามารถลดลงได้#define NOT(arg) (!(arg))ซึ่งแน่นอนว่าผลลัพธ์เดียวกัน
Jonathan Leffler
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.