欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

宏定义导致三目运算结果正确

程序员文章站 2022-03-07 22:02:26
前言:今天记录一下前两天写代码遇到的一个有意思的小问题。这个问题初看很诡异,分析后直击自己知识的浅薄。首先有两个宏定义,以下程序运行均在手机端运行,也就是两个宏定义结果都是YES#define kDeviceiPhone [[UIDevice currentDevice].model isEqualToString:@"iPhone"] ? YES : NO#define kDeviceiPhone [[UIDevice currentDevice].model isEqualToString...

前言:今天记录一下前两天写代码遇到的一个有意思的小问题。这个问题初看很诡异,分析后直击自己知识的浅薄。

首先有两个宏定义,以下程序运行均在手机端运行,也就是两个宏定义结果都是YES

#define kDeviceiPhone [[UIDevice currentDevice].model isEqualToString:@"iPhone"] ? YES : NO

#define kDeviceiPhone [[UIDevice currentDevice].model isEqualToString:@"iPhone"]

这两个宏定义有什么区别吗?如果我用if判断,用一个BOOL类型变量去接收它们,会发现两个宏定义返回的结果是一样的。

为了区分两个宏定义我给它们用两个不同的名字,重新定义一下

#define kDeviceiPhone [[UIDevice currentDevice].model isEqualToString:@"iPhone"] ? YES : NO

#define kDeviceiPhoneDeriected [[UIDevice currentDevice].model isEqualToString:@"iPhone"]

暂且一个叫kDeviceiPhone通过三目运算返回结果,一个叫kDeviceiPhoneDeriected直接就是字符串的isEqualToString返回结果。

接下来就是精彩时刻:

例子一:

你可以猜一下下边代码输出结果

BOOL ret = NO;
    
if(kDeviceiPhone && ret) {
        
   NSLog(@"=====111111======");
}

我定义了一个变量ret,这个ret初始化为NO。所以宏定义kDeviceiPhone && ret结果是什么呢?如果不加思考肯定直接说结果是NO。但是运行代码就会让你大跌眼镜。

程序运行后进入了if判断,控制台输出了=====111111======

宏定义导致三目运算结果正确

 

这是什么情况?稍后咱们再分析,继续举栗子。

例子二:

我们再看另一个宏定义是否也会进入这个判断

 BOOL ret = NO;
    
 if(kDeviceiPhoneDeriected && ret) {
     NSLog(@"+++++22222++++++");
 }
    

理论上宏定义kDeviceiPhoneDeriected返回结果等于kDeviceiPhone的结果,所以跟ret做&&运算,结果应该是一样的,但是这次却不会进入if判断语句,控制台并没有输出任何东西。

我们再看例子三:

BOOL ret = NO;
    
if(ret && kDeviceiPhone) {
   NSLog(@"------3333-------");
}
    

这次我们把例子1中的kDeviceiPhone与ret的顺序变换了一下,结果呢?你猜到了吗?

控制台没有输出,代码并没有进入if语句。what?

是不是颠覆认知,一个宏定义做&&运算跟前后顺序有关系?

再看例子四:

BOOL ret = NO;
    
if(ret && kDeviceiPhoneDeriected) {
   NSLog(@"+++++4444++++++");
}

这个呢?这次的结果是没有进入到if语句判断,控制台没有输出。还好还好,并没有完全颠覆我的认知。

然后看第五个例子:

BOOL ret = NO;
    
if((kDeviceiPhone) && ret) {
   NSLog(@"=====55555======");
}
    

这个例子跟第一个好像,但是有点不同,哪里不同呢,宏定义被小括号包住了,这次结果呢?当然这次结果是没有进入if判断语句,控制台没有打印。

下边就开始我们的分析之旅吧。

宏定义的原理是什么呢?

宏定义是用来将一个标识符定义为一个字符串,该标识符被称为宏名,被定义的字符串称为替换文本。

注意:只是简单的替换而已,不要在中间计算结果,一定要替换出表达式之后再算。

好像找到问题所在了。

那么我们把第一个例子替换一下

[[UIDevice currentDevice].model isEqualToString:@"iPhone"] ? YES : NO && NO

我们if语句判断的是不是就上边这个?分析一下为啥结果是YES。首先三目运算符和&&的优先级你应该是知道的吧,原来就是这里。上边代码执行顺序是什么呢?

宏定义导致三目运算结果正确

根据优先级关系,所以代码先执行&&运算,然后执行三目运算。所以第1步,NO&&NO结果为NO, 上边条件语句相当于[[UIDevice currentDevice].model isEqualToString:@"iPhone"] ? YES : NO,然后是第2步,设备型号判断结果返回是正确的,所以三目运算的结果是YES,当然就能进入到if语句判断。

接下来分析第二个例子,第二个就是

[[UIDevice currentDevice].model isEqualToString:@"iPhone"] && NO;

当然结果是NO,毫无疑问。

例子三对应的判断条件是

NO && [[UIDevice currentDevice].model isEqualToString:@"iPhone"] ? YES : NO;

先&&运算结果为NO,然后三目运算返回的结果肯定是NO了。

例子四不再解释,直接看例子五,其实就是加了一个小括号,当然先算括号里的了,返回结果为YES再&&NO,当然是NO了。

其实上边代码无非就是两个知识点,一个是宏定义的替换,一个是三目运算和&&运算的先后顺序。

代码虽然简单,但是想当然的写代码会有太多坑,知识点还是需要吃透才是关键。

你我共勉!!!

 

本文地址:https://blog.csdn.net/Lu_Ca/article/details/112568043