Поиск…


замечания

Чтобы использовать предопределенный тип _Bool и заголовок <stdbool.h> , вы должны использовать версии C99 / C11 C.

Чтобы избежать предупреждений компилятора и, возможно, ошибок, вы должны использовать только пример typedef / define если используете C89 и предыдущие версии языка.

Использование stdbool.h

C99

Используя файл заголовка системы stdbool.h вы можете использовать bool как тип данных Boolean. true оценивает значение 1 а false - 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 - просто хорошее написание для типа данных _Bool . Он имеет специальные правила, когда числа или указатели преобразуются в него.

Использование #define

C всех версий эффективно обрабатывает любое целочисленное значение, отличное от 0 как true для операторов сравнения, а целочисленное значение 0 как false . Если у вас нет _Bool или bool с C99, вы можете имитировать тип данных Boolean на C с помощью макросов #define , и вы все равно можете найти такие вещи в устаревшем коде.

#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!");
    }
}

Не <stdbool.h> это в новый код, так как определение этих макросов может столкнуться с современным использованием <stdbool.h> .

Использование встроенного (встроенного) типа _Bool

C99

_Bool также добавлен в стандартную C-версию C99, а также является родным типом данных C. Он способен удерживать значения 0 (для false ) и 1 (для true ).

#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 - целочисленный тип, но имеет специальные правила для конверсий из других типов. Результат аналогичен использованию других типов в выражениях if . В следующих

_Bool z = X;
  • Если X имеет арифметический тип (любой номер), z становится 0 если X == 0 . В противном случае z становится равным 1 .
  • Если X имеет тип указателя, z становится 0 если X является нулевым указателем и 1 противном случае.

Чтобы использовать более приятные варианты написания bool , false и true вам нужно использовать <stdbool.h> .

Целые и указатели в булевых выражениях.

Все целые числа или указатели могут использоваться в выражении, которое интерпретируется как «значение истины».

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");
  }
...

Выражение argc % 4 оценивается и приводит к одному из значений 0 , 1 , 2 или 3 . Первое, 0 - единственное значение, которое является «ложным» и приносит исполнение в часть else . Все остальные значения являются «истинными» и переходят в часть if .

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

Здесь указатель A оценивается и, если он является нулевым указателем, обнаруживается ошибка и программа завершается.

Многие люди предпочитают писать что-то как A == NULL , но если у вас есть такие сравнения указателей как часть других сложных выражений, вещи становятся очень трудночитаемыми.

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]);
}

Для этого вам нужно будет сканировать сложный код в выражении и быть уверенным в предпочтении оператора.

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]);
}

относительно легко захватить: если указатель действителен, мы проверяем, отличен ли первый символ от нуля, а затем проверьте, является ли это буквой.

Определение типа bool с использованием typedef

Учитывая, что большинство отладчиков не знают макросов #define , но могут проверять константы enum , может быть желательно сделать что-то вроде этого:

#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;

Это позволяет компиляторам для исторических версий C функционировать, но остается передовым, если код скомпилирован с использованием современного компилятора C.

Для получения дополнительной информации о typedef см. Typedef , для получения дополнительной информации о enum см. Перечисления



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow