Objective c 解释C预处理器代码

Objective c 解释C预处理器代码,objective-c,c-preprocessor,stringification,Objective C,C Preprocessor,Stringification,给定\define LOG_OBJECT(OBJECT)(NSLog(@“#OBJECT@”%@%@:%d),[OBJECT description],[NSString stringWithUTF8String:u FILE_uuuuuuuuuuuu]lastPathComponent],[uuuuuu LINE_uuuuu]);语句LOG_OBJECT(self将生成: 2014-07-18 17:43:30.041 FrogCamera[12484:2144843]self ViewCon

给定
\define LOG_OBJECT(OBJECT)(NSLog(@“#OBJECT@”%@%@:%d),[OBJECT description],[NSString stringWithUTF8String:u FILE_uuuuuuuuuuuu]lastPathComponent],[uuuuuu LINE_uuuuu]);
语句
LOG_OBJECT(self将生成:

2014-07-18 17:43:30.041 FrogCamera[12484:2144843]self ViewController.m:20

我希望了解预处理器代码是如何工作的。我如何才能看到预处理器生成的语句

具体而言:

  • 为什么整个#define语句被包装在
    ()
  • #object
    是否是提供的值的文本替换
  • 为什么在
    #对象之前要求
    @“
  • 也就是说,
    @“#object@%@%@:%d”
    如何转换为
    @“self%@%@:%d”
  • 下面是一个用法示例:

    @interface ViewController ()
    #define LOG_OBJECT(object)  (NSLog(@"" #object @" %@ %@:%d", [object description], [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__));
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        LOG_OBJECT(self);
        // = 2014-07-18 17:48:19.439 FrogCamera[12597:2151087] self <ViewController: 0x79755000> ViewController.m:20
        (NSLog(@"self %@ %@:%d", [self description], [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__));
        // = 2014-07-18 17:48:19.440 FrogCamera[12597:2151087] self <ViewController: 0x79755000> ViewController.m:21
    }
    @end
    
    @界面视图控制器()
    #定义日志对象(对象)(NSLog(@“”#对象@“%@%@:%d)”,[对象描述],[NSString STRING WITHUTF8STRING:\uuuu文件\uuuuuuuuu]lastPathComponent],\uuuuuuu行];
    @结束
    @实现视图控制器
    -(无效)viewDidLoad{
    [超级视图下载];
    日志对象(自身);
    //=2014-07-18 17:48:19.439 FrogCamera[12597:2151087]self-ViewController.m:20
    (NSLog(@“self%@%@:%d”,[self description],[NSString stringWithUTF8String:\uuuu文件\uuuuuuuuu]最后路径组件],\uuuuu行]);
    //=2014-07-18 17:48:19.440 FrogCamera[12597:2151087]self-ViewController.m:21
    }
    @结束
    

    有关日志对象语句的来源,请参阅。

    如果要查看预处理器宏的扩展内容,请在文件打开时单击产品菜单,然后单击执行操作->预处理“ViewController.m“。这将让您看到替换了宏的扩展源的外观。有关如何使用宏的更多详细信息,请参见

    如果要查看预处理器宏的扩展内容,请在文件打开时单击产品菜单,然后执行操作->预处理“ViewController.m”。这将让您看到替换了宏的扩展源的外观。有关如何使用宏的更多详细信息,请参见

    这相当简单:

  • 每当展开的宏可能执行意外操作时,都会使用宏中的括号。一个典型的例子是:
    #define SUM(A, B) A + B
    SUM(1, 1) * 3 //the expected result is 6, the real result is 1 + 1 * 3 = 4 
    在每个宏周围添加括号是防止此类错误的良好编程约定
  • #param
    是一个字符串化操作符。它将参数用引号括起来-例如,参数
    被转换为
    “值”
  • 字符串化操作符创建一个C字符串,它是一个字符数组(
    char*
    )。作者想要一个
    NSString*
    ,这就是为什么他要在开头添加一个
    @
    。请注意,
    @“aaa”“bbb”
    相当于
    @“aaabb”
    (此功能使我们能够在多行上拆分字符串)。然而,这不是很优雅。使用
    %s
    会使它更简单一些
  • 它仅转换为
    @““self”@“%@%@:%d”
    。编译器将连续字符串视为一个字符串
  • 这相当简单:

  • 每当展开的宏可能执行意外操作时,都会使用宏中的括号。一个典型的例子是:
    #define SUM(A, B) A + B
    SUM(1, 1) * 3 //the expected result is 6, the real result is 1 + 1 * 3 = 4 
    在每个宏周围添加括号是防止此类错误的良好编程约定
  • #param
    是一个字符串化操作符。它将参数用引号括起来-例如,参数
    被转换为
    “值”
  • 字符串化操作符创建一个C字符串,它是一个字符数组(
    char*
    )。作者想要一个
    NSString*
    ,这就是为什么他要在开头添加一个
    @
    。请注意,
    @“aaa”“bbb”
    相当于
    @“aaabb”
    (此功能使我们能够在多行上拆分字符串)。然而,这不是很优雅。使用
    %s
    会使它更简单一些
  • 它仅转换为
    @““self”@“%@%@:%d”
    。编译器将连续字符串视为一个字符串
  • 基于C,2
    #
    是一个运算符。4.相邻的字符串文字被连接起来。基于C,2
    #
    是一个运算符。4.相邻的字符串文字是串联的。