Używanie wartości logicznych w C

C nie ma żadnych wbudowanych typów logicznych. Jak najlepiej wykorzystać je w C?

 543
Author: Peter Mortensen, 2009-12-17

13 answers

Opcja 1

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

Opcja 2

typedef int bool;
enum { false, true };

Opcja 3

typedef enum { false, true } bool;

Wariant 4 (C99)

#include <stdbool.h>

Wyjaśnienie

  • opcje 1, 2 i 3 będą miały w praktyce takie samo zachowanie. #2 i # 3 nie używają jednak # defines, co moim zdaniem jest lepsze.
  • opcja 4 będzie działać tylko wtedy, gdy używasz C99 i jest to" standardowy sposób", aby to zrobić. Wybierz tę opcję, jeśli to możliwe.

Jeśli jesteś niezdecydowany, idź z #3!

 850
Author: Andreas Bonini,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-17 14:20:36

Kilka myśli na temat booleanów w C:

Jestem na tyle stary, że po prostu używam zwykłego int s jako mojego typu boolean bez typedefów lub specjalnych definicji lub enums dla wartości true/false. Jeśli zastosujesz się do mojej sugestii, aby nigdy nie porównywać ze stałymi logicznymi, wystarczy użyć 0/1, aby i tak zainicjować flagi. Jednak takie podejście może być uznane za zbyt reakcyjne w dzisiejszych czasach. W takim przypadku należy zdecydowanie użyć <stdbool.h>, ponieważ przynajmniej ma on korzyści z standaryzacja.

Niezależnie od tego, jakie stałe są wywoływane, używaj ich tylko do inicjalizacji. Never ever write something like

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

Te mogą być zawsze zastąpione przez jaśniejsze

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

Zauważ, że można je czytać na głos w sposób rozsądny i zrozumiały.

Nadaj zmiennej logicznej pozytywne nazwy, tj. full zamiast notfull. Ten ostatni prowadzi do kodu, który jest trudny do odczytania łatwo. Porównaj

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

Z

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

Obie pierwsze pary czytają w sposób naturalny, podczas gdy {[13] } jest niewygodne w czytaniu, nawet tak jak jest, i staje się znacznie gorsze w bardziej złożonych wyrażeniach logicznych.

Należy unikać argumentów logicznych. Rozważmy funkcję zdefiniowaną w ten sposób

void foo(bool option) { ... }

Wewnątrz ciała funkcji, jest bardzo jasne, co oznacza argument, ponieważ ma wygodną, i miejmy nadzieję sensowną nazwę. Ale strony połączeń wyglądają jak

foo(TRUE);
foo(FALSE):

Tutaj zasadniczo nie można powiedzieć, co parametr oznaczał, nie patrząc zawsze na definicję funkcji lub deklarację, a jest znacznie gorzej, gdy dodasz jeszcze więcej parametrów logicznych. Proponuję albo

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

Lub

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

W obu przypadkach Strona wywołania wygląda teraz jak

foo(OPT_ON);
foo(OPT_OFF);

Które czytelnik ma przynajmniej szansę zrozumieć bez pogłębiania definicji foo.

 196
Author: Dale Hagglund,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-14 21:46:16

Logiczna w C jest liczbą całkowitą: zero dla false i niezerową dla true.

Zobacz typ danych Boolean , section C, C++, Objective-C, AWK.

 78
Author: Fortega,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-31 11:30:41

Oto wersja, której użyłem:

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

Ponieważ false ma tylko jedną wartość, ale logiczna prawda może mieć wiele wartości, ale technika ustawia true jako wartość, której kompilator użyje dla przeciwieństwa false.

To rozwiązuje problem kogoś, kto koduje coś, co sprowadza się do tego:

if (true == !false)

Myślę, że wszyscy zgodzilibyśmy się, że nie jest to dobra praktyka, ale za jeden raz koszt wykonania " true = !false " eliminujemy ten problem.

[[7]} [Edytuj] w koniec użyłem:
typedef enum { myfalse = 0, mytrue = !myfalse } mybool;

Aby uniknąć kolizji nazw z innymi schematami, które definiowały true i false. Ale koncepcja pozostaje taka sama.

[Edytuj] aby pokazać konwersję liczby całkowitej na wartość logiczną:

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

Pierwszy (najbardziej prawy) ! konwertuje niezerową liczbę całkowitą na 0, a następnie drugą (najbardziej lewą) ! konwertuje wartość 0 Na wartość myfalse. Zostawię to jako ćwiczenie dla czytelnika, aby przekonwertować zerową liczbę całkowitą.

 60
