原文地址:

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. winform 动态添加控件及事件

    for (int i = 0; i < 4; i++) { Button btn = new Button(); //btn.Name = dt.Rows[i]["ANDON_CONT ...

  2. 拓扑排序+数学+DP【洛谷P1685】 游览

    P1685 游览 题目描述 顺利通过了黄药师的考验,下面就可以尽情游览桃花岛了! 你要从桃花岛的西头开始一直玩到东头,然后在东头的码头离开.可是当你游玩了一次后,发现桃花岛的景色实在是非常的美丽!!! ...

  3. luogu2155 [SDOI2008]沙拉公主的困惑

    link 求出1到N的阶乘中与M的阶乘互质的数的个数,对R取模,多组询问,R<=10^9+10,T<=10000,1 < = N , M < = 10000000 1到\(M! ...

  4. jdk 1.6.0_41 下载

    Java SE Development Kit 6u41 Product / File Description File Size Download password Linux x86 65.43 ...

  5. 将已有项目同步到远程git仓库(github,gitee)及giteee的visual studio插件使用一二

    一.将已有项目同步到远程仓库的最简便方法是用git bash: 将已有项目同步到远程仓库有两种方法:1用git bash:2.用vs插件,两者的思路和步骤基本一致的. 实验发现,如果用vs插件,bas ...

  6. linux中sigsuspend和pause的区别

    pause和sigsuspend都是用于等待信号的发生 简单的说,sigsuspend = unblock + pause sigsuspend 函数是用于需要先接触 某个信号的阻塞状态 然后等待该信 ...

  7. [USACO5.4]奶牛的电信Telecowmunication 最小割

    题目描述 农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流.这些机器用如下的方式发送电邮:如果存在一个由c台电脑组成的序列a1,a2,...,a(c),且a1与a2相 ...

  8. kuangbin专题十六 KMP&&扩展KMP HDU2594 Simpsons’ Hidden Talents

    Homer: Marge, I just figured out a way to discover some of the talents we weren’t aware we had. Marg ...

  9. python中各种转义字符

    转义字符 描述 \(在行尾时) 续行符 \\ 反斜杠符号 \’ 单引号 \” 双引号 \a 响铃 \b 退格(Backspace) \e 转义 \000 空 \n 换行 \v 纵向制表符 \t 横向制 ...

  10. mariaDB 远程连接不上

    GRANT ALL PRIVILEGES ON *.* TO 'user'@'%' IDENTIFIED BY 'password' WITH GRANT OPTION; // %:表示从任何主机连接 ...