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?

Bugster
źródło
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.

Andrew T Finnell
źródło
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ć!

Emilio Garavaglia
źródło
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)

Jamie Taylor
źródło
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};
kamikadze
źródło
-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ą.

fjrg76
źródło
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.

Pieter B.
źródło
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.