เมื่อใดที่คุณควรใช้ bools ใน C ++


34

เรามีงานที่มอบหมายสำหรับชั้นเรียนของเราซึ่งเราต้องสร้างเกมโอเอกซ์ ผู้คนชอบที่จะทำให้ตัวเองสับสนดังนั้นพวกเขาจึงเขียนเกมที่ซับซ้อนซึ่งรวมถึงเมนู ในตอนท้ายของเกมคุณต้องมีตัวเลือกให้เล่นอีกครั้งหรือออกจากโปรแกรม ฉันใช้intตัวแปรสำหรับเรื่องนั้น แต่ฉันสังเกตเห็นเพื่อนร่วมชั้นบางคนใช้บูล

มันมีประสิทธิภาพมากกว่านี้ไหม? ความแตกต่างระหว่างการจัดเก็บคำตอบที่ควรเก็บค่าสองค่าในintแทนที่จะเก็บไว้ในบูลคืออะไร วัตถุประสงค์ที่แน่นอนของตัวแปรเหล่านี้คืออะไร?


32
ไม่แน่ใจเกี่ยวกับประสิทธิภาพ แต่จุดประสงค์ของการintคือเก็บจำนวนเต็มและจุดประสงค์ของการboolเก็บค่าบูลีน ( trueหรือfalse) ใช้boolIMO intสะท้อนให้เห็นถึงการใช้งานที่ดีขึ้นกว่าการใช้
George Duckett

12
ในความเป็นจริงก่อน C ++ และ C99, C89 ไม่มีประเภทบูลีน โปรแกรมเมอร์มักtypedef int Boolจะทำให้มันชัดเจนว่าพวกเขากำลังใช้บูลีน การสนับสนุนแบบรวม C ++ สำหรับboolภาษานั้นเช่นเดียวกับ C99 ที่มี_Boolคำหลัก(ค่อนข้างน่าเกลียด)
Charles Salvia

มันไม่เกี่ยวกับ "รู้ว่าเมื่อใดควรใช้bool" มันเกี่ยวกับเหตุผลที่เรามีชื่อแตกต่างกันสำหรับประเภทที่คล้ายกัน (เช่นlength_t) และทำไมจึงเป็นสิ่งสำคัญที่คอมไพเลอร์ตรวจสอบประเภท
Abyx

บางครั้งคำตอบก็คือ 'รสชาติ' ฉันเดิมพันถ้าคุณเขียนการบ้านเดิมของคุณตอนนี้ช่วงเวลานี้จะมีหลายสิ่งที่แตกต่างกันเช่นการสั่งซื้อพารามิเตอร์ฟังก์ชั่นและชื่อของพวกเขา ทำไมคุณไม่เขียนมันในลำดับพารามิเตอร์เดียวกันหรือชื่อเดียวกัน? เป็นเพราะคุณไม่ได้ทำหรือว่าไม่สำคัญมากและคุณเขียนอะไรก็ได้

คำตอบ:


82

เมื่อเลือกประเภทของตัวแปรและชื่อตัวแปรคุณต้องการให้เจตนาของคุณชัดเจนที่สุด หากคุณเลือกbool(บูล) ประเภทก็เป็นที่ชัดเจนมีเพียงสองค่าที่ยอมรับได้: หรือtrue falseถ้าคุณใช้int(จำนวนเต็ม) ชนิดมันไม่ได้ชัดเจนว่าเจตนาของตัวแปรที่สามารถเป็นค่า 1 หรือ 0 หรือสิ่งที่คุณเลือกที่จะหมายถึงและtrue falseพลัสsizeof(int)โดยทั่วไปแล้วจะกลับมาเป็น 4 ไบต์ขณะที่sizeof(bool)จะกลับ 1


7
ตกลง ฉันคิดว่าความตั้งใจออกแบบมีความสำคัญมากกว่า คุณจะต้องแทนที่พวกเขาเป็นครั้งคราวเท่านั้น
ChrisF

9
ในการย้ำจุดของ @ AndrewFinnel: Bool เป็นเอกสารด้วยตนเองมากกว่า ตัวแปรที่คุณตั้งค่าเป็น 0 หรือ 1 อาจเป็นตัวนับ ตัวแปรที่คุณตั้งค่าเป็นจริงหรือเท็จนั้นชัดเจนว่าเป็นแฟล็ก
Scott C Wilson

2
Bools ป้องกันการใช้ตัวแปรในทางที่ผิดสำหรับการใช้งานอื่น จำนวนเต็มสามารถตั้งค่าเป็นค่าอื่นที่ไม่ใช่ 0 หรือ 1 เพื่อสร้างสถานะเพิ่มเติมรหัสของคุณอาจไม่ทราบ
Michael Shopsin

