笔记-iOS预处理

预处理

程序中的源代码计算机是没法识别的,须要将写好的代码转成0、1二进制代码,计算机才能识别。将源代码转成二进制代码须要两步:编译和连接编程

编译是经过编译器将每一个文件的代码都转为二进制代码,在这个过程当中,若是有语法错误,会有编译失败的提示,若是成功,那么会生成对应多个目标文件。在一个文件中可能会用到其余文件,所以,还须要将编译生成的目标文件和系统提供的文件组合到一块儿,这个过程就是连接,最后生成了可执行文件。
一般人们所理解的程序运行就是编译和连接两个阶段,但实际上在编译以前,预处理器要进行预处理操做,处理完以后才能进入到编译阶段。由于预处理指令是在编译以前就进行了,因此它比程序运行时进行操做的效率高。bash

预处理程序其实是在分析程序前先处理的语句,它能够识别散布在程序中的特定语句。全部的预处理语句都适用"#"开头,这个符号必须是一行中的第一个非空字符。函数

预处理能够大概分为三类:文件包含、宏定义和条件编译ui

文件包含

文件包含:在当前文件中用到其它文件中的函数或方法或其它信息时,能够将其它文件的头文件包含进来,而后再当前文件中使用,文件包含通常放到文件的开头。spa

若是使用C语言编程,文件包含是#include<>或者#include""。若是使用Objective-C语言,文件包含为#import<>或者#import""#include#import最大的区别是:#import在导入文件的时候进行了去重复检查,此外,""和<>二者也是有区别的,""通常是用来引用自定义的文件,<>通常是用来引用系统的文件。程序在执行的时候,会根据你写的样式,优先去寻找对应类型的文件。好比<>会先去找系统文件,若是找不到,再去找自定义文件。因此正确的选择样式,可以提升程序的执行效率。code

循环引用:在使用文件包含的时候,会遇到A文件中用到B文件,B文件中用到A文件,这种互相使用包含的关系就有点相似死循环了,运行的时候就会报错。解决这个问题最好的办法就是用@Class代替文件包含,@Class就是代表有这个类,等在源文件中真正用到的时候才会去包含文件。get

宏定义

在程序中,有一些常量或者简短的函数会被屡次重复调用的,对于这些经常使用的数据,咱们可使用宏定义。使用宏定义能够快速的完成程序中的多处配置,最大的好处就是只要修改宏定义的值,全部使用宏定义的值都会发生改变。此外,宏定义是在程序编译以前进行替换和设置,比定义成全局变量或者函数的效率要高编译器

宏定义是经过 #define来实现的,通常写在程序文件包含的下面。宏名一般用所有的大写字母表示。string

条件编译

条件编译:在编译以前由预处理器来根据处理语句进行判断,若是知足条件,就编译知足条件下的代码。反之就不进入编译环节。
条件编译主要分为两种:一种是判断是否认义过某个宏,根据是否认义过这个宏,来决定是否编译某段代码。另外,还有一组语句和条件结构中的阶梯if结构很是相似,可是写法上有区别,是 #if、#elif、#else、#endif组成。须要注意的是,不管哪一种,都要有 #endif结束标志。此外,最重要的一点是: 条件编译中的条件不能使用普通变量,通常会选择使用宏定义。io

#import <Foundation/Foundation.h>
#define ZB_COUNT 10

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        #if defined(ZB_COUNT)
            NSLog(@"定义了 COUNT 这个宏");
        #endif
        
        #ifndef defined(ZB_MAX)
            NSLog(@"没有定义 ZB_COUNT 这个宏")
        #endif
        
        #if ZB_COUNT== 1
            NSLog(@"ZB_COUNT=1");
        #elif ZB_COUNT==2
            NSLog(@"ZB_COUNT=2");
        #elif ZB_COUNT==3
            NSLog(@"ZB_COUNT=3");
        #else
            NSLog(@"ZB_COUNT=%i", ZB_COUNT);
        #endif
    }
    return 0;
}
复制代码

最后补充一下预处理经常使用指令:

# 空指令,没有任何效果
#include 包含一个源代码文件
#define 定义宏
#undef 取消定义宏
#if 若是条件为真,则编译下面的代码
#elif 若是前面的#if不为真,则编译下面的代码
#endif 结束一个#if。。。#elif条件编译块
#ifdef 若是已经定义了某个宏,则编译下面的代码
#ifndef 若是没有定义某个宏,则编译下面的代码
#error 中止编译并显示错误信息
复制代码

原文

相关文章
相关标签/搜索