zoukankan      html  css  js  c++  java
  • [Objective-C语言教程]预处理器(18)

    Objective-C预处理器不是编译器的一部分,而是编译过程中的一个单独步骤。 简单来说,Objective-C预处理器只是一个文本替换工具,它指示编译器在实际编译之前进行必要的预处理。 我们将Objective-C预处理器称为OCPP

    所有预处理器命令都以井号(#)开头。它必须是第一个字符(前面不能有空格),并且为了便于阅读,预处理器指令应该从第一列开始。 以下部分列出了所有重要的预处理程序指令 -

    编号指令描述
    1 #define 替换预处理器宏
    2 #include 从另一个文件插入特定标头
    3 #undef 未定义的预处理器宏
    4 #ifdef 如果定义了此宏,则返回true
    5 #ifndef 如果未定义此宏,则返回true
    6 #if 测试编译时条件是否为true
    7 #else #if的替代方案
    8 #elif #else#if 中的一个语句
    9 #endif 结束预处理器条件
    10 #error stderr上打印错误消息
    11 #pragma 使用标准化方法向编译器发出特殊命令

    1. 预处理器示例

    分析以下示例以了解各种宏的指令。

    #define MAX_ARRAY_LENGTH 20

    该指令告诉OCPP20替换MAX_ARRAY_LENGTH宏标识。使用#define定义常量来提高可读性。

    1 #import <Foundation/Foundation.h>
    2 #include "myheader.h"

    这些指令告诉OCPP 从Foundation Framework获取foundation.h,并将文本添加到当前源文件中。 下一行告诉OCPP 从本地目录获取myheader.h并将内容添加到当前源文件。

    1 #undef  FILE_SIZE
    2 #define FILE_SIZE 42

    它告诉OCPP 取消定义现有的FILE_SIZE,并将FILE_SIZE定义为42

    1 #ifndef MESSAGE
    2    #define MESSAGE "You wish!"
    3 #endif

    它告诉OCPP仅在尚未定义MESSAGE宏时才定义MESSAGE

    1 #ifdef DEBUG
    2    /* Your debugging statements here */
    3 #endif

    它告诉OCPP如果定义了DEBUG,则执行包含语句的过程。 如果在编译时将- DDEBUG标志传递给gcc编译器,这将非常有用。 它将定义DEBUG,因此可以在编译期间动态打开和关闭调试。

    2. 预定义的宏

    ANSI C定义了许多宏。虽然每个都可用于编程,但不应直接修改预定义的宏。

    编号描述
    1 __DATE__ 当前日期为“MMM DD YYYY”格式的字符文字
    2 __TIME__ 当前时间作为“HH:MM:SS”格式的字符文字
    3 __FILE__ 它包含当前文件名作为字符串文字。
    4 __LINE__ 它包含当前行号作为十进制常量。
    5 __STDC__ 当编译器符合ANSI标准时,定义为1

    试试下面的例子代码 -

     1 #import <Foundation/Foundation.h>
     2 
     3 int main() {
     4    NSLog(@"File :%s
    ", __FILE__ );
     5    NSLog(@"Date :%s
    ", __DATE__ );
     6    NSLog(@"Time :%s
    ", __TIME__ );
     7    NSLog(@"Line :%d
    ", __LINE__ );
     8    NSLog(@"ANSI :%d
    ", __STDC__ );
     9 
    10    return 0;
    11 }

    当编译并执行文件main.m 中的上述代码时,它会产生以下结果 -

    1 2018-11-15 08:44:54.041 main[50640] File :main.m
    2 2018-11-15 08:44:54.042 main[50640] Date :Nov 15 2018
    3 2018-11-15 08:44:54.042 main[50640] Time :08:44:52
    4 2018-11-15 08:44:54.042 main[50640] Line :7
    5 2018-11-15 08:44:54.043 main[50640] ANSI :1

    3. 预处理器运算符

    Objective-C预处理器提供以下运算符来创建宏 -

    3.1. 宏延续()

    宏通常必须包含在一行中。宏延续运算符用于继续对于单行来说太长的宏。 例如 -

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

    3.2. 字符串化(#)

    字符串化或数字符号运算符(#)在宏定义中使用时,将宏参数转换为字符串常量。 此运算符只能在具有指定参数或参数列表的宏中使用。 例如 -

    1 #import <Foundation/Foundation.h>
    2 
    3 #define  message_for(a, b)  
    4    NSLog(@#a " and " #b ": We love you!
    ")
    5 
    6 int main(void) {
    7    message_for(Carole, Debra);
    8    return 0;
    9 }

    执行上面示例代码,得到以下结果:

    1 2018-11-15 08:56:38.088 main[98681] Carole and Debra: We love you!

    3.3. 令牌粘贴(##)

    宏定义中的令牌粘贴运算符(##)组合了两个参数。 它允许将宏定义中的两个单独的标记连接到一个标记中。 例如 -

     1 #import <Foundation/Foundation.h>
     2 
     3 #define tokenpaster(n) NSLog (@"token" #n " = %d", token##n)
     4 
     5 int main(void) {
     6    int token34 = 40;
     7 
     8    tokenpaster(34);
     9    return 0;
    10 }

    执行上面示例代码,得到以下结果:

    2018-11-15 08:58:04.872 main[138839] token34 = 40

    它是如何发生的,因为这个例子导致预处理器的以下实际输出 -

    NSLog (@"token34 = %d", token34);

    此示例显示令牌##ntoken34的串联,这里使用了stringizetoken-pasting

    3.4. defined()运算符

    预处理器定义的运算符用于常量表达式,以确定是否使用#define定义标识符。如果定义了指定的标识符,则该值为true(非零)。 如果未定义符号,则值为false(零)。 定义的运算符指定如下 -

     1 #import <Foundation/Foundation.h>
     2 
     3 #if !defined (MESSAGE)
     4    #define MESSAGE "You wish!"
     5 #endif
     6 
     7 int main(void) {
     8    NSLog(@"Here is the message: %s
    ", MESSAGE);  
     9    return 0;
    10 }

    执行上面示例代码,得到以下结果:

    1 2018-11-15 09:04:30.790 main[31654] Here is the message: You wish!

    4. 参数化宏

    OCPP的一个强大功能是使用参数化宏模拟函数的能力。 例如,可能需要一些代码来对数字进行平方,如下所示 -

    1 int square(int x) {
    2    return x * x;
    3 }

    可以使用宏重写上面的代码,如下所示 -

    #define square(x) ((x) * (x))

    必须先使用#define指令定义带参数的宏,然后才能使用它们。 参数列表括在括号中,并且必须紧跟宏名称。 宏名称和左括号之间不允许有空格。 例如 -

    1 #import <Foundation/Foundation.h>
    2 
    3 #define MAX(x,y) ((x) > (y) ? (x) : (y))
    4 
    5 int main(void) {
    6    NSLog(@"Max between 20 and 10 is %d
    ", MAX(10, 20));  
    7    return 0;
    8 }

    执行上面示例代码,得到以下结果:

    2018-11-15 09:08:15.586 main[64146] Max between 20 and 10 is 20
  • 相关阅读:
    ubuntu14.04 安装 zoom.us
    【JulyEdu-Python基础】第 8 课:Python第三方库
    【JulyEdu-Python基础】第 7 课:Python并发编程以及系统常用模块
    【JulyEdu-Python基础】第 6 课:高级面向对象
    【JulyEdu-Python基础】第 4 课:面向对象基础
    【深度学习笔记】第 7 课:文本和序列的深度模型
    【深度学习笔记】第 6 课:卷积神经网络简介
    【JulyEdu-Python基础】第 3 课:容器以及容器的访问使用
    【JulyEdu-Python基础】第 2 课:关键字和循环控制
    【JulyEdu-Python基础】第 1 课:入门基础
  • 原文地址:https://www.cnblogs.com/strengthen/p/10571484.html
Copyright © 2011-2022 走看看