_Bool 类型
C99 引入了 _Bool 类型作为 C 语言的布尔类型,配合 <stdbool.h> 头文件中的 bool、true、false 宏使用。虽然 C 语言长期以来用整数 0 表示"假"、非 0 表示"真",但 _Bool 提供了语义更清晰的布尔运算方式。
基本用法
包含 <stdbool.h> 后,可以使用 bool、true、false:
#include <stdbool.h>
#include <stdio.h>
int main(void)
{
bool is_ready = true;
bool is_empty = false;
printf("is_ready = %d\n", is_ready); /* 输出 1 */
printf("is_empty = %d\n", is_empty); /* 输出 0 */
if (is_ready)
printf("Ready!\n");
return 0;
}
bool 是 _Bool 的别名(通过 typedef),true 定义为 1,false 定义为 0。_Bool 类型的大小是 1 字节(sizeof(_Bool) 为 1),只能存储 0 或 1。
转换规则
任何标量类型赋值给 _Bool 时,非零值转换为 1,零值转换为 0:
#include <stdbool.h>
bool a = 5; /* 5 非零,a = 1 */
bool b = 0; /* b = 0 */
bool c = 0.001; /* 0.001 非零,c = 1 */
bool d = -100; /* -100 非零,d = 1 */
bool e = NULL; /* NULL 是 0,e = 0 */
这个规则让 _Bool 能安全地接受任何整数或指针值:
int count = 10;
bool has_items = count; /* count != 0,has_items = true */
int *ptr = malloc(sizeof(int));
bool valid = ptr; /* ptr != NULL,valid = true */
free(ptr);
valid = ptr; /* ptr 可能非零(悬垂指针),但逻辑上应设为 false */
注意:释放指针后,指针值不一定变为 NULL,所以 valid = ptr 可能仍为 true。应显式赋值:valid = false; 或 ptr = NULL; valid = ptr;。
与整数的区别
在 C99 之前,C 程序员用 int 表示布尔值:
/* 传统 C89 写法 */
int is_valid = 1; /* 真 */
int is_done = 0; /* 假 */
if (is_valid) { }
C99 的 _Bool 提供了类型安全:
/* C99 写法 */
bool is_valid = true;
bool is_done = false;
虽然底层仍然是整数(true 是 1,false 是 0),但使用 bool 能明确表达意图,提高代码可读性。
逻辑运算
_Bool 支持所有逻辑和比较运算,结果也是 _Bool:
#include <stdbool.h>
bool a = true;
bool b = false;
bool c = a && b; /* 逻辑与:false */
bool d = a || b; /* 逻辑或:true */
bool e = !a; /* 逻辑非:false */
bool f = (5 > 3); /* 比较结果:true */
bool g = (5 == 3); /* false */
逻辑运算符 && 和 || 具有短路求值特性:
bool result = (a && expensive_function());
/* 如果 a 为 false,expensive_function() 不会执行 */
bool result2 = (a || expensive_function());
/* 如果 a 为 true,expensive_function() 不会执行 */
实际应用
函数返回值:
#include <stdbool.h>
bool is_prime(int n)
{
if (n < 2) return false;
for (int i = 2; i * i <= n; i++)
if (n % i == 0) return false;
return true;
}
if (is_prime(17))
printf("17 is prime\n");
状态标志:
#include <stdbool.h>
typedef struct {
bool is_connected;
bool is_authenticated;
bool has_data;
} ConnectionState;
ConnectionState conn = {false, false, false};
if (conn.is_connected && conn.is_authenticated)
printf("Ready to transfer\n");
条件编译中的布尔宏:
#define DEBUG_MODE true
#if DEBUG_MODE
printf("Debug: x = %d\n", x);
#endif
注意:#if 预处理指令中不能使用 bool、true、false,因为它们在预处理阶段还未定义。应使用整数:#define DEBUG_MODE 1。
常见错误
忘记包含头文件:
/* 错误:未包含 <stdbool.h> */
bool flag = true; /* 编译错误:bool 未定义 */
/* 正确 */
#include <stdbool.h>
bool flag = true;
如果不包含 <stdbool.h>,可以直接使用 _Bool、_true、_false(不推荐):
_Bool flag = 1; /* 不使用 <stdbool.h> */
假设 bool 只能存储 true/false:
bool flag = true;
flag = 2; /* 合法!2 非零,转换为 1 */
printf("%d\n", flag); /* 输出 1,不是 2 */
_Bool 的存储值只能是 0 或 1,赋值其他值会自动归一化。
与位运算混淆:
bool a = true;
bool b = true;
bool c = a & b; /* 位运算:1 & 1 = 1,结果 true */
bool d = a && b; /* 逻辑运算:true && true = true */
虽然对 _Bool 来说 & 和 && 结果相同,但 && 有短路求值,& 没有。对布尔值应始终使用逻辑运算符 &&、||、!。