您的位置:首页 > 编程语言 > C语言/C++

C语言之预处理

2015-12-18 15:05 253 查看
预处理是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));

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: