C语言之预处理

来源:互联网 发布:修复php intl.dll软件 编辑:程序博客网 时间:2024/05/21 10:14

预处理是c语言(也包括OC)的一部分,它们是一些特殊的命令.在编译器对C程序(或者 OC程序)进行编译之前,编译器会对这些预处理命令进行处理,然后将这些处理的结构与源程序一起进行编译.

预处理命令有如下特征.
1)预处理命令必须以#号开头
2)预处理通常位于程序的开头部分

下面一起来看一下几种使用情况:

1: 使用#define,#undef执行宏定义

#define PI 3.14159-(void)testOne{    /*#define的作用就是为字符串起一个名字.例如: #define PI 3.14159. 这里的PI就代表3.14159      注意事项:1)宏定义不是c语言,因此不需要在宏名称与字符串之间使用=进行赋值.              2)宏定义不是变量,也不是常量,所以不要对宏名称进行赋值.              3)编译器处理宏定义只是进行"査找,替换"----将所有出现宏名称的地方替换成为该宏中对应的字符串.              4)通常来说,宏名称会使用所有字母大写形式.              5)执行宏定义开始后,该宏的作用域为宏定义开始直至源码结束.如果希望提前结束宏定义,可以使用.#undef 宏名称.    */    NSLog(@"%f",PI*2); //预处理 6.283180    //添加    //#undef PI    //NSLog("%f",PI*2);//如果再次使用将提示错误,没有声明PI.}

2: 带参数的宏定义

#define AREA(r)  PI * r * r #define AREAONE(r)  (PI * (r) * (r))-(void)testTwo{    //定义带参数宏的语法: #define 宏名称(参数列表) 字符串    NSLog(@"%f",AREA(2)); //预处理 12.566360    //但是这里存在一个风险,因为编译器对宏只是执行简单的"査找,替换".因此,如果我们调用如下参数:    NSLog(@"%f",AREA(10+2));// 预处理 53.415900.    //那么计算公式就成为了PI * 10 +2 * 10 +2 ,所以这里并不是我们原来希望的,先计算10+2.然后再作为参数计算.    //为了能够正确处理宏定义,所以使用圆括号将参数括起来.如:#define AREAONE(r)  (PI * (r) * (r))    NSLog(@"%f",AREAONE(10+2));//预处理 452.388960}

3: 使用#ifdef,#ifndef,#else,#endif执行条件编译

通常来说,源代码中所有的代码行都会参与编译,最后生成执行性代码,但是有些时候,
程序需要根据机器环境进行选择性的编译–对于特定的设备,只编译该设备相关的代码,
这可以借助条件编译来完成.

c语言支持两组条件编译指令,第一条是#ifdef,#ifndef,#else,#endif,语法如下:

1):
#ifdef 宏名称
//任意语句(可以编写多个语句)
#endif
这里表示:如果定义了指定的宏,则执行#ifdef和#endif之间的语句.

也可以如下:

#ifdef 宏名称
//任意语句
#else
//任意语句
#endif
这里表示:如果定义了指定的宏定义,则执行#ifdef和#else之间的语句.否则执行#else和 #endif之间的语句.

2):
对于 #ifdef指令还有一种否定写法:
#ifndef 宏名称
//任意语句
#endif
这里表示:如果没有定义指定的宏,则执行#ifndef和#endif之间的语句.

同样也有:

#ifndef 宏名称
//任意语句
#else
//任意语句
#endif

这里表示:如果没有定义指定的宏定义,则执行#ifndef和#else之间的语句.否则执行#else和 #endif之间的语句.

#define iPhone-(void)testThree{           #ifdef iPhone                  NSLog(@"下面执行iPhone相关代码");           #else                  NSLog(@"下面执行iPad相关代码");           #endif          //预处理 下面执行iPhone相关代码.          一个很好的实际应用例子就是NSLog的使用:          #ifndef __OPTIMIZE__  // __OPTIMIZE__ 是release 默认会加的宏          #define NSLog(...) NSLog(__VA_ARGS__)          #else          #define NSLog(...){}          #endif}

4: 使用#if,#elif,#else,#endif执行条件编译

#if,#elif,#else,#endif提供了更通用的条件编译,它可以对指定的表达式进行推断,
根据表达式的值决定是否要编译指定的语句.语法格式如下:

#if 表达式
//任意语句
#elif 表达式
//任意语句
…可以有0个或者多个#elif语句
#else(注:最后的#else语句可以省略)
//任意语句
#endif

这个条件编译指令的用法与前面差不多,只是该编译器指令中使用的条件要么是常量表达式,要么是基于已有的宏的表达式.

#define AGE 30-(void)testFour{        #if AGE > 60            NSLog(@"老年人");        #elif AGE > 40            NSLog(@"中年人");        #elif AGE > 20            NSLog(@"年轻人");        #else            NSLog(@"少年人");        #endif      // 预处理[4793:1211851] 年轻人}

5: #和##运算符

#define STR(s) # s#define CONCAT(a, b) a##b // ##运算符在宏表达式中连接几个参数#define VERSION \3                         // 因为有换行符\ 所以上句等价于 #define VERSION 3-(void)testFive{    NSLog(@"%s",STR(3));    NSLog(@"%d",CONCAT(3, 4));}
0 0
原创粉丝点击