Kiedy należy używać booli w C ++?


34

Mieliśmy zadanie dla naszej klasy, w którym musieliśmy stworzyć grę w kółko i krzyżyk . Ludzie lubią się komplikować, więc pisali skomplikowane gry zawierające menu. Pod koniec gry trzeba było ponownie zagrać lub wyjść z programu. Użyłem do tego intzmiennej, ale zauważyłem, że niektórzy koledzy z klasy używają BOOL-ów.

Czy to jest bardziej wydajne? Jaka jest różnica między przechowywaniem odpowiedzi, która powinna przechowywać tylko dwie wartości, inta nie przechowywaniem w bool? Jaki jest dokładny cel tych zmiennych?


32
Nie jestem pewien co do wydajności, ale celem intjest przechowanie liczby całkowitej, a celem booljest przechowanie wartości logicznej ( truelub false). Korzystanie z boolIMO znacznie lepiej odzwierciedla jego wykorzystanie niż używanie int.
— George Duckett,

12
W rzeczywistości przed C ++ i C99 C89 nie miał typu logicznego. Programiści często typedef int Boolw celu wyjaśnienia, że ​​używają wartości logicznej. C ++ zintegrowało obsługę booljęzyka, podobnie jak C99 ze (raczej brzydkim) _Boolsłowem kluczowym.
— Charles Salvia,

Nie chodzi o „wiedzieć, kiedy używać bool”, chodzi o to, dlaczego mamy różne nazwy dla podobnych typów (jak length_t) i dlaczego ważne jest, aby kompilator sprawdzał typy.
— Abyx,

Czasami odpowiedzią jest po prostu „smak”. Założę się, że jeśli teraz przepisujesz teraz to samo zadanie, będzie kilka różnych rzeczy, takich jak kolejność parametrów funkcji i ich nazwy. Dlaczego nie napisałeś tej samej kolejności parametrów lub tej samej nazwy? To dlatego, że po prostu tego nie zrobiłeś lub to nie było bardzo ważne i po prostu napisałeś cokolwiek

Odpowiedzi:


82

Wybierając typy zmiennych i nazwy zmiennych, chcesz, aby Twoje zamiary były tak jasne, jak to możliwe. Jeśli wybierzesz booltyp (boolean), jasne jest, że istnieją tylko dwie dopuszczalne wartości: truelub false. Jeśli użyjesz typu int(liczba całkowita), nie jest już jasne, że intencją tej zmiennej może być tylko 1 lub 0 lub dowolne wartości, które chcesz oznaczać truei false. Plus sizeof(int)zwykle zwraca 4 bajty, podczas gdy sizeof(bool)zwraca 1.


7
Zgoda. Myślę, że zamiary projektowe są ważniejsze. Tylko od czasu do czasu będziesz musiał je zastąpić.
— ChrisF

9
Aby powtórzyć punkt @ AndrewFinnel: Bool jest bardziej samo dokumentujący. Zmienna ustawiona na 0 lub 1 może być licznikiem; zmienna ustawiona na true lub false jest wyraźnie flagą.
— Scott C Wilson,

2
Bools zapobiegają nadużywaniu zmiennej do innych zastosowań. Liczba całkowita może być ustawiona na wartości inne niż 0 lub 1, aby utworzyć dodatkowe stany, o których Twój kod może nie wiedzieć.
— Michael Shopsin

+1. Wyjaśnia intencję / opcje. Możesz użyć dowolnej metody przechowywania wartości, w tym ciągu o wartości „tak” lub „nie”, ale powinieneś wybrać tę, która ma NAJBARDZIEJ sens. W tym przypadku jest to wartość logiczna.
— Craige,

Myślałem, że booleany w C ++ są tego samego rozmiaru co ints, 4 bajty.
— DogDog,

53

Wydaje się we wszystkich (do teraz) gromadzone odpowiedzi nikt nie złapał fakt, że OP mówił o BOOLnie bool.

