Szukaj…


Uwagi

Aby użyć predefiniowanego typu _Bool i nagłówka <stdbool.h> , musisz używać wersji C99 / C11 C.

Aby uniknąć ostrzeżeń kompilatora i ewentualnych błędów, powinieneś używać przykładu typedef / define wtedy, gdy używasz C89 i poprzednich wersji języka.

Korzystanie ze stdbool.h

C99

Użycie systemowego pliku nagłówkowego stdbool.h pozwala na użycie bool jako logicznego typu danych. true ocenia na 1 a false na 0 .

#include <stdio.h>
#include <stdbool.h>

int main(void) {
    bool x = true;  /* equivalent to bool x = 1; */
    bool y = false; /* equivalent to bool y = 0; */
    if (x)  /* Functionally equivalent to if (x != 0) or if (x != false) */
    {
        puts("This will print!");
    }
    if (!y) /* Functionally equivalent to if (y == 0) or if (y == false) */
    {
        puts("This will also print!");
    }
}

bool to po prostu niezła pisownia dla typu danych _Bool . Ma specjalne zasady, gdy konwertowane są na nią liczby lub wskaźniki.

Używanie #define

C wszystkich wersji skutecznie będzie traktować dowolną wartość całkowitą inną niż 0 jako true dla operatorów porównania, a wartość całkowitą 0 jako false . Jeśli nie masz _Bool lub bool od C99, możesz symulować typ danych Boolean w C przy użyciu makr #define , a nadal możesz znaleźć takie rzeczy w starszym kodzie.

#include <stdio.h>

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

int main(void) {
    bool x = true;  /* Equivalent to int x = 1; */
    bool y = false; /* Equivalent to int y = 0; */
    if (x) /* Functionally equivalent to if (x != 0) or if (x != false) */
    {
        puts("This will print!");
    }
    if (!y) /* Functionally equivalent to if (y == 0) or if (y == false) */
    {
        puts("This will also print!");
    }
}

Nie wprowadzaj tego w nowym kodzie, ponieważ definicja tych makr może kolidować z nowoczesnymi zastosowaniami <stdbool.h> .

Korzystanie z wewnętrznego (wbudowanego) typu _Bool

C99

Dodane w standardowej wersji C C99, _Bool jest również rodzimym typem danych C. Jest w stanie utrzymać wartości 0 (dla fałszu ) i 1 (dla prawdy ).

#include <stdio.h>

int main(void) {
    _Bool x = 1; 
    _Bool y = 0;
    if(x) /* Equivalent to if (x == 1) */
    {
        puts("This will print!");
    }
    if (!y) /* Equivalent to if (y == 0) */
    {
        puts("This will also print!");
    }
}

_Bool jest liczbą całkowitą, ale ma specjalne reguły dla konwersji z innych typów. Wynik jest analogiczny do użycia innych typów w wyrażeniach if . W następującym

_Bool z = X;
  • Jeśli X ma typ arytmetyczny (dowolna liczba), z staje się 0 jeśli X == 0 . W przeciwnym razie z staje się 1 .
  • Jeśli X ma typ wskaźnika, z staje się 0 jeśli X jest wskaźnikiem pustym, a 1 przeciwnym razie.

Aby użyć lepszej pisowni bool , false i true , musisz użyć <stdbool.h> .

Liczby całkowite i wskaźniki w wyrażeniach boolowskich.

Wszystkie liczby całkowite lub wskaźniki mogą być użyte w wyrażeniu interpretowanym jako „wartość prawdy”.

int main(int argc, char* argv[]) {
  if (argc % 4) {
    puts("arguments number is not divisible by 4");
  } else {
    puts("argument number is divisible by 4");
  }
...

Wyrażenie argc % 4 jest oceniane i prowadzi do jednej z wartości 0 , 1 , 2 lub 3 . Pierwszy 0 jest jedyną wartością, która jest „false” i przynosi wykonanie do else części. Wszystkie pozostałe wartości są „prawdziwe” i przechodzą do części if .

double* A = malloc(n*sizeof *A);
if (!A) {
   perror("allocation problems");
   exit(EXIT_FAILURE);
}

Tutaj wskaźnik A jest oceniany, a jeśli jest wskaźnikiem zerowym, wykrywany jest błąd i program kończy działanie.

Wiele osób woli zamiast tego pisać jako A == NULL , ale jeśli masz takie porównania wskaźników jako część innych skomplikowanych wyrażeń, rzeczy stają się szybko trudne do odczytania.

char const* s = ....;   /* some pointer that we receive */
if (s != NULL && s[0] != '\0' && isalpha(s[0])) {
   printf("this starts well, %c is alphabetic\n", s[0]);
}

Aby to sprawdzić, musisz zeskanować skomplikowany kod w wyrażeniu i upewnić się co do preferencji operatora.

char const* s = ....;   /* some pointer that we receive */
if (s && s[0] && isalpha(s[0])) {
   printf("this starts well, %c is alphabetic\n", s[0]);
}

jest stosunkowo łatwy do przechwycenia: jeśli wskaźnik jest prawidłowy, sprawdzamy, czy pierwszy znak jest różny od zera, a następnie sprawdzamy, czy jest to litera.

Definiowanie typu bool za pomocą typedef

Biorąc pod uwagę, że większość debuggerów nie zna makr #define , ale może sprawdzać stałe enum , pożądane może być wykonanie czegoś takiego:

#if __STDC_VERSION__ < 199900L
typedef enum { false, true } bool;
/* Modern C code might expect these to be macros. */
# ifndef bool
#  define bool bool
# endif
# ifndef true
#  define true true
# endif
# ifndef false
#  define false false
# endif
#else
# include <stdbool.h>
#endif

/* Somewhere later in the code ... */
bool b = true;

Pozwala to na działanie kompilatorów dla historycznych wersji C, ale pozostaje kompatybilny do przodu, jeśli kod jest skompilowany z nowoczesnym kompilatorem C.

Aby uzyskać więcej informacji na temat typedef patrz typedef , aby uzyskać więcej na enum zobaczyć Wyliczenia



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow