IOS 预处理语句
程序中的源代码计算机是无法识别的,需要将写好的代码转成0、1二进制代码,计算机才能识别。将源代码转成二进制代码的需要经过两步,编译和链接。编译是通过编译器将每个文件的代码都转为二进制代码,在这个过程中,如果有语法错误,会有编译失败的提示,如果成功,那么会生成对应多个目标文件。在一个文件中可能会用到其他文件,因此,还需要将编译生成的目标文件和系统提供的文件组合到一起,这个过程就是链接。经过链接,最后生成了可执行文件。
通常人们所理解的程序运行就是编译和链接两个阶段,但实际上在编译之前预处理器要进行预处理操作,处理完之后才进入到编译阶段。因为预处理指令是在编译之前就行进了,所以它比程序运行时进行操作的效率高。
预处理程序实际上是在分析程序前先处理的语句,它可以识别散步在程序中的特定语句。所有的预处理语句都使用井号(#)开头,这个符号必须是一行中的第一个非空字符。
预处理语句可以大概划分成三类:文件包含、宏定义和条件编译,下面,就一一来讲解。
文件包含
文件包含指的是在当前文件中用到其他文件中的函数或方法或者是其他信息时,可以将其他文件的头文件包含进来,然后再当前文件中使用,文件包含一般放到文件的开头位置。
如果使用C语言编程,文件包含是#include<> 或者 #include“”。如果使用Objective-C语言,文件包含为#import<>或者#import“”。#include与#import最大的区别是#import在导入文件的时候进行了去重复检查。此外,“”和<>两个也是有区别的,“”是用来放自己写的文件,<>用来放系统文件。程序在执行的时候,会根据你写的样式,优先去寻找对应类型的文件。比如<>,会先去找系统的文件,如果找不到,再去找自定义的文件。所以,正确的选择样式,能够提高程序的运行效率。
在使用文件包含的时候,会遇到A文件中用到B文件,B文件中用到A文件,这种相互使用包含的关系,这种情况就有点像死循环了,要使用A文件,必须要先有B,可是在B中,又需要先有A,因此在运行的时候,会出现错误。解决这个问题最好的办法,是用@class代替文件包含,@class就是表明有这个类,等在源文件中真正用到的时候再包含文件。
代码:
// A.h
// Test
//
// Created by jerei on 15-7-24.
// Copyright (c) 2015年 jerehedu. All rights reserved.
// #import <Foundation/Foundation.h>
@class B;
@interface A : NSObject @property (nonatomic, strong) B *obj; @end //
// B.h
// Test
//
// Created by jerei on 15-7-24.
// Copyright (c) 2015年 jerehedu. All rights reserved.
// #import <Foundation/Foundation.h>
@class A;
@interface B : NSObject @property (nonatomic, strong) A *obj; @end
宏定义
在程序中,有一些常量或者简短的函数是会多次重复使用的,对于这些常用的数据,我们可以使用宏定义。使用宏定义可以快速的完成程序中多处的配置,最大的好处是只要修改宏定义的值,所有使用宏定义的值都会发生改变。此外,宏定义是在程序编译之前进行替换和设置,比定义成全局变量或函数的效率要高。
宏定义是通过#define来实现的,一般写在程序的文件包含的下面。宏名通常用全部的大写字母表示。下面,就通过代码举来看一下宏定义的使用。
代码:
// main.m
// Test
//
// Created by jerei on 15-7-24.
// Copyright (c) 2015年 jerehedu. All rights reserved.
// #import <Foundation/Foundation.h> #define JR_PI 3.14 #define JR_MAX(a,b) ((a>b)?(a):(b)) //得到两个数中较大值 #define JR_SQUARE_1(n) n*n //求数字的平方
#define JR_SQUARE_2(n) (n)*(n) //求数字的平方 #define JR_HELLO @"hello world"; int main(int argc, const char * argv[]) {
@autoreleasepool { int num1 = JR_MAX(, );
NSLog(@"max = %i",num1);
//结果: max = 2 int num2 = JR_SQUARE_1();
NSLog(@"2的平方 = %i",num2);
//结果:2的平方 = 4 int num3 = JR_SQUARE_1(+);
NSLog(@"(2+1)的平方 = %i",num3);
//结果:(2+1)的平方 = 5 int num4 = JR_SQUARE_2(+);
NSLog(@"(2+1)的平方 = %i",num4);
//结果:(2+1)的平方 = 9
}
return ;
}
在代码中可以看到,同样都是求一个数的平方,但是两个宏定义得到的结果却是不一样的。第一个计算2+1的平方的时候是2+1*2+1,所以结果为5,答案错误。因此,在写宏定义,带参数的时候,需要设置小括号,保证正确性。
条件编译
条件编译其实就在编译之前由预处理器来根据预处理语句进行判断,如果满足条件,就编译满足条件下面的代码段,如果不满足条件,下面的代码段就不进入编译环节。
条件编译主要分为两种,一种是判断是否定义过某个宏,根据是否定义过这个宏,来决定是否编译某段代码。另外,还有一组语句和条件结构中的阶梯if结构非常类似,但是写法上有所区别,是#if、#elif、#else、#endif组成。需要注意的是,无论哪种,都要有#endif结束标志。此外,最重要的一点是,条件编译中的条件不能使用普通的变量,一般会选择使用宏定义。
代码:
// main.m
// Test
//
// Created by jerei on 15-7-24.
// Copyright (c) 2015年 jerehedu. All rights reserved.
// #import <Foundation/Foundation.h> #define JR_COUNT 10 int main(int argc, const char * argv[]) {
@autoreleasepool { #if defined(JR_COUNT)
NSLog(@"定义了 COUNT 这个宏");
#endif #if defined(JR_MAX)
NSLog(@"没有定义了 JR_MAX 这个宏");
#endif #if JR_COUNT==1
NSLog(@"JR_COUNT=1");
#elif JR_COUNT==2
NSLog(@"JR_COUNT=2");
#elif JR_COUNT==3
NSLog(@"JR_COUNT=3");
#else
NSLog(@"JR_COUNT=%i",JR_COUNT);
#endif }
return ;
}
疑问咨询或技术交流,请加入官方QQ群:
(452379712)
出处:http://www.cnblogs.com/jerehedu/
本文版权归烟台杰瑞教育科技有限公司和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
IOS 预处理语句的更多相关文章
- 前端学PHP之PDO预处理语句
× 目录 [1]定义 [2]准备语句 [3]绑定参数[4]执行查询[5]获取数据[6]大数据对象 前面的话 本来要把预处理语句和前面的基础操作写成一篇的.但是,由于博客园的限制,可能是因为长度超出,保 ...
- mysql之预处理语句prepare、execute、deallocate
预制语句的SQL语法基于三个SQL语句: PREPARE stmt_name FROM preparable_stmt; EXECUTE stmt_name [USING @var_name [, @ ...
- php pdo预处理语句与存储过程
很多更成熟的数据库都支持预处理语句的概念.什么是预处理语句?可以把它看作是想要运行的 SQL 的一种编译过的模板,它可以使用变量参数进行定制.预处理语句可以带来两大好处: 1.查询仅需解析(或预处理) ...
- MySQL预处理语句
预制语句的SQL语法基于三个SQL语句: PREPARE stmt_name FROM preparable_stmt; EXECUTE stmt_name [USING @var_name [, @ ...
- PDO 学习与使用 ( 二 ) PDO 数据提取 和 预处理语句
以数据库 msg 为例,说明 PDO 的数据提取.预处理语句: mysql> show tables;+---------------+| Tables_in_msg |+----------- ...
- PHP基础知识之————PDO预处理语句
转载处:http://www.cnblogs.com/xiaohuochai/p/6133353.html 定义 在生成网页时,许多PHP脚本通常都会执行除参数之外,其他部分完全相同的查询语句,针对这 ...
- PHP MySQL 预处理语句
PHP MySQL 预处理语句 预处理语句对于防止 MySQL 注入是非常有用的. 预处理语句及绑定参数 预处理语句用于执行多个相同的 SQL 语句,并且执行效率更高. 预处理语句的工作原理如下: 预 ...
- mysql中SQL执行过程详解与用于预处理语句的SQL语法
mysql中SQL执行过程详解 客户端发送一条查询给服务器: 服务器先检查查询缓存,如果命中了缓存,则立刻返回存储在缓存中的结果.否则进入下一阶段. 服务器段进行SQL解析.预处理,在优化器生成对应的 ...
- PDO预处理语句规避SQL注入攻击
所谓SQL注入式攻击,就是攻击者把SQL命令插入到Web表单的输入域或页面请求的查询字符串,欺骗服务器执行恶意的SQL命令.在某些表单中,用户输入的内容直接用来构造(或者影响)动态SQL命令,或作为存 ...
随机推荐
- 基于jquery扩展漂亮的CheckBox
大家都知道默认的html复选框控件样式可定义相当有限,无法满足大多用户的美观度.今天跟大家一起分享前一段时间自己编写的CheckBox控件.喜欢的朋友可以拿去使用,有什么好的建议希望你给我留言.废话不 ...
- 2017-2018-1 20179202《Linux内核原理与分析》第二周作业
本周着重学习了汇编指令,并通过反汇编C程序了解栈帧变化. 实践 看了孟老师的演示视频后,我重新写了C程序,如下: int main() { int a=1,b=2; return g(a,b); } ...
- Vijos1448 校门外的树 [树状数组]
题目传送门 校门外的树 描述 校门外有很多树,有苹果树,香蕉树,有会扔石头的,有可以吃掉补充体力的……如今学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现有两个操作:K= ...
- 【小思考】Python里面有声明和定义分离这一说么?
第一部分: 探究这个问题,还是因为编程的时候碰到了这个错误: 提示tcplink没有定义,tcplink是我自己写的一个给监听到的tcp连接请求分配新线程的函数,不过是写在了下面,就像这样: 如果是C ...
- 【BZOJ 4380】4380: [POI2015]Myjnie (区间DP)
4380: [POI2015]Myjnie Description 有n家洗车店从左往右排成一排,每家店都有一个正整数价格p[i].有m个人要来消费,第i个人会驶过第a[i]个开始一直到第b[i]个洗 ...
- android studio 可以汉化的 文件 地方
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha 汉化包 百度云盘 下载地址:https://pan.baidu.com/s/1pLjwy ...
- SpringBoot 解决时区问题
SpringBoot 解决时区问题 1.在启动类加上 @PostConstruct void setDefaultTimezone() { TimeZone.setDefault(TimeZone.g ...
- hdu 5206 Four Inages Strategy 判断是否是正方形
Four Inages Strategy Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem. ...
- python相对包导入报“Attempted relative import in non-package”错误
文章是从stackoverflow翻译过来的,原文地址:Relative imports for the billionth time 本文要在原理上解决 python当中相对包导入出现的问题. 问 ...
- 点广告获取一些BTC(比特币)的网站
免费获取比特币:http://freebtc.qiniudn.com/freebtc.html free btc:http://freebtc.qiniudn.com/freebtc.html ...