xml地图|网站地图|网站标签 [设为首页] [加入收藏]

C中的BOOL你了解吗

来源:http://www.ccidsi.com 作者:集成经验 人气:159 发布时间:2020-04-15
摘要:真。Vēritās。管理学的成套大纲都成立在对它的物色上,可它的贴切含义和满含照旧未有完全展今后大家近日。真相是单独存在的,依然被有标准的定义反对虚假?三个命题是不是足以

真。Vēritās。管理学的成套大纲都成立在对它的物色上,可它的贴切含义和满含照旧未有完全展今后大家近日。真相是单独存在的,依然被有标准的定义反对虚假?三个命题是不是足以同一时候是真和假?是还是不是有绝没有错真理,依旧一切都以绝对的?

Objective-C用BOOL来编码真值,它是signed char的typedef,何况用宏YES和NO来代表真和假。

0 前言

7月8日付出的代码在服务端编写翻译现身了错误,而本机编写翻译进程中尚无其余难题。定位到不当日志,发掘是因为错把函数参数类型BOOL写成bool(Xcode自动补全的锅#_#)引起布尔值类型转变难题。

error: incompatible block pointer types sending 'void (^__strong)(BOOL)' to parameter of type 'void (^)(bool)'

在刚接触Objective-C语法的时候,以为BOOL类型和C/C 中的bool关键字相同归于语言等级的原生类型,只是Objective-C选择了字母全大写的款式,何况clang编写翻译器也支撑C/C ,由此在编写Objective-C代码时就主动将BOOLbool品种看作二次事。
BOOLbool是还是不是真正等同呢?为何本机与服务器编写翻译进度中会现身二种处境吧?

假,相当于0。0是极为重要的数字,0的开采被誉为人类伟大的意识之一。最早,阿拉伯数字中未有“0”,经过1000多年后才产生了“0”。 ”零”发源于印度共和国,后来流传了波士顿.未有“0”那一个数字时,为了表示某一人上叁个计数单位也从不,就“不写”或“空写”。后来,菲律宾人在数字中间加上小点“.”表示空位,又过了相当短日子,小点便改成“0”。

布尔值用于标准推断,举个例子if和while语句,来進展有准绳的逻辑只怕重国民党的新生活运动行。当判定四个条件语句,数值0为“假”,而其他任何数值为“真”。因为NULL和nil被定义为0,所以对于折现不设有的数值的尺度语句也被判别为“假”。

1 真假布尔类型

C99规范提供了bool类型,大家得以像int/double类型相似定义布尔变量。但bool实际不是是非同小可字,它实质上是二个宏定义,真正的布尔关键字是_Bool
_Bool类型变量占1个字节空间,1意味着布尔真值,0意味着布尔假值。
以下代码取自于stdbool.h头文件的源代码,5-7行表明了bool只是_Bool的宏定义,何况truefalse也分别定义为1和0。

// stdbool.h http://clang.llvm.org/doxygen/stdbool_8h_source.html
#ifndef __STDBOOL_H
#define __STDBOOL_H
/* Don't define bool, true, and false in C  , except as a GNU extension. */
#ifndef __cplusplus
#define bool _Bool
#define true 1
#define false 0
#elif defined(__GNUC__) && !defined(__STRICT_ANSI__)
/* Define _Bool, bool, false, true as a GNU extension. */
#define _Bool bool
#define bool  bool
#define false false
#define true  true
#endif
#define __bool_true_false_are_defined 1
#endif /* __STDBOOL_H */

既然C99中的bool只是_Bool关键字的宏定义,那Objective-C中的BOOL到底是什么样吗?

// objc.h
#define OBJC_BOOL_DEFINED

/// Type to represent a boolean value.
#if (TARGET_OS_IPHONE && __LP64__)  ||  TARGET_OS_WATCH
#define OBJC_BOOL_IS_BOOL 1
typedef bool BOOL;
#else
#define OBJC_BOOL_IS_CHAR 1
typedef signed char BOOL; 
// BOOL is explicitly signed so @encode(BOOL) == "c" rather than "C" 
// even if -funsigned-char is used.
#endif

#if __has_feature(objc_bool)
#define YES __objc_yes
#define NO  __objc_no
#else
#define YES ((BOOL)1)
#define NO  ((BOOL)0)
#endif

没有错,BOOL也是宏定义,在objc.h头文件的源代码中它被定义为signed char项目,见代码8-10行。(注:在陆拾几人的HTC平台以至iWatch平台下,BOOL等价于bool,见代码5-7行)
在Objective-C代码中平淡无奇应用的YESNO也只是signed char类型的1和0,见代码19-20行。

再壹次,将我们有逻辑的世界编码为冷落的微型机总括字节码使得我们只可以用这么或那样的措施管理那一个难题。同一时候,通过翻阅我们关于Objective-C中布尔值及其同类的探讨,你会开掘,真相实乃比小说还奇怪。

在Objective-C中,当际遇处理真值的参数、属性和实例变量时,使用处目BOOL。当分配字面值时,使用宏YES和NO。

2 真假值的论断

平凡情状下,布尔值仅用于规范决断,因为它只有二种情景:/
在C语言中,平日以为变量值等于0为假,不然值为真。比如:

// c language
if (var != 0) {
  // 真
} else {
  // 假
}

使用那个特点,非常轻松写出认清四个整型变量是不是不等于的函数

// c language
int different(int a, int b) {
  return a - b;
}

在C99规范现身后,能够动用bool来声称布尔类型以致规格推断,bool本质是_Bool类型关键字,_Bool类型的值只会是1或0。
假使出现任何体系变量值转变为_Bool类型,那么非0值都将被转换为1,也正是true,而0值仍为0,即false。
因此,different函数能够重写为:

// c99
bool different(int a, int b) {
  return a - b;
}
ret = different(a, b);  // 这里ret的值只可能是1(true)或0(false)

different(10, 11) == true;  //   (bool)-1 == true -> 1 == 1 真
different(256, 0) == true;  //  (bool)256 == true -> 1 == 1 真
different(11, 10) == true;  //    (bool)1 == true -> 1 == 1 真

然而,Objective-C的BOOL是signed char类型,因而BOOL类型的值范围是-128 ~ 127不单是1(YESState of Qatar或0(NO卡塔尔(قطر‎,个中0表示值为假,其他值均表示值为真。
在此种宏定义下,直接将BOOL类型的值与YES对比会产出部分难以置信景况,因为YES真值等于1,而BOOL类型的真值并不一定是1。
平时来讲代码仅仅将函数再次回到值类型更动为BOOL类型,但却赢得了错误的结果。

// Objective-C
BOOL different(int a, int b) {
  return a - b;
}

different(10, 11) == YES;  // -1 == 1 假
different(256, 0) == YES;  //  0 == 1 假
different(11, 10) == YES;  //  1 == 1 真

因为无法保证函数再次来到值类型为BOOL的函数一定再次来到了YES也许NO,所以对BOOL类型的值作判断时应有制止与真值YES直接相比较

当推断贰个准绳语句,数值0为“假”,而任何任何数值为“真”。因为NULL和nil被定义为0,所以对于那么些不设有的数值的尺码语句也被决断为“假”。

荒诞难点的失实答案

新手平日在尺度推断时踏向等号运算符:

if ([a isEqual:b] == YES) {
    ...
}

那不唯有是不供给的,並且据书上说右侧的值,它有希望会招致不可预料的结果。正如Big Nerd Ranch blog post, "BOOL's Sharp Edges"中所描述的那么:

static BOOL different (int a, int b) { 
    return a - b;
}

而是,因为BOOL在骨子里中被typedef为signed char,所以结果并不会像预想的那么:

if (different(11, 10) == YES) { 
    printf ("11 != 10n");
} else { 
    printf ("11 == 10n");
}
if (different(10, 11) == YES) { 
    printf ("10 != 11n");
} else { 
    printf ("10 == 11n");
}
if (different(512, 256) == YES) {
    printf ("512 != 256n");
} else { 
    printf ("512 == 256n");
}

此结果为:
11 != 10 10 == 11 512 == 256

它大概符合语法,但是它在语意上完全说不通。所以,代替他的艺术是,使用==输出结果,可能将数值通过!(或者!!State of Qatar转变到布尔值。

3 总结

  • bool和BOOL都以宏定义,并非关键字;bool等价于_Bool类型,BOOL在六13人iOS平台或iWatch平台下等价于bool,在其他平台等价于signed char类型。
  • bool和BOOL类型变量只占多个字节空间,但bool类型独有1(true卡塔尔国和0(falseState of Qatar三种值,而BOOL类型的值范围是-128 ~ 127。
  • bool类型值可与true直接举办相比,而BOOL类型值与YES进行相比较频仍获得错误的结果。

BOOL也是宏定义,在objc.h头文件的源代码中它被定义为signed char类型

关于NSNumber和BOOL的真相

下边包车型客车表明式会输出什么?

NSLog(@"%@", [@(YES) class]);

答案是:
__NSCFBoolean

NSCFBoolean是NSNumber类簇中的三个私有的类。它是向阳CFBooleanRef类型的桥梁,它被用来给Core Foundation的习性列表和集中封装布尔数值。CFBoolean定义了常量kCFBooleanTrue和kCFBooleanFalse。因为CFNumberRef和CFBooleanRef在Core Foundation中归属分化种类,那样是有道理的,它们在NSNumber被以差别的衔接类展现。

下边的表格是Objective-C中的全数真值类型和数值:

Name Typedef Header True Value False Value
BOOL signed char objc.h YES NO
bool _Bool(int) stdbool.h true false
Boolean unsigned char MacTypes.h TRUE FALSE
NSNumber __NSCFBoolean Foundation.h @(YES) @(NO)
CFBooleanRef struct CoreFoundation.h kCFBooleanTrue kCFBooleanFalse

4 Reference

  • http://nshipster.cn/bool/
  • https://www.bignerdranch.com/blog/bools-sharp-corners/

    Update October 2013 - On 64-bit iOS (device and simulator) BOOL is now actually bool, so the sharp corners have thankfully gone away for that platform.

  • http://stackoverflow.com/questions/3016846/is-there-any-difference-between-bool-and-boolean-in-objective-c

  • http://niehan.blog.techweb.com.cn/archives/228.html

在objc.h文件中定义:

本文由68399皇家赌场发布于集成经验,转载请注明出处:C中的BOOL你了解吗

关键词: 68399皇家赌场 iOS 神奇 简介 iOS开

最火资讯