+1 มันทำให้เจตนา / ตัวเลือกชัดเจน คุณสามารถใช้วิธีใดก็ได้ที่คุณต้องการเก็บค่ารวมถึงสตริงที่มีค่าเป็น "ใช่" หรือ "ไม่" แต่คุณควรเลือกวิธีที่เหมาะสมที่สุด ในกรณีนี้นั่นคือบูลีน
Craige

ฉันคิดว่าบูลีนใน C ++ มีขนาดเท่ากันกับ ints, 4 ไบต์
DogDog

53

ดูเหมือนว่าในทุกคำตอบ (จนถึงตอนนี้) เก็บรวบรวมไม่มีใครจับความจริงที่ว่า OP พูดเกี่ยวกับการไม่ได้BOOLbool

เนื่องจากคำถามถูกแท็ก C ++ จึงต้องสังเกตว่า:

  • intเป็นจำนวนเต็มที่มีตั้งแต่- INT_MINถึงINT_MAXมาโครที่กำหนดไว้<climits>ซึ่งค่าขึ้นอยู่กับสถาปัตยกรรมของเครื่องโฮสติ้ง ใน C ++ ค่าเหล่านี้ก็สามารถเข้าถึงได้เช่นกันstd::numeric_limits<int>::min()และ...:max()ตามลำดับ) พฤติกรรมของผู้ประกอบการบูลีนที่ใช้ในการintรักษา0เป็นเท็จและทุกสิ่งทุกอย่างที่เป็นความจริง
  • BOOLเป็นเพียงคำใบ้ที่บอกถึงพฤติกรรมแบบบูลสำหรับ int มันถูกกำหนด<cstddef>เป็น

    #define BOOL int
    #define TRUE 1
    #define FALSE 0
    
  • BOOLไม่มีอะไรมากไปกว่าน้ำตาลซินแทคติกสำหรับสิ่งที่ - โดยคอมไพเลอร์ - มันไม่มีอะไรมากไปกว่า int มันเป็นสิ่งที่ C ใช้โปรแกรมเมอร์ แต่ c ++ โปรแกรมเมอร์ควรหลีกเลี่ยงเนื่องจาก C ++ boolมี

  • boolภาษาชนิดหนึ่งที่มีค่าเป็นเพียงการสนับสนุนและtrue falseเมื่อแปลงint trueเป็น 1 และfalseกลายเป็น 0

สิ่งสำคัญคือความปลอดภัยต่อความผิดพลาดในการเขียนโปรแกรม:

BOOL a = FALSE;  // in fact int a = 0;
a = 5; //now a == 5 -- what does it mean?;

ไม่สามารถเขียนโค้ดด้วยประเภทบูลที่เหมาะสม:

bool a = false;
a = 5; // error: no bool(const int&) available.

การใช้BOOLแทนที่จะboolเป็นเพียงนิสัยที่ไม่ดีซึ่งสืบทอดมาจากอดีตอันรุ่งโรจน์ซึ่งไม่มีใครสามารถลืมได้จริง ๆ ดังนั้นจึงสร้างปัญหาเก่าสำหรับวันรุ่งขึ้นที่รุ่งโรจน์น้อยลง

ครูสอนภาษาควรคิดอย่างจริงจังเกี่ยวกับเรื่องนี้!


9
บูลไม่ได้เป็นส่วนหนึ่งของ C ++ หรือภาษา C บูลกับตัวอักษรตัวพิมพ์ใหญ่เป็นวิธีที่ใช้กันมากที่สุดในบูลีน C ในสมัยก่อนเมื่อ C ไม่มีบูลีน ตัวอย่างเช่น Windows API จะกำหนด BOOL นอกจากนี้ยังไม่มีการบอกถึงวิธีการกำหนด BOOL บางแอปพลิเคชันอาจกำหนดให้เป็นบิตฟิลด์ยาวหนึ่งบิต คุณไม่สามารถสันนิษฐานได้ว่ามันมีค่าเท่ากับ int เสมอเพราะบางไลบรารีกำหนดไว้อย่างนั้น

1
+1 บางทีเขาอาจจะจริงไม่ได้หมายถึง BOOL และไม่บูล บางที BOOL สามารถนำไปใช้ในรูปแบบที่แตกต่างกันได้แม้ว่า Codereview อาจไม่รู้ว่าถ้าเขาถามคำถามแบบนี้ เขาเห็นว่ามันถูกกำหนดให้เป็น int ดังนั้นเขาจึงถามโดยธรรมชาติว่าทำไมเขาถึงใช้ int ไม่ได้
Neil

1
@Lundin: โดยทั่วไปแล้วคุณถูกต้อง แต่ให้คิดว่านี่เป็นคำตอบที่อยู่ในขอบเขตของคำถามโดยที่ OP พูดถึง BOOL และความเท่าเทียมกันของ int
Emilio Garavaglia

ถึงกระนั้นแนวคิดของการใช้ BOOL หรือบูลเพื่อแสดงเจตนายังคงมีผลอยู่
Andrew T Finnell

1
@zvrba: จริง แต่นี่เป็นเพราะวิธีที่ MS ตัดสินใจใช้บูลในคอมไพเลอร์ของตัวเอง ใช้ได้กับคอมไพเลอร์ MS ที่ทำงานกับโปรเซสเซอร์ Intel เท่านั้น โปรดทราบว่าสำหรับแพลตฟอร์ม Intel ทุกประเภทที่สั้นกว่า 32 บิตต้องมีการปิดบังบนอินพุตหรือเอาต์พุต แต่ถ่าน [] ยังคงถูกใช้และไม่จำเป็นต้องถูกแทนที่ด้วย int [] เสมอไป
Emilio Garavaglia

6

ประเภทบูลมีขนาดเล็กกว่าประเภท Int จึงใช้พื้นที่ในหน่วยความจำน้อยลง ขึ้นอยู่กับระบบที่คุณคอมไพล์ด้วย / สำหรับ Int สามารถเป็น 4 - 8 ไบต์ในขณะที่ Bool เป็น 1 ไบต์ (ดังที่เห็นในบทความ MSDN นี้ )

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

ทำไมต้องทำสิ่งที่ซับซ้อนด้วยวัตถุที่สามารถเก็บค่าได้หลากหลายเมื่อคุณแน่ใจว่าคุณจำเป็นต้องเก็บค่าที่แตกต่างกัน 1 ใน 2 เท่านั้น?

เกิดอะไรขึ้นในระบบที่ใช้ int ถ้าคุณเก็บ 75 อันไว้ หากคุณได้เพิ่มเงื่อนไขพิเศษ

if (value >= 0 )
  return true;  //value is greater than 0, thus is true
else
  return false; //value is 0 or smaller than 0, thus is false

หรือ

if (value == 0)
  return false;  //value is greater than 0, thus is true
else if (value == 1)
  return true; //value is 0 or smaller than 0, thus is false

จากนั้นคุณจะครอบคลุมถึงสถานการณ์นี้ แต่ถ้าคุณไม่มีคุณก็ไม่ได้

คุณอาจมีกรณี (ขึ้นอยู่กับวิธีที่คุณเปลี่ยนค่าของ int) ที่คุณมีบัฟเฟอร์ล้นและค่า "รีเซ็ต" กลับเป็น 0 หรือขอบเขตล่างของ int ของคุณ (ซึ่งอาจจะอยู่ที่ไหนสักแห่งใน ภูมิภาคของ -127 ถึง −9,223,372,036,854,775,808 ขึ้นอยู่กับสถาปัตยกรรมเป้าหมายของคุณ ) จะเกิดอะไรขึ้นในโค้ดของคุณ?

อย่างไรก็ตามหากคุณใช้บูลคุณสามารถใช้สิ่งนี้:

if(continueBool == true)
  return true;
else
  return false;

หรือแม้กระทั่ง:

return (continueBool== true) ? true : false;

หรือแม้กระทั่ง:

return continueBool;

ขึ้นอยู่กับคอมไพเลอร์ของคุณอาจมีการปรับให้เหมาะสมที่สามารถทำงานกับรหัสที่ใช้ Bools เพื่อจัดเก็บค่าจริง / เท็จที่แมป ในขณะที่อาจไม่มีการปรับให้เหมาะสมที่สามารถทำได้สำหรับ Ints ที่ใช้เพื่อเก็บค่าจริง / เท็จที่แมป

นอกจากนี้เรายังต้องจำไว้ว่า C ++ (พร้อมด้วย C, Assembly และ FORTRAN) ใช้เพื่อเขียนโค้ดที่มีประสิทธิภาพสูงขนาดเล็กและรวดเร็ว ดังนั้นจะเป็นการดีกว่าถ้าคุณใช้ Bool ในกรณีนี้ - โดยเฉพาะถ้าคุณถูกทำเครื่องหมายในการใช้ตัวแปรหน่วยความจำแคชหรือเวลาของตัวประมวลผล

คำถามที่คล้ายกันคือ: ทำไมฉันจะเก็บจำนวนเต็ม (ค่า) ในการลอย? คำตอบ: คุณไม่ควรเพราะไม่มีประเด็น

