- Objective-C 基础
- Objective-C - 首页
- Objective-C - 概述
- Objective-C - 环境设置
- Objective-C - 程序结构
- Objective-C - 基本语法
- Objective-C - 数据类型
- Objective-C - 变量
- Objective-C - 常量
- Objective-C - 运算符
- Objective-C - 循环
- Objective-C - 决策
- Objective-C - 函数
- Objective-C - 块
- Objective-C - 数字
- Objective-C - 数组
- Objective-C - 指针
- Objective-C - 字符串
- Objective-C - 结构体
- Objective-C - 预处理器
- Objective-C - Typedef
- Objective-C - 类型转换
- Objective-C - 日志处理
- Objective-C - 错误处理
- 命令行参数
- 高级 Objective-C
- Objective-C - 类与对象
- Objective-C - 继承
- Objective-C - 多态
- Objective-C - 数据封装
- Objective-C - 分类
- Objective-C - 模拟
- Objective-C - 扩展
- Objective-C - 协议
- Objective-C - 动态绑定
- Objective-C - 复合对象
- Obj-C - Foundation 框架
- Objective-C - 快速枚举
- Obj-C - 内存管理
- Objective-C 有用资源
- Objective-C - 快速指南
- Objective-C - 有用资源
- Objective-C - 讨论
Objective-C 预处理器
Objective-C 预处理器不是编译器的一部分,而是在编译过程中一个单独的步骤。简单来说,Objective-C 预处理器只是一个文本替换工具,它指示编译器在实际编译之前进行必要的预处理。我们将把 Objective-C 预处理器称为 OCPP。
所有预处理器命令都以井号 (#) 开头。它必须是第一个非空白字符,并且为了可读性,预处理器指令应该从第一列开始。以下部分列出了所有重要的预处理器指令 -
| 序号 | 指令及描述 |
|---|---|
| 1 | #define 替换预处理器宏 |
| 2 | #include 插入来自另一个文件的特定头文件 |
| 3 | #undef 取消定义预处理器宏 |
| 4 | #ifdef 如果此宏已定义则返回真 |
| 5 | #ifndef 如果此宏未定义则返回真 |
| 6 | #if 测试编译时条件是否为真 |
| 7 | #else #if 的替代方案 |
| 8 | #elif #else 和 #if 合并成一个语句 |
| 9 | #endif 结束预处理器条件 |
| 10 | #error 在 stderr 上打印错误消息 |
| 11 | #pragma 使用标准化方法向编译器发出特殊命令 |
预处理器示例
分析以下示例以了解各种指令。
#define MAX_ARRAY_LENGTH 20
此指令告诉 OCPP 将 MAX_ARRAY_LENGTH 的实例替换为 20。使用 #define 定义常量以提高可读性。
#import <Foundation/Foundation.h> #include "myheader.h"
这些指令告诉 OCPP 从 Foundation 框架获取 foundation.h 并将文本添加到当前源文件中。下一行告诉 OCPP 从本地目录获取 myheader.h 并将内容添加到当前源文件中。
#undef FILE_SIZE #define FILE_SIZE 42
这告诉 OCPP 取消定义现有的 FILE_SIZE 并将其定义为 42。
#ifndef MESSAGE #define MESSAGE "You wish!" #endif
这告诉 OCPP 仅在 MESSAGE 未定义时定义 MESSAGE。
#ifdef DEBUG /* Your debugging statements here */ #endif
这告诉 OCPP 在定义 DEBUG 时处理包含的语句。如果您在编译时向 gcc 编译器传递 -DDEBUG 标志,这将很有用。这将定义 DEBUG,因此您可以在编译过程中动态地打开和关闭调试。
预定义宏
ANSI C 定义了许多宏。虽然每个宏都可用于您的编程,但预定义宏不应直接修改。
| 序号 | 宏及描述 |
|---|---|
| 1 | __DATE__ 当前日期,以“MMM DD YYYY”格式的字符文字表示 |
| 2 | __TIME__ 当前时间,以“HH:MM:SS”格式的字符文字表示 |
| 3 | __FILE__ 包含当前文件名,作为字符串文字。 |
| 4 | __LINE__ 包含当前行号,作为十进制常量。 |
| 5 | __STDC__ 当编译器符合 ANSI 标准时定义为 1。 |
让我们尝试以下示例 -
#import <Foundation/Foundation.h>
int main() {
NSLog(@"File :%s\n", __FILE__ );
NSLog(@"Date :%s\n", __DATE__ );
NSLog(@"Time :%s\n", __TIME__ );
NSLog(@"Line :%d\n", __LINE__ );
NSLog(@"ANSI :%d\n", __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!\n")
字符串化 (#)
字符串化或井号运算符('#'),在宏定义中使用时,会将宏参数转换为字符串常量。此运算符只能在具有指定参数列表的宏中使用。例如 -
#import <Foundation/Foundation.h>
#define message_for(a, b) \
NSLog(@#a " and " #b ": We love you!\n")
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 的连接,这里我们同时使用了字符串化和标记粘贴。
defined() 运算符
预处理器 defined 运算符用于常量表达式中,以确定是否使用 #define 定义了标识符。如果指定了标识符,则值为真(非零)。如果符号未定义,则值为假(零)。defined 运算符的指定方式如下 -
#import <Foundation/Foundation.h>
#if !defined (MESSAGE)
#define MESSAGE "You wish!"
#endif
int main(void) {
NSLog(@"Here is the message: %s\n", 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\n", MAX(10, 20));
return 0;
}
当上述代码编译并执行时,它会产生以下结果 -
2013-09-14 05:52:15.859 demo[20683] Max between 20 and 10 is 20