A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© ZXY66452 中级黑马   /  2015-12-7 22:13  /  917 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

Objective-C的预处理器是不是编译器的一部分,但是在编译过程中是一个单独的步骤。在简单的条件,是一个Objective-C预处理器只是一个文本替换工具,它指示编译器做实际的编译之前需要预先处理。我们会参考Objective-C的预处理为OCPP。

井号(#)开头的所有预处理命令。它必须是第一个非空字符,可读性,预处理器指令应在第一列开始。下节列出了所有重要的预处理指令:

指示        描述
#define        替代预处理宏
#include        从另一个文件中插入一个特定的头
#undef        取消定义预处理宏
#ifdef        如果定义了这个宏返回true
#ifndef        返回true,如果该宏没有被定义
#if        编译时间条件下的测试,如果是true
#else        #if 替代方案
#elif        #else 和 #if 在一个语句
#endif        结束预处理条件
#error        stderr上打印错误消息
#pragma        编译器使用一个标准化的方法发出特殊命令 预处理器实例
分析下面的例子来了解各种指令。

#define MAX_ARRAY_LENGTH 20
该指令告诉OCPP,以取代实例MAX_ARRAY_LENGTH为20。使用#定义常数,以增加可读性。

#import <Foundation/Foundation.h>
#include "myheader.h"
这些的指令告诉OCPP得到 foundation.h 基础框架和文本添加到当前源文件。下一行告诉 OCPP 从本地目录得到 myheader.h 的内容添加到当前源文件。

#undef  FILE_SIZE
#define FILE_SIZE 42
告诉OCPP 取消对现有 FILE_SIZE 的定义,并把它定义为42 。

#ifndef MESSAGE
   #define MESSAGE "You wish!"
#endif
这告诉OCPP定义消息,如果消息没有被定义。

#ifdef DEBUG
   /* Your debugging statements here */
#endif
这告诉OCPP如果DEBUG被定义语句随附过程。如果传递 DDEBUG标志,gcc编译器在编译时,这是非常有用的。这将定义DEBUG,所以可以在编译过程中打开调试和关闭。

预定义宏
ANSI C定义了一些宏。虽然每一个都是供编程使用,预定义宏不应该被直接修改。

Macro        描述
__DATE__        The current date as a character literal in "MMM DD YYYY" format
__TIME__        The current time as a character literal in "HH:MM:SS" format
__FILE__        This contains the current filename as a string literal.
__LINE__        This contains the current line number as a decimal constant.
__STDC__        Defined as 1 when the compiler complies with the ANSI standard.
让我们试试下面的例子:

#import <Foundation/Foundation.h>

int main()
{
   NSLog(@"File :%s
", __FILE__ );
   NSLog(@"Date :%s
", __DATE__ );
   NSLog(@"Time :%s
", __TIME__ );
   NSLog(@"Line :%d
", __LINE__ );
   NSLog(@"ANSI :%d
", __STDC__ );

   return 0;
}
文件 main.m 上面的代码在编译和执行时,它会产生以下结果:

2013-09-14 04:46:14.859 demo[20683] File :main.m
2013-09-14 04:46:14.859 demo[20683] Date :Sep 14 2013
2013-09-14 04:46:14.859 demo[20683] Time :04:46:14
2013-09-14 04:46:14.859 demo[20683] Line :8
2013-09-14 04:46:14.859 demo[20683] ANSI :1
预处理运算符
Objective-C 预处理器提供了运算符,以帮助创建宏:

宏延续()

宏通常必须包含在一个单一的行。宏延续运算符用于继续宏的一行。例如:

#define  message_for(a, b)  
    NSLog(@#a " and " #b ": We love you!
")
Stringize (#)

stringize或数字符号运算符('#'),在宏定义内使用时,一个宏参数转换成一个字符串常量。此操作只可用于在宏具有指定参数或参数列表。例如:

#import <Foundation/Foundation.h>

#define  message_for(a, b)  
    NSLog(@#a " and " #b ": We love you!
")

int main(void)
{
   message_for(Carole, Debra);
   return 0;
}
让我们编译和运行上面的程序,这将产生以下结果:

2013-09-14 05:46:14.859 demo[20683] Carole and Debra: We love you!
标记粘贴 (##)

标记粘贴运算符(##)在宏定义内结合两个参数。在宏定义,允许两个单独的令牌必须合并成一个单一的令牌。例如:

#import <Foundation/Foundation.h>

#define tokenpaster(n) NSLog (@"token" #n " = %d", token##n)

int main(void)
{
   int token34 = 40;

   tokenpaster(34);
   return 0;
}
让我们编译和运行上面的程序,这将产生以下结果:

2013-09-14 05:48:14.859 demo[20683] token34 = 40
它是如何发生的,因为这个例子中的结果在下面从预处理的实际输出:

NSLog (@"token34 = %d", token34);
这个例子显示了串联令牌#n为进token34,这里我们使用stringize和标记粘贴。

defined() 运算符

预处理器定义的常量表达式运算符用于确定是否使用#define定义一个标识符。如果指定的标识符被定义,该值是真(非零)。如果符号没有定义,这个值是false(零)。定义的运算符规定如下:

#import <Foundation/Foundation.h>

#if !defined (MESSAGE)
   #define MESSAGE "You wish!"
#endif

int main(void)
{
   NSLog(@"Here is the message: %s
", MESSAGE);  
   return 0;
}
让我们编译和运行上面的程序,这将产生以下结果:

2013-09-14 05:48:19.859 demo[20683] Here is the message: You wish!
参数化宏
OCPP的一个强大功能是能够模拟函数,使用参数化宏。例如,我们可能有一些代码方数字如下:

int square(int x) {
   return x * x;
}
我们可以重写上面的代码中使用宏如下:

#define square(x) ((x) * (x))
带参数的宏,必须使用才可以使用#define指令定义。参数列表括在括号中,必须紧跟在宏名。宏名和左括号之间不允许有空格。例如:





#import <Foundation/Foundation.h>

#define MAX(x,y) ((x) > (y) ? (x) : (y))

int main(void)
{
   NSLog(@"Max between 20 and 10 is %d
", MAX(10, 20));  
   return 0;
}
让我们编译和运行上面的程序,这将产生以下结果:

2013-09-14 05:52:15.859 demo[20683] Max between 20 and 10 is 20

6 个回复

倒序浏览
收藏一下以后看~
回复 使用道具 举报
不错,整理的很详细。
回复 使用道具 举报
不错,整理的好
回复 使用道具 举报
恢复的恶魔 来自手机 中级黑马 2015-12-8 00:06:57
报纸
收藏一下,准备以后看。感谢分享
回复 使用道具 举报
学习了 今天刚学了main函数
回复 使用道具 举报
不错,整理的很详细。,厉害
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马