Ponieważ pytanie jest oznaczone jako C ++, należy zauważyć, że:

  • intjest liczbą całkowitą, która waha się od makr INT_MINdo INT_MAX- zdefiniowanych, <climits>których wartości zależą od architektury komputera hostującego. W C ++ wartości te są również dostępne odpowiednio std::numeric_limits<int>::min()i ...:max()). Zachowanie operatorów logicznych zastosowane do inttraktowania 0jako fałszywe, a wszystko inne jako prawdziwe .
  • BOOLjest tylko wskazówką sugerującą zachowanie typu boolean dla int. Jest zdefiniowany <cstddef>jako

    #define BOOL int
    #define TRUE 1
    #define FALSE 0
    
  • BOOLjest więc niczym więcej niż cukrem syntaktycznym, bo tym, co - według kompilatora - jest niczym więcej niż int. Jest to coś, czego używają programiści C, ale programiści C ++ powinni unikać, ponieważ C ++ ma bool.

  • booljest typem integralnym języka, którego obsługiwane wartości to just truei false. Po przekształceniu int truestaje się 1 i falsestaje się 0.

Ważnym aspektem jest to, że jest bardziej bezpieczny przed błędami programowania:

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

niemożliwe jest kodowanie odpowiednim typem bool:

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

Używanie BOOLzamiast booljest tylko złym nawykiem odziedziczonym po chwalebnej przeszłości, którego nikt tak naprawdę nie jest w stanie zapomnieć, tworząc stary problem dla mniej chwalebnego jutra.

Nauczyciele języka powinni poważnie o tym pomyśleć!


9
BOOL nie jest częścią C ++ ani języka C. BOOL z dużymi literami jest najczęstszym sposobem, w jaki booleany były implementowane w C, w dawnych czasach, gdy C nie miał typu boolowskiego. Na przykład interfejs API systemu Windows zdefiniuje BOOL. Co więcej, nie wiadomo, jak zdefiniowano BOOL, niektóre aplikacje mogą zdefiniować go jako jedno-bitowe pole bitowe. Nie można zakładać, że zawsze jest równa int tylko dlatego, że jakaś określona biblioteka definiuje to w ten sposób.

1
+1. Być może rzeczywiście miał na myśli BOOL, a nie bool. Być może BOOL może zostać zaimplementowany na potencjalnie różne sposoby, chociaż Codereview prawdopodobnie nie wie o tym, jeśli zadaje takie pytanie. Widzi, że jest on zdefiniowany jako int, więc naturalnie pyta, dlaczego nie może po prostu użyć int.
— Neil,

1
@Lundin: w ogólnym sensie masz rację, ale zastanów się, że jest to odpowiedź, która mieści się w zakresie pytania, w którym PO mówił o BOOL i int równoważności.
— Emilio Garavaglia

Mimo to pomysł użycia BOOL lub bool do oznaczenia zamiaru nadal obowiązuje.
— Andrew T Finnell,

1
@zvrba: prawda, ale wynika to ze sposobu, w jaki MS postanowił zaimplementować bool we własnych kompilatorach. Dotyczy to tylko kompilatorów MS pracujących dla procesorów Intel. Należy zauważyć, że w przypadku platformy Intel każdy typ integralny krótszy niż 32 bity wymaga maskowania na wejściu lub wyjściu. Ale char [] są nadal używane i niekoniecznie zawsze zastępowane przez int []
— Emilio Garavaglia

6

Typy bool są mniejsze niż typy Int, dlatego zajmują mniej miejsca w pamięci. W zależności od systemu, w którym kompilujesz / dla, liczba Int może wynosić 4–8 bajtów, podczas gdy wartość Bool to 1 bajt (jak widać w tym artykule MSDN )

Połącz to z niektórymi aspektami KISS i dobrego projektu programu, i staje się oczywiste, dlaczego lepiej jest używać bool do przechowywania zmiennej, która będzie miała tylko 2 wartości.

Po co nadmiernie komplikować rzeczy za pomocą obiektu, który może przechowywać szeroki zakres wartości, skoro masz pewność, że zawsze musisz przechowywać tylko 1 z 2 różnych wartości?

Co dzieje się w systemie, który używa int, jeśli przechowujesz w nim 75? Jeśli dodano dodatkowe warunki warunkowe

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

lub

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

wtedy jesteś objęty tą sytuacją. Ale jeśli nie, to nie jesteś.

Możesz mieć również przypadek (w zależności od tego, jak zmieniasz wartość int), w którym występuje przepełnienie bufora, a wartość „resetuje” z powrotem do 0 lub dolnej granicy int (która może być gdzieś w region od -127 do −9 223 372,036,854,775,808, w zależności od architektury docelowej ). Co dzieje się wtedy w kodzie?

