C ไม่มีบูลีนในตัวชนิดใด ๆ วิธีที่ดีที่สุดที่จะใช้ใน C คืออะไร?
C ไม่มีบูลีนในตัวชนิดใด ๆ วิธีที่ดีที่สุดที่จะใช้ใน C คืออะไร?
คำตอบ:
จากดีที่สุดถึงแย่กว่า:
ตัวเลือก 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!
<stdbool.h> boolคอมไพเลอร์เลือกอาจเหมาะสมกว่าสำหรับวัตถุประสงค์ที่ตั้งใจไว้ของค่าบูลีนมากกว่าการใช้int(เช่นคอมไพเลอร์อาจเลือกใช้งานที่boolแตกต่างจากint) นอกจากนี้ยังอาจส่งผลให้การตรวจสอบประเภทที่เข้มงวดยิ่งขึ้นในเวลารวบรวมหากคุณโชคดี
                    intสำหรับbool? นั่นช่างสิ้นเปลือง unsigned charใช้ _Boolหรือใช้ในตัวของ C
                    ความคิดเล็กน้อยเกี่ยวกับบูลีนใน 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ซึ่งผู้อ่านมีอย่างน้อยโอกาสของความเข้าใจโดยไม่ต้องขุดลอกขึ้นความหมายของการเป็น
a == bทำงาน
                    aและbนับจากศูนย์ฉันขอแนะนำa > 0 == b > 0แทน หากคุณยืนยันในการใช้ประโยชน์จากความเป็นจริงของค่าที่ไม่เป็นศูนย์โดยพลการให้ค่า!!varบูลีน 0/1 เทียบเท่ากับvarดังนั้นคุณสามารถเขียน!!a == !!bแม้ว่าผู้อ่านจำนวนน้อยจะรู้สึกสับสน
                    !a == !bก็เพียงพอสำหรับการทดสอบความเท่าเทียมกันไม่ใช่ศูนย์กลายเป็นศูนย์และศูนย์กลายเป็นหนึ่ง
                    !!aว่า "แปลงไม่ใช่บูลีนเป็นค่าความจริงที่เทียบเท่ากัน" ในขณะที่ฉันอ่าน!aว่า "เปลี่ยนตรรกะบูลีนเป็นตรรกะ" โดยเฉพาะฉันต้องการเหตุผลบางอย่างที่ต้องการการผกผันแบบตรรกะ
                    บูลีนใน C เป็นจำนวนเต็ม: ศูนย์สำหรับเท็จและไม่เป็นศูนย์สำหรับจริง
ดูเพิ่มเติมชนิดข้อมูลแบบบูลส่วนC, C ++, Objective-C, AWK
นี่คือรุ่นที่ฉันใช้:
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,
true, falseและboolเป็นไฮไลต์ใน IDE มากที่สุดเพราะพวกเขามีค่า enum และ typedef เป็นตรงข้ามกับ#definesที่ไม่ค่อยเคยไวยากรณ์ที่ไฮไลต์
                    gcc -ansi -pedantic -Wallให้คำเตือนใด ๆ ดังนั้นฉันไว้วางใจgcc; หากใช้งานได้แม้c89จะใช้งานc99ได้ก็ตาม
                    !เท่านั้นที่สามารถคืนค่า0และ1ดังนั้นtrue = !falseมักจะคุ้มค่ากำหนด 1. typedef enum { false, true } bool;วิธีการนี้ไม่ได้ให้ความปลอดภัยพิเศษใด
                    if(!value)) แต่ข้อยกเว้นนั้นไม่สามารถใช้ได้ในกรณีเฉพาะนี้
                    หากคุณกำลังใช้คอมไพเลอร์ C99 มันมีการรองรับในตัวสำหรับประเภทบูล:
