C语言之预处理
2015-12-18 15:05
253 查看
预处理是c语言(也包括OC)的一部分,它们是一些特殊的命令.在编译器对C程序(或者 OC程序)进行编译之前,编译器会对这些预处理命令进行处理,然后将这些处理的结构与源程序一起进行编译.
预处理命令有如下特征.
1)预处理命令必须以#号开头
2)预处理通常位于程序的开头部分
下面一起来看一下几种使用情况:
1: 使用#define,#undef执行宏定义
2: 带参数的宏定义
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之间的语句.
4: 使用#if,#elif,#else,#endif执行条件编译
#if,#elif,#else,#endif提供了更通用的条件编译,它可以对指定的表达式进行推断,
根据表达式的值决定是否要编译指定的语句.语法格式如下:
#if 表达式
//任意语句
#elif 表达式
//任意语句
…可以有0个或者多个#elif语句
#else(注:最后的#else语句可以省略)
//任意语句
#endif
这个条件编译指令的用法与前面差不多,只是该编译器指令中使用的条件要么是常量表达式,要么是基于已有的宏的表达式.
5: #和##运算符
预处理命令有如下特征.
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)); }
相关文章推荐
- liunx c语言制作 微型web服务器 300行代码
- boost库的安装和使用略记
- C++11: tuple
- 帮 C/C++ 程序员彻底了解链接器
- C#应用调试C++ dll的方法
- C++ 回调函数理解
- C/C++异常处理阶段总结
- C++获取网页数据时的505错误
- C++ Primer Pluse(第6版)中文版 第13章13.4静态联编和动态联编中的问题
- 我的C++学习历程(old)
- 为什么C++(感谢waterwalk翻译)
- Why C++
- 【C/C++】BinarySearch
- 为什么C++(来自C++之父的观点)
- C++之父元旦专访(8+13个问题,关于C++的学习&使用和未来)
- C /C++标准库 - <cstddef> (stddef.h)
- 黑马程序员 - OC语言 - 【考点】分类(Category)使用注意事项
- 黑马程序员 - OC语言 - 构造方法的概念
- 【C语言】 简易通讯录
- 黑马程序员 - OC语言 - 响应方法