【原创】bool、BOOL 和 _Bool 辨析

      最近在搞跨平台编译的时候又遇到了 C99 标准支持的问题,主要体现在布尔类型问题上面。于是乎决定把这个问题彻底搞搞清楚,遂成此文。 

【 bool、BOOL 和 _Bool 的区别 】 

      bool 类型在 C++ 中以关键字的形式被支持,表示布尔类型,其对应变量的值只有真(true)和假(false)两种值。 

      BOOL 类型在头文件 <windef.h> 中定义为 typedef int BOOL;在头文件 <wtypes.h> 中定义为 typedef long BOOL;
      BOOL 类型的长度视实际环境来定,一般可认为是 4 个字节。 
      BOOL 是微软定义的表达布尔逻辑的类型。与 C++ 中的 bool 类型不同是,它是一个三值逻辑:TRUE、FALSE 和 ERROR。当返回值为大于 0 的整数时为 TRUE,返回值为 0 时为 FALSE,返回值为 -1 时为 ERROR。 

      _Bool 是 C99 标准中定义的一个新关键字,以提供布尔类型。C2008 草案中只规定了 _Bool 类型的大小至少应能够存放 0 和 1 这两个值。而并没有规定具体的大小。这交给编译器自由发挥了。 

【跨平台如何使用布尔类型】 

      C++ 里有专门的 bool 关键字。但是在 C99 之前,C 语言里没有这样的类型。从 C99 标准开始,增加了关键字 _Bool 用来表示布尔类型。所以只要你的编译器支持 C99,你就可以直接使用布尔型了(当然,VC,VS系列编译器均不支持 C99)。除此之外,C99 为了在 C 中兼容 C++ 里对布尔类型的定义,又增加了一个头文件 stdbool.h。并在其中定义了 bool、true 和 false,让我们可以像 C++ 一样的定义和使用布尔类型。 

使用布尔类型的几种方式: 
a. 自己定义的“仿布尔类型” 
在 C99 标准被支持之前,我们常常自己模仿定义布尔类型,方式有很多种,常见的有下面两种:

/* 第一种方法 */ 

?


1

2

3

typedef int BOOL;

#define TRUE 1

#define FALSE 0

/* 第二种方法 */ 

?


1

enum bool{false, true};

b. 使用 C99 新增的关键字 _Bool

      C99 新增关键字 _Bool 类型的长度为 1,只能取值为 0 或 1 。将任意非零值赋值给 _Bool 类型变量,都会先转换为 1,表示为真。将零值赋值给 _Bool 类型,结果为 0,表示为假。 

c. 使用 C99 新增头文件 stdbool.h 
      在 C++ 中,通过 bool 来定义布尔变量,通过 true 和 false 对布尔变量进行赋值。C99 为了让我们能够写出与 C++ 兼容的代码,添加了头文件 <stdbool.h> 。所以我们只要包含了该头文件,就可以像 C++ 中使用布尔变量的方式进行操作。 

在我自己的 linux 系统中查找 stdbool.h 头文件,找到两处: 
1. 系统定义 

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

[root@Betty ~]# vi /usr/lib/syslinux/com32/include/stdbool.h

 

/*

 * $Id: stdbool.h,v 1.1 2003/04/16 06:32:31 hpa Exp $

 *

 * stdbool.h

 */

 

#ifndef _STDBOOL_H

#define _STDBOOL_H

 

#ifndef __cplusplus

 

#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L)

# if !defined(__GNUC__) ||(__GNUC__ < 3)

  typedef char _Bool;           /* For C compilers without _Bool */

# endif

#endif

 

#define bool  _Bool

#define true  1

#define false 0

 

#else

 

/* C++ */

#define bool  bool

#define true  true

#define false false

 

#endif

 

#define __bool_true_false_are_defined 1

 

#endif /* _STDBOOL_H */

2. GCC 定义

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

[root@Betty ~]# vi /usr/lib/gcc/x86_64-redhat-linux/4.1.1/include/stdbool.h

 

/* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.

 

This file is part of GCC.

 

GCC is free software; you can redistribute it and/or modify

it under the terms of the GNU General Public License as published by

the Free Software Foundation; either version 2, or (at your option)

any later version.

 

GCC is distributed in the hope that it will be useful,

but WITHOUT ANY WARRANTY; without even the implied warranty of

MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

GNU General Public License for more details.

 

You should have received a copy of the GNU General Public License

along with GCC; see the file COPYING.  If not, write to

the Free Software Foundation, 51 Franklin Street, Fifth Floor,

Boston, MA 02110-1301, USA.  */

 

/* As a special exception, if you include this header file into source

   files compiled by GCC, this header file does not by itself cause

   the resulting executable to be covered by the GNU General Public

   License.  This exception does not however invalidate any other

   reasons why the executable file might be covered by the GNU General

   Public License.  */

 

/*

 * ISO C Standard:  7.16  Boolean type and values  <stdbool.h>

 */

 

#ifndef _STDBOOL_H

#define _STDBOOL_H

 

#ifndef __cplusplus

 

#define bool    _Bool

#define true    1

#define false   0

 

#else /* __cplusplus */

 

/* Supporting <stdbool.h> in C++ is a GCC extension.  */

#define _Bool   bool

#define bool    bool

#define false   false

#define true    true

 

#endif /* __cplusplus */

 

/* Signal that all the definitions are present.  */

#define __bool_true_false_are_defined   1

 

#endif  /* stdbool.h */

其实这两个头文件的定义本身还隐形的说明了一些信息,阅者自斟。

时间: 2024-09-11 11:23:04

【原创】bool、BOOL 和 _Bool 辨析的相关文章

浅谈C语言编程中的布尔bool数据类型_C 语言

我们知道在C++里有专门的bool类型,用来表示真或假.但是在C语言里没有这样的类型(至少我是一直这么认为的),表达式的值0为假,非0为真.所以条件判断语句( if(-).while(-) )非常灵活,甚至一个指针类型都可以是条件表达式. 为了使程序更清晰,我们常常会给出如下的宏定义: typedef int BOOL; #define TRUE 1 #define FALSE 0 这是最常见的写法,能被任何C语言编译器认可. 今天我在一段程序里看见这么一行 #include ,这个陌生的头文件

C++中优化BOOL变量的声明

通常我们会这样声明BOOL 变量: class CMyClass { ... BOOL m_bVar1; BOOL m_bVar2; BOOL m_bVar3; BOOL m_bVar4; BOOL m_bVar5; BOOL m_bVar6; BOOL m_bVar7; BOOL m_bVar8; ... }; 考虑到BOOL 变量在Win32 下其实是一个int ,占4个字节,那么上面8个BOOL变量就会占去 32个字节. typedef int BOOL; // BOOL takes 4

C# 系统应用之获取IE浏览记录和IE地址栏输入网址

该文章是"个人电脑历史记录清除软件"项目的系统应用系列文章. 前面"C# 系统应用之清除Cookies.IE临时文件.历史记录"中已经讲述了借助RunDll32.exe运行dll文件实现清除IE缓存操作,同时网上有很多方法讲述删除操作的,但怎样获取IE浏览器中最近浏览的网站历史记录和IE浏览器的地址栏输入的网址呢?这是我这篇文章需要讲解的知识. 一.Environment.GetFolderPath方法获取IE历史记录 前文说过在Windows中IE历史记录的位置为

基于xmpp openfire smack开发之Android客户端开发[3]

在上两篇文章中,我们依次介绍openfire部署以及smack常用API的使用,这一节中我们着力介绍如何基于asmack开发一个Android的客户端,本篇的重点在实践,讲解和原理环节,大家可以参考前两篇的文章 基于xmpp openfire smack开发之openfire介绍和部署[1] 基于xmpp openfire smack开发之smack类库介绍和使用[2]   1.源码结构介绍 activity包下存放一些android页面交互相关的控制程序,还有一个些公共帮助类 db包为sqli

Swift与C#的基础语法比较

背景: 这两天不小心看了一下Swift的基础语法,感觉既然看了,还是写一下笔记,留个痕迹~ 总体而言,感觉Swift是一种前后端多种语言混合的产物~~~ 做为一名.NET阵营人士,少少多多总喜欢通过对比来加深认识. 所以做了一个简单的比较列表. 下面是基础语法的比较:     Swift C#(4.0以上) 常量定义: let name="cyq.data" Const name="cyq.data"; 变量定义: 指定类型: var name="cyq.

CYQ.Data 轻量数据层之路 MDataTable 绑定性能优化之章(十一)

昨天jyk进群后,用Microsoft Application Center Test 对CYQ.Data 框架进行进行了一下压力测试 然后截了几张图上来,只有纯图如下: 1:使用了框架:sql 2000的分页存储过程[临时表分的页]: 2:把存储过程直接换成select语句: 3:他的框架测试结果: 4:这是测试结果了. 以下是说明: 1.DataTable :714次/秒 2.MDataTable:559 次/秒 (简单存储过程) 3.MDataTable:500 次/秒 (完整存储过程)

如何在Cocos2D游戏中实现A*寻路算法(五)

大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交流之用,请勿进行商业用途.同时,转载时不要移除本申明.如产生任何纠纷,均与本博客所有人.发表该翻译稿之人无任何关系.谢谢合作! 跟随着黄色砖块前进 现在我们已经找到了我们的路径,我们只需要让猫咪跟随它. 我们接下来要做的是记住整个路径,并且使得猫咪根据路径一步一步的移动. 在CatSprite.h中建

ansible运维工具filter_plugins插件如何实现jinja2自定义filter过滤器

前言:    filter_plugins是什么? 这个单词拆解下,filter !  熟悉jinja2模板的人,到知道他是过滤器,可以在模板中以管道的方式用pyhton的代码处理字符串. ansible模板调用的是jinja2,这个大家都知道 . 这个filter_plugins插件代码,就是为了更好的处理jinja2模板中的字符串和逻辑判断的. 先前,我和沈灿讨论一个模板的问题,实在蛋疼的要命,总是达不到我们要的数据,当时是做一个数据的统计和rabbitmq的配置,有些地方用jinja2模板

ansible 自定义filter_plugins的用法

ansible playbook 一个非常强大的功能就是允许我们自定义filter_plugins,这个filter_plugin是什么呢? 就是我们一般看到的 {{item|max}} 其实,后边的这个 max就是一个函数,我们可以定义自己的函数,例如: |-- filter_plugins |   |-- zhiming_filter.py |   `-- zhiming_filter.pyc `-- main.yml 目录结构就是我们在我们的playbook下创建filter_plugin