#include <stdbool.h>
int main()
{
  bool b = false;
  b = true;
}สิ่งแรกก่อน 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
- เมื่อค่าสเกลาร์ใด ๆ ถูกแปลง
_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 ตามที่เป็น ; และทำการแปลงโดเมนอย่างระมัดระวังจากค่าอื่น ๆ ถึงสิ่งเหล่านี้ด้วยการปฏิเสธคู่!!BOOL, TRUEและFALSE!intหรือunsigned intถือการแจงนับ แต่ฉันรู้ว่าไม่มีอะไรใน Standard ที่จะทำให้การแจงนับเป็นสิ่งอื่นที่ไม่ใช่จำนวนเต็ม ชนิด
                    typedef enum {
    false = 0,
    true
} t_bool;!0 = 1โดยมาตรฐาน C และ!a = 0สำหรับการใด ๆ aค่าที่ไม่ใช่ศูนย์ ปัญหาคือการใด ๆ ที่ไม่ใช่ศูนย์ถือเป็นจริง ดังนั้นถ้าaและbทั้งคู่เป็น "จริง" มันไม่จำเป็นต้องเป็นกรณีที่ `a == b`
                    C มีประเภทบูลีน: บูล (อย่างน้อยสำหรับ 10 (!) ปี)
รวม stdbool.h และจริง / เท็จจะทำงานตามที่คาดไว้
bool _Boolเรื่องความแตกต่างเพราะคุณสามารถ#undefมาโคร (และว่าได้รับอนุญาตอย่างน้อยเป็นวัดคลองท่อม) แต่คุณไม่สามารถuntypedeftypedef แม้ว่ามันจะไม่เปลี่ยนแรงผลักดันหลักของความคิดเห็นแรกของคุณ
                    สิ่งใดที่ไม่ใช่ศูนย์จะถูกประเมินเป็นจริงในการดำเนินการบูลีนดังนั้นคุณสามารถทำได้
#define TRUE 1
#define FALSE 0และใช้ค่าคงที่
เป็นเพียงส่วนเติมเต็มให้กับคำตอบอื่น ๆ และชี้แจงหากคุณได้รับอนุญาตให้ใช้ 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 บิตที่มีคุณสามารถใช้ถ่านหรือภาชนะขนาดเล็กจำนวนหนึ่งได้
หลอกรหัส
#define TRUE  1
#define FALSE 0
char bValue = TRUE;int) เนื่องจากบนสถาปัตยกรรมบางตัวที่คุณได้รับประสิทธิภาพที่สำคัญจากการตรวจสอบตัวแปร / แพ็คมาสก์
                    คุณสามารถใช้ _Bool ได้ แต่ค่าส่งคืนจะต้องเป็นจำนวนเต็ม (1 สำหรับจริง, 0 สำหรับเท็จ) อย่างไรก็ตามขอแนะนำให้รวมและใช้บูลเช่นเดียวกับใน C ++ ดังที่ได้กล่าวไว้ใน คำตอบนี้จากฟอรัม daniwebและคำตอบนี้จากคำถาม stackoverflow อื่น ๆ นี้:
_Bool: ประเภทบูลีนของ C99 แนะนำให้ใช้ _Bool โดยตรงในกรณีที่คุณรักษารหัสดั้งเดิมที่กำหนดมาโครสำหรับบูลจริงหรือเท็จแล้ว มิฉะนั้นมาโครเหล่านั้นจะได้มาตรฐานในส่วนหัว รวมส่วนหัวนั้นและคุณสามารถใช้บูลเหมือนใน C ++
นิพจน์แบบมีเงื่อนไขจะถือว่าเป็นจริงหากไม่ใช่ศูนย์ แต่มาตรฐาน 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 ที่สามารถทริกเกอร์คำเตือนได้
หากคุณใช้ 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เช่นมาตรฐานต้องการให้คุณ
                    ปัจจุบัน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นี่คือสิ่งที่ฉันใช้:
enum {false, true};
typedef _Bool bool;_Bool เป็นชนิดในตัวใน C. มันมีไว้สำหรับค่าบูลีน
คุณสามารถใช้#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);และอื่น ๆ
argและนิพจน์โดยรวม: #define NOT(arg) (((arg) == TRUE) ? FALSE : TRUE). อย่างไรก็ตามจะเป็นการดีกว่าที่จะทดสอบความผิดพลาด (จะให้คำตอบที่ถูกต้องแม้ว่าจะargเป็น 23 แทนที่จะเป็น 0 หรือ 1: #define NOT(arg) (((arg) == FALSE) ? TRUE : FALSE)แต่แน่นอนว่าการแสดงออกทั้งหมดสามารถลดลงได้#define NOT(arg) (!(arg))ซึ่งแน่นอนว่าผลลัพธ์เดียวกัน