【IOS 开发学习总结-OC-7.4】objective-c与c语言的预处理
来源:互联网 发布:公司seo是什么意思 编辑:程序博客网 时间:2024/05/02 11:14
在编译器对 C或者 objective-c 进行编译前,编译器会对这些预处理命令进行处理,然后将这些预处理的结果与源程序一起编译。
预处理命令的2个特征:
1.都必须以#开头
2.通常位于程序开头部分。
使用#define及#undef 执行宏定义
这里#define的作用是:为字符串起一个名字。可以使用更有意义的名字代替原来的字符串。为编程提供便利。
示例:#define PI 3.14159
,通常来说,宏名称通常会使用所有字母的大写形式。
宏定义注意点:
- 宏定义不是C 语句。无需用分号结束,也不要使用=进行赋值。
- 宏定义不是变量。不要对宏名称进行赋值。
- 编译器处理宏定义,只是进行”查找,替换”,要保证宏定义是正确的。
执行宏定义后,该宏的作用 域为定义该宏开始,直到该源代码结束,如果想提前结束宏定义,可以使用语句:#undef 宏名称
示例代码:
#import <Foundation/Foundation.h>// 定义PI代替3.1415926#define PI 3.1415926int main(int argc , char * argv[]){ @autoreleasepool{ NSLog(@"请输入圆的半径:"); double radius; scanf("%lg" , &radius); // 使用PI NSLog(@"圆周长:%g" , PI * 2 * radius); NSLog(@"圆面积:%g" , PI * radius * radius); }}
开发技巧:
实际项目开发中,常把一些未来可能需要修改的值定义成宏,这样可以避免批量更改代码中的值。
宏定义还可以引用另一个已有的宏,从而形成嵌套替换的宏。示例代码:
#import <Foundation/Foundation.h>// 定义PI代替3.1415926#define PI 3.1415926// 直接使用前面已有的PI来定义新的宏#define GIRTH(r) (PI * 2 * (r))// 直接使用前面已有的PI来定义新的宏#define AREA(r) (PI * (r) * (r))int main(int argc , char * argv[]){ @autoreleasepool{ NSLog(@"请输入圆的半径:"); double radius; scanf("%lg" , &radius); // 使用宏执行计算 NSLog(@"圆周长:%g" , GIRTH(radius)); NSLog(@"圆面积:%g" , AREA(radius)); }}
带参数的宏定义
除了定义简单的宏以外,可以在宏定义中使用参数,这样定义的宏更灵活。
语法格式为:#define 宏名称(参数列表) 字符串
示例代码:
#import <Foundation/Foundation.h>// 定义PI代替3.1415926#define PI 3.1415926// 直接使用前面已有的PI来定义新的宏#define GIRTH(r) (PI * 2 * (r))// 直接使用前面已有的PI来定义新的宏#define AREA(r) (PI * (r) * (r))int main(int argc , char * argv[]){ @autoreleasepool{ NSLog(@"请输入圆的半径:"); double radius; scanf("%lg" , &radius); // 使用宏执行计算 NSLog(@"圆周长:%g" , GIRTH(radius)); NSLog(@"圆面积:%g" , AREA(radius)); }}
注意:因为宏定义只是执行简单查找和替换,当传入的参数是个表达式的时候,常会出现一些我们不希望出现的错误。所以,为了编译器能正确处理宏定义,建议将宏定义中的参数用圆括号括起来。如果整个宏定义返回的是数值,可再将整个宏定义的字符串用圆括号括起来。就像上面的代码那样做的。
使用#ifdef,#ifndef,#else,#endif 执行条件编译
有时候需要选择性编译——比如对于特定的设备,只编译该设备相关的代码,就可以借助条件编译来完成。
语法格式1:
#ifdef 宏名称//任意语句#endif
如果定义了指定的宏,则执行#ifdef 和#endif之间的语句。
语法格式2:
#ifdef 宏名称 //任意语句#else //任意语句#endif
如果定义了指定的宏,则执行#ifdef 和#else之间的语句,否则执行#else和#endif之间的语句。
与此类似的一组,是#ifndef, # else,#endif 组成的。也跟上面是一个形式,只是把#ifdef换成了#ifndef。#ifndef的意思是如果没有定义指定的宏。
语法格式1:
#ifndef 宏名称//任意语句#endif
如果没有定义指定的宏,则执行#ifndef 和#endif之间的语句。
语法格式2:
#ifndef 宏名称 //任意语句#else //任意语句#endif
如果没有定义指定的宏,则执行#ifndef 和#else之间的语句,否则执行#else和#endif之间的语句。
示例代码:
// 定义iPad宏#define iPadint main(int argc , char * argv[]){ @autoreleasepool{ #ifdef iPad NSLog(@"这是iPad平板"); NSLog(@"下面执行关于iPad的代码"); #else NSLog(@"这是iPhone手机"); NSLog(@"下面执行关于iPhone的代码"); #endif }}
通过上面代码中的条件编译语句,源程序可以不做任何修改就可以自动适应不同的设备。
宏定义用法@利用宏定义控制调试信息是否输出
利用宏定义控制调试信息是否输出。示例代码:
#import <Foundation/Foundation.h>int main(int argc , char * argv[]){ @autoreleasepool{ for(int i = 0 ; i < 10 ; i++) { #ifdef DEBUG NSLog(@"调试输出:i的值为,%d" , i); #endif } }}
使用#if,#elif,#else,#endif 提供了更通用的条件编译
可以对表达式进行判断,根据表达式的值决定是否要编译指定的语句。
语法格式:
#if 表达式//任意语句#elif 表达式...// 可以有零到多个#elif 语句#else//任意语句#endif
示例代码:
#import <Foundation/Foundation.h>#define AGE 25int main(int argc , char * argv[]){ @autoreleasepool{ #if AGE > 60 NSLog(@"老年人"); #elif AGE > 40 NSLog(@"中年人"); #elif AGE > 20 NSLog(@"青年人"); #else NSLog(@"少年人"); #endif }}
有了流程控制语句,条件编译指令还有什么卵用?
条件编译是在编译器编译之前进行的预处理。使用条件编译指令后,不符合条件的程序语句根本不会编译;而普通的分支语句呢,所有的代码都被编译成执行性代码,程序运行时再根据需要决定执行哪些语句。这就意味着普通分支语句,生成的文件更大,而且执行效率更低(需在运行时判断条件)。
#include
与#import
C语言提供了#include ,objective-c 提供了比#include更好用#import。OC 也能使用#include 但不推荐。
- # include 指令的作用很简单:将指定的源码插入到当前代码的制定位置。但有个显著的缺点,需要程序员自行判断是否重复导入。但#import可以帮助判断,避免重复导入的问题。
#import "Apple"
和#import <Foundation/Foundation.h>
中引号和尖括号的作用是神马?——双引号,告诉预处理程序到当前文件所在路径搜索指定的源文件(也可通过 Xcode 的项目设置来设置预处理的搜索路径);而尖括号<>,告诉预处理程序到相应的系统头文件路径中搜索。
- 【IOS 开发学习总结-OC-7.4】objective-c与c语言的预处理
- 【IOS 开发学习总结-OC-7.5】objective-c 的c语言特性——结构体
- 【IOS 开发学习总结-OC-6】objective-c 的数组
- IOS开发之路-Objective-C OC学习总结
- 【IOS 开发学习总结-OC-2】objective-c 数据类型
- 【IOS 开发学习总结-OC-3】objective-c 类型转换
- 【IOS 开发学习总结-OC-4】objective-c 运算符
- 【IOS 开发学习总结-OC-7.8-★★】 objective-c——指针与数组
- 【IOS 开发学习总结-OC-7.10-★】 objective-c——函数与指针
- 【IOS 开发学习总结-OC-5】objective-c 的流程控制
- 【IOS 开发学习总结-OC-23】★objective-c的反射机制
- 【IOS 开发学习总结-OC-18】★★objective-c面向对象之——OC的包装类与对象处理
- 【IOS 开发学习总结-OC-7.2】C 语言特性——局部变量与全局变量
- 【IOS 开发学习总结-OC-7.3】C 语言特性——动态存储与静态存储
- 【IOS 开发学习总结-OC-12】★objective-c面向对象之——合成存取方法与点语法
- 【IOS 开发学习总结-OC-19】★★objective-c面向对象之——类别与扩展
- 【IOS 开发学习总结-OC-26】★★★objective-c——foundation 框架之日期与时间
- 【IOS 开发学习总结-OC-7.11-★】 objective-c——指针数组和指向指针的指针
- 终于狠下心做了一点小突破
- 信号量 互斥锁 条件变量的区别
- Joomla开发者文档
- Struts2环境配置
- java Biginteger类和BigDecimal类
- 【IOS 开发学习总结-OC-7.4】objective-c与c语言的预处理
- 4、XML
- 动态规划算法
- Java中选择排序,冒泡排序等排序方法示例
- maching learning NG的matlab作业代码
- Multi-host, Multi-stage Vulnerability Analysis Language
- 关于高速缓存和I/O高速缓冲的讲解
- Android WebView下载apk
- Apache 80端口被IIS或其他服务占用怎么处理