Jeśli jednak użyłeś bool, możesz użyć czegoś takiego:

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

Lub nawet:

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

lub nawet:

return continueBool;

W zależności od kompilatora mogą istnieć optymalizacje, które może wykonać na kodzie używającym Boolsa do przechowywania mapowanych wartości prawda / fałsz. Chociaż mogą nie istnieć optymalizacje, które może wykonać dla Ints do przechowywania odwzorowanych wartości prawda / fałsz.

Musimy również pamiętać, że C ++ (wraz z C, asemblerem i FORTRAN) służy do pisania bardzo wydajnego, małego i szybkiego kodu. Tak więc lepiej byłoby użyć Bool w tym przypadku - szczególnie jeśli jesteś zaznaczony na podstawie używania zmiennych, pamięci, pamięci podręcznej lub czasu procesora.

Podobne pytanie brzmi: dlaczego miałbym przechowywać liczbę całkowitą (wartość) w liczbach zmiennoprzecinkowych? Odpowiedź: Nie powinieneś, bo nie ma sensu.

Krótko mówiąc: Jako nauczyciel / korepetytor / wykładowca / profesor, aby omówić z tobą rozmiary różnych rodzajów wartości (na wypadek, gdybyś to przegapił) i dlaczego są one ważne w rozwoju oprogramowania.

Mam nadzieję, że to pomoże jako punkt wyjścia (mam również nadzieję, że nie wydaje się to pedantyczne)


4
Niepotrzebne użycie nagrody if (). Po prostu napisz return value >= 0;dla pierwszego przykładu.
— zvrba

Nie byłem pewien, czy OP rozumie składnię. Czasami opłaca się być trochę bardziej gadatliwym niż zwykle - zwłaszcza, że ​​OP wspomniało, że to zadanie
— Jamie Taylor

2
Nie można się nie zgodzić, ale jedynie wskazać, że oszczędność trzech bajtów poprzez wybranie bool zamiast int nie zrobi zauważalnej różnicy w przypadku większości programów. Nie martw się o wydajność, dopóki naprawdę nie masz problemu z wydajnością!
— James Anderson

@James: również w wielu przypadkach nie zapisujesz trzech bajtów, ponieważ następna zmienna, chyba że jest to kolejna wartość logiczna lub znak, prawdopodobnie zostanie wyrównana do granicy czterech bajtów.
— JeremyP

1

Celem jest jasność intencji. Typ zwracany jest częścią interfejsu funkcji, a boolmówi więcej o tym, czego można oczekiwać od funkcji niż an int.

Nawet BOOLjest bardziej wyrazisty niż int, chociaż jest tego samego typu, co najmniej pokazuje twoje zamiary.

Jednak żaden z nich nie jest tym, co poleciłbym:

enum class UiCmd {QUIT, START_GAME};

-1

W programowaniu chcesz reprezentować coś z prawdziwego życia w kodzie. Mimo, że int i bool mogą zrobić to samo, podśrodkowa idea jest zupełnie inna: przy użyciu bool odpowiedź może być tak lub nie; i to wszystko, taka jest intencja. Za pomocą liczb całkowitych możesz reprezentować ilości bez kropki dziesiętnej. I w tym samym duchu, dlaczego miałbyś wybierać liczbę całkowitą, kiedy podwójne może zrobić to samo? Jeśli podczas modelowania problemu liczba całkowita ma większy sens niż liczba podwójna, możesz wybrać liczbę całkowitą.


1
wydaje się, że nie oferuje to nic istotnego w porównaniu z punktami przedstawionymi i wyjaśnionymi w najwyższej odpowiedzi tutaj, opublikowanej około 6 lat temu
— komara

-2

Ponieważ w końcu i tak zamienisz liczbę całkowitą na wartość logiczną: „jeśli (i = 1), to zagraj w inną grę”. W tej sytuacji (i = 1) jest konwertowany na true lub false: boolean.


zależy bardzo od tego, na której maszynie pracujesz i od kompilatorów. Możesz być zaskoczony, gdy dowiadujesz się, że na komputerach mainframe IBM pojedyncza flaga z literą „Y” lub „N” jest najbardziej wydajnym sposobem implementacji logiki logicznej.
— James Anderson

4
Warto zauważyć, że if (i = 1)prawdopodobnie jest to bardzo niewłaściwa rzecz w kodzie.
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.