原文地址:

http://blog.csdn.net/kindazrael/article/details/8108868

Objective-C : #define 用法解析

在 C 语言中,预处理代码 (Preprocessor) 是非常强大的工具,能让你的代码变得更加易读和易改。利用预处理代码,你可以重新定义代码的一部分,使得你的代码更适合你的风格。预处理代码 (Preprocessor) 在代码编译之前被提前处理。预处理代码均由一个井号 (#) 打头。

1. 关于 #define

#define 声明主要用于将常量(或字符串)赋予有意义的名字,比如当你在编写一个日历程序时,可以定义:

#define MONTHS_PER_YEAR 12

请注意格式。#define 命令之后为常量名,再之后为所赋的代替值,用空格隔开,结尾不需分号。

#define 常量名 代替值

通常情况下,习惯将预处理的常量名全大写,单词之间用下划线隔开(与正常变量区分)。这样做的原因是在编译器处理这段 #define 代码时,会自动寻找空格,空格之后的被认为是代替值。这也是为什么在每一行代码的末尾不用加分号的原因,因为如果加了分号,分号本身也会被认为是代替值的一部分。

一个被定义的常量名并不是一个变量;它的值一旦被定义,便不能再被改变。 #define 声明通常位于一个文件的顶部,紧接在 #import 文件导入定义之后。需要注意的是, #define 声明必须位于常量名使用之前(不像方法 (method) 可以放在文件中任意位置)。

使用 #define 的另一个例子是储存一些有意义的数值, 比如

#define PI 3.141592654
// 计算圆的面积使用 "PI * radius * radius" 即可

,这比处处书写 3.141592654 要方便许多。(改起来也快很多)

2. 更高级的用途

注意,预处理代码起的作用实际上相当于在编译之前,在整个代码中进行了一次“搜索、替换”功能。这意味着 #define 有许多更复杂、更高级的用途。

我们先从 2π 开始,将 TWO_PI 定义为 2π:

#define TWO_PI 2.0 * 3.141592645

由于我们之前曾定义过 π,我们同样可以在定义中使用定义后的常量名来指代:

#define TWO_PI 2.0 * PI

除了常量以外,你还可以利用预处理定义 Objective-C 代码中任意一段字符或字符串,例如:

#define AND &&
#define OR ||
#define EQUALS == if (y EQUALS OR y EQUALS ) // …

合理地利用 #define,可增强代码的可读性。对比下列两行代码:

if ((year %  ==  && year %  != ) || (year %  == ))

// 或

#define IS_LEAP_YEAR (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)
if (IS_LEAP_YEAR) // 代码可读性更强。

一个定义通常应在一行代码中完成。但如果你需要手动空行,那么在每行后输入一个后划线(\)即可将几行代码连接起来成为一行。例如:

#define IS_LEAP_YEAR(y) (y % 4 == 0 && y % 100 != 0) \
|| (y % == ) if ( IS_LEAP_YEAR(currentYear) )

3. 宏

#define 声明中还可以使用参数,并且可使用多个参数;这一特性被称为“宏”:

如:

#define SQUARE(x) ( (x) * (x) )

此时, y = SQUARE(v + 1); 等价于 y = ( (v + 1) * (v + 1) );

两个参数

例如,你可以定义:

#define CalcInterest(x,y) ( x * y )

代码中便可书写:

int earnings = CalcInterest(,));

多个参数

例如,在代码中,你需要频繁使用 [NSArray arrayWithObjects: object, ..., nil] 这一命令。利用#define,你可以简化代码:

#define Array(FIRST, ...) [NSArray arrayWithObjects: FIRST, ##__VA_ARGS__, nil]

其中 ##__VA_ARGS__ 用于表示省略号所代表的所有内容。

4. # 算符以及 ## 算符

# 算符可产生一个 C-语言 格式的字符串。如:

#define string(x) #x //则 string(testing) == "testing"

## 算符用来连接两段字符串。假设你有一组变量,x1 到 x100。如果你想打印其中某一个变量的值。你可以这样定义:

#define printxvar(n) printf("%i\n", x ## n)

由此, printxvar(20); 在编译时将被识别为 printf(“%i\n”, x20);。这样只需要输入 printxvar(n);便可以打印出 xn 的值。

其实,##最常用的用途还是上面介绍的 ##__VA_ARGS__,它可用来抓取省略号所代表的所有内容。