Author: Michael Potter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-16 21:00:27

Jeśli używasz kompilatora C99, ma on wbudowane wsparcie dla typów bool:

#include <stdbool.h>
int main()
{
  bool b = false;
  b = true;
}

Http://en.wikipedia.org/wiki/Boolean_data_type

 36
Author: Gary Willoughby,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-26 05:30:34
typedef enum {
    false = 0,
    true
} t_bool;
 17
Author: mouviciel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-17 12:51:15

C ma typ boolean: bool (przynajmniej przez ostatnie 10(!) lat)

Include stdbool.h I true / false będą działać zgodnie z oczekiwaniami.

 10
Author: dmeister,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-17 13:28:42

Wszystko, co niezerowe jest oceniane jako true w operacjach logicznych, więc możesz po prostu

#define TRUE 1
#define FALSE 0

I użyj stałych.

 8
Author: ggambett,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-17 12:48:43

Po kolei. C, tj. ISO / IEC 9899 ma typ boolean od 19 lat . Jest to znacznie dłuższy czas niż oczekiwany Długość kariery programisty C z częściami amatorskimi / akademickimi/zawodowymi połączonymi podczas wizyty to pytanie . Mój przewyższa to o jakieś 1-2 lata. Jednak w czasie , gdy przeciętny czytelnik dowiedział się czegoś o C, C faktycznie miał boolean typ danych.

Dla datatype, #include <stdbool.h>, i używać true, false i bool. Lub nie obejmują go, i używać _True, _False i _Bool zamiast tego.


W tym wątku odpowiedzi są różne niebezpieczne Rady. Zwracam się do nich:

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

To Nie-Nie, ponieważ przypadkowy czytelnik - który nauczył się C w ciągu tych 19 lat - spodziewałby się, że bool odnosi się do rzeczywistej bool typ danych i zachowywałby się podobnie, ale tak nie jest! Na przykład

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

Z C99 bool / _Bool, b zostanie ustawione na false MFF a było zero, a true inaczej. Z typedef w miejscu, double będzie zmuszony do int - jeśli wartość double nie jest w zakresie int int, zachowanie jest niezdefiniowane .

Oczywiście to samo dotyczy, Jeśli true i false zostały zadeklarowane w enum.

Co jest nawetbardziej niebezpieczne deklaruje

typedef enum bool {
    false, true
} bool;

Ponieważ teraz wszystkie wartości oprócz 1 i 0 są nieważne, a jeśli taka wartość zostanie przypisana do zmiennej tego typu, zachowanie będzie całkowicie niezdefiniowane .

Dlatego iff nie możesz używać C99 z jakiegoś niewytłumaczalnego powodu, dla zmiennych logicznych powinieneś użyć:

  • type int and values 0 and 1 w 2007 roku, w wyniku połączenia z innymi domenami, liczba domen została zmieniona na 100.]}
  • lub jeśli nalegasz nie pamiętasz, że 0 jest falsyfikatem i niezerowe truish, przynajmniej użyj wielkich liter , aby nie pomylić ich z pojęciami C99: BOOL, TRUE i FALSE!
 8
Author: Antti Haapala,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-18 16:36:47

@Thomas Matthews: wyrażenia warunkowe są uważane za prawdziwe, jeśli są niezerowe, ale standard C wymaga, aby same operatory logiczne zwracały 0 LUB 1.

@ Tom: #define TRUE !Fałsz jest zły i całkowicie bezcelowy. Jeśli plik nagłówkowy trafi do skompilowanego kodu C++, może to prowadzić do problemów:

void foo(bool flag);

...

int flag = TRUE;
foo(flag);

Niektóre Kompilatory wygenerują ostrzeżenie o konwersji int = > bool. Czasami ludzie unikają tego, robiąc:

foo(flag == TRUE);

Aby wymusić wyrażenie być C++ bool. Ale jeśli # define TRUE !FALSE, kończy się na:

foo(flag == !0);

Co kończy się wykonaniem porównania int-to-bool, które i tak może wywołać Ostrzeżenie.

 1
Author: jamesdlin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-18 04:17:30

To jest to:

#define TRUE 1
#define FALSE 0
 0
Author: RngTng,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-18 22:59:52

Możesz użyć znaku lub innego kontenera o małej liczbie.

Pseudo-kod

#define TRUE  1
#define FALSE 0

char bValue = TRUE;
 0
Author: Filip Ekberg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-14 22:18:26

Możesz po prostu użyć dyrektywy #define w następujący sposób:

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

I używać w następujący sposób:

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

I tak..on

 -1
Author: Prakash Bhattarai,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-26 01:31:16