เรื่องสั้นสั้น ๆ : ในฐานะที่คุณครู / ครูสอนพิเศษ / อาจารย์ / อาจารย์สอนคุณมากกว่าขนาดของประเภทค่าที่แตกต่างกับคุณ (ในกรณีที่คุณพลาด) และทำไมพวกเขาถึงมีความสำคัญในการพัฒนาซอฟต์แวร์

ฉันหวังว่าจะช่วยเป็นจุดเริ่มต้น (ฉันหวังว่ามันจะไม่ตรงตามความคิด)


4
การใช้รางวัล if () ที่ไม่จำเป็น เพียงแค่เขียนreturn value >= 0;ตัวอย่างแรก
zvrba

ฉันไม่แน่ใจในระดับความเข้าใจไวยากรณ์ของ OP บางครั้งมันเป็นรางวัลที่ verbose มากกว่าปกติเล็กน้อยโดยเฉพาะอย่างยิ่งเมื่อ OP กล่าวว่าเป็นการมอบหมาย
Jamie Taylor

2
ไม่เห็นด้วย - แต่เพียงเพื่อชี้ให้เห็นว่าการบันทึกสามไบต์ด้วยการเลือกบูลมากกว่า int จะไม่ทำให้เกิดความแตกต่างที่เห็นได้ชัดเจนในโปรแกรมส่วนใหญ่ ไม่ต้องกังวลเรื่องประสิทธิภาพจนกว่าคุณจะมีปัญหาเรื่องประสิทธิภาพ!
James Anderson

@James: ในหลายกรณีคุณจะไม่บันทึกสามไบต์เนื่องจากตัวแปรถัดไปยกเว้นว่าเป็น bool หรือ char ตัวอื่นอาจจะได้รับการจัดแนวให้เป็นสี่ไบต์
JeremyP

1

วัตถุประสงค์ที่นี่คือความชัดเจนของเจตนา ชนิดส่งคืนเป็นส่วนหนึ่งของอินเทอร์เฟซฟังก์ชันและตัวboolบอกคุณเกี่ยวกับสิ่งที่คาดหวังจากฟังก์ชันมากกว่าที่intจะทำ

แม้ว่าBOOLจะเป็นintประเภทเดียวกันอย่างน้อยก็แสดงให้เห็นเจตนาของคุณ

อย่างไรก็ตามไม่มีสิ่งใดที่ฉันอยากจะแนะนำ:

enum class UiCmd {QUIT, START_GAME};

-1

ในการเขียนโปรแกรมคุณต้องการแสดงอะไรบางอย่างจากชีวิตจริงในรหัส แม้ว่า int และบูลสามารถทำสิ่งเดียวกันได้แนวคิด subyacent นั้นแตกต่างกันโดยสิ้นเชิง: เมื่อใช้บูลคำตอบอาจเป็นใช่หรือไม่; และนั่นคือทั้งหมดที่ตั้งใจ ด้วยจำนวนเต็มคุณอาจแทนปริมาณที่ไม่มีจุดทศนิยม และในจิตวิญญาณเดียวกันนั้นทำไมคุณถึงเลือกจำนวนเต็มเมื่อสองเท่าสามารถทำอย่างเดียวกันได้? หากจำนวนเต็มเหมาะสมกว่าสองเท่าเมื่อสร้างแบบจำลองปัญหาคุณอาจเลือก int


1
สิ่งนี้ดูเหมือนจะไม่นำเสนออะไรมากมายเกินกว่าที่ทำคะแนนและอธิบายไว้ในคำตอบยอดนิยมที่นี่ซึ่งโพสต์เมื่อประมาณ 6 ปีที่แล้ว
gnat

-2

เพราะในที่สุดคุณจะแปลงจำนวนเต็มเป็นบูลีน แต่อย่างใด: "if (i = 1) จากนั้นเล่นเกมอื่น" ในสถานการณ์นี้ (i = 1) จะถูกแปลงเป็นจริงหรือเท็จ: บูลีน


ขึ้นอยู่กับเครื่องที่คุณใช้งานอยู่และคอมไพเลอร์ที่เกี่ยวข้อง คุณอาจประหลาดใจที่ได้เรียนรู้มากกว่าบนเมนเฟรมของไอบีเอ็มด้วยแฟล็กอักขระเดี่ยวที่มี "Y" หรือ "N" เป็นวิธีที่มีประสิทธิภาพที่สุดในการใช้ตรรกะบูลีน
James Anderson

4
โน้ตif (i = 1)น่าจะเป็นมากสิ่งที่ผิดที่จะมีในรหัสหนึ่งของ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.