Objective-C #define 用法解析 (转)的更多相关文章

  1. #define用法解析

    #define Add(a,b) a+b; 在一般使用的时候是没有问题的,但是如果遇到如: c * Add(a,b) * d 的时候就会出现问题,代数式的本意是a+b然后去和c,d相乘,但是因为使用了 ...

  2. extern "c"用法解析

    转自: extern "c"用法解析 - 简书 引言 C++保留了一部分过程式语言的特点,因而它可以定义不属于任何类的全局变量和函数.但是,C++毕竟是一种面向对象的程序设计语言, ...

  3. extern "C" 用法解析

    extern "c"用法解析 作者 作者Jason Ding ,链接http://www.jianshu.com/p/5d2eeeb93590 引言 C++保留了一部分过程式语言的 ...

  4. C/C++之extern "C"的用法解析

    extern "C"的用法解析 http://blog.sina.com.cn/u/494a1ebc010004g5 C++中extern “C”含义深层探索 1.引言 C++语言 ...

  5. ZT extern "C"的用法解析

    extern "C"的用法解析 1.引言 C++语言的创建初衷是“a better C”,但是这并不意味着C++中类似C语言的全局变量和函数所采用的编译和连接方式与C语言完全相同. ...

  6. 安卓JNI精细化讲解,让你彻底了解JNI(二):用法解析

    目录 用法解析 ├── 1.JNI函数 │ ├── 1.1.extern "C" │ ├── 1.2.JNIEXPORT.JNICALL │ ├── 1.3.函数名 │ ├── 1 ...

  7. WordPress的have_posts()和the_post()用法解析

    原文地址:http://www.phpvar.com/archives/2316.html 网上找到一篇介绍WordPress的have_posts()和the_post()用法解析的文章,觉得不错! ...

  8. mysql group by 用法解析(详细)

    在使用mysql时,有时需要查询出某个字段不重复的记录,虽然mysql提供 有distinct这个关键字来过滤掉多余的重复记录只保留一条,但往往只用它来返回不重复记录的条数,而不是用它来返回不重记录的 ...

  9. (转载)mysql group by 用法解析(详细)

    (转载)http://blog.tianya.cn/blogger/post_read.asp?BlogID=4221189&PostID=47881614 mysql distinct 去重 ...

随机推荐

  1. 视图view没有主键,但可以添加唯一索引

    视图没有主键,但可以加上唯一索引 大致可以这样理解:视图是张虚拟的表.视图所对应的数据不进行实际的存储,数据库中只存储视图的定义,对视图的数据进行操作时,系统根据视图的定义去操作与视图相关联的基本表. ...

  2. BZOJ 1974 [Sdoi2010] auction 代码拍卖会(数位dp)

    题目描述 随着iPig在P++语言上的造诣日益提升,他形成了自己一套完整的代码库.猪王国想参加POI的童鞋们都争先恐后问iPig索要代码库.iPig不想把代码库给所有想要的小猪,只想给其中的一部分既关 ...

  3. The Datawarehouse's future is bright

    The Future Data Warehouse Professionals I hava remarked many times that a successful data warehouse ...

  4. Gym - 101845K 排序+概率

    The UNAL programming coaches have lost a bet, they bet the 6 UNAL teams would occupy the first six p ...

  5. 分布式通信框架RMI

    1.RPC概念: Remote procedure call protocal,远程过程调用协议,一般用来实现部署在不同机器上的系统之间的方法调用, 使得程序能够像访问本地系统资源一样,通过网络传输去 ...

  6. Python迭代器生成器,模块和包

      1.迭代器和生成器 2.模块和包 1.迭代器 迭代器对象要求支持迭代器协议的对象,在Python中,支持迭代器协议就是实现对象的__iter__()和__next__()方法.    其中__it ...

  7. python 中文路径问题

    Python直接读取中文路径的文件时失败,可做如下处理: inpath = 'D:/work/yuanxx/在线导航/驾车导航/walk_log/20130619_172355.txt' uipath ...

  8. 以Tkinter模块来学习Python实现GUI(图形用户界面)编程

    tk是什么:它是一个图形库,支持多个操作系统,使用tcl语言开发的.tkinter是Python内置的模块, 与tk类似的第三方图形库(GUI库)还有很多,比如:Qt,GTK,wxWidget,wxP ...

  9. 80C51单片机介绍

    80C51单片机属于MCS-51系列单片机,由Intel公司开发,其结构是8048的延伸,改进了8048的缺点. 增加了如乘(MUL).除(DIV).减(SUBB).比较(CMP).16位数据指针.布 ...

  10. HDU 4352 区间的有多少个数字满足数字的每一位上的数组成的最长递增子序列为K(数位DP+LIS)

    题目:区间的有多少个数字满足数字的每一位上的数组成的最长递增子序列为K 思路:用dp[i][state][j]表示到第i位状态为state,最长上升序列的长度为k的方案数.那么只要模拟nlogn写法的 ...