【#ifndef, #define, 和 #endif】

2024-01-03 15:25:25

前言

学习AFNetWoring源码的时候,在AFN的h借接口文件又看到了这几个宏定义,学习记录一下。
请添加图片描述

作用

#ifndef, #define, 和 #endif是C/CPP的预处理指令,常常用来条件编译和防止头文件重复包含。

简介

#ifndef 它是if not define的简写,是宏定义的一种,确切的说是预处理功能(宏定义、文件包含、条件编译)三种中的一种——条件编译。

使用#ifndef可以避免以下错误:如果在.h文件中定义了全局变量,一个C文件包含了.h文件多次,如果不加#ifndef宏定义,会出现变量重复定义的错误;如果加了#ifndef则不会出现这种错误。

  • #ifndef:如果未定义)用于判断指定的标识符是否已经被定义。如果该标识符未定义,则执行下面的代码块,否则跳过。
  • #define: 用于定义指定的标识符,通常用于定义宏。在条件编译中,一般用来定义一个标识符,以便在后面的代码中进行条件判断。
  • #endif :用于结束条件编译的代码块。

通常语法如下

#ifndef IDENTIFIER
#define IDENTIFIER

// 在这里放置需要执行的代码

#endif

其中,IDENTIFIER 是你自己定义的标识符名称,可以是任意合法的标识符。

这种结构的作用是为了防止头文件的重复包含。通过定义一个唯一的标识符,当该头文件第一次被包含时,IDENTIFIER 未定义,预处理器会执行 #define 下的代码块,标识该头文件已经被包含。当同一个头文件再次被包含时,由于 IDENTIFIER 已经被定义,预处理器会跳过 #define 下的代码块,从而避免了重复包含。

这种写法在头文件中很常见,以确保头文件的内容只会被编译一次,防止重复定义和冲突。

例子

以开头的代码为例

#ifndef _AFNETWORKING_
    #define _AFNETWORKING_

    #import "AFURLRequestSerialization.h"
    #import "AFURLResponseSerialization.h"
    #import "AFSecurityPolicy.h"

#if !TARGET_OS_WATCH
    #import "AFNetworkReachabilityManager.h"
#endif

    #import "AFURLSessionManager.h"
    #import "AFHTTPSessionManager.h"

#endif /* _AFNETWORKING_ */

这段代码的是OC的预编译指令,用于编译时对于代码进行条件判断和控制

  • #ifndef:预处理指令,用于判断一个标识符是否已经被定义过。如果标识符没有被定义过,则编译下面的代码块,否则忽略下面的代码块。
  • #define:预处理指令,用于定义一个标识符。在这个例子中,AFNETWORKING 就是被定义的标识符。
  • #endif:预处理指令,用于结束一个条件编译块。
    这段代码的作用是:当 AFNETWORKING 这个标识符没有被定义时,编译下面的代码块,并且将 AFNETWORKING 定义为已经被定义。这样可以避免头文件的重复引用和编译错误。

分解

#ifndef _AFNETWORKING_
#define _AFNETWORKING_

这里定义了一个标识符 _AFNETWORKING_,如果该标识符未定义(即未被之前的代码定义过),则执行下面的代码块,否则跳过。

#import "AFURLRequestSerialization.h"
#import "AFURLResponseSerialization.h"
#import "AFSecurityPolicy.h"

这里通过#import指令引入了一些其他的头文件,这些头文件可能包含了一些类或函数的声明。

#if !TARGET_OS_WATCH
#import "AFNetworkReachabilityManager.h"
#endif

这段代码使用了条件编译,判断是否为目标平台是不是watchOS,如果不是watchOS,则引入 "AFNetworkReachabilityManager.h" 头文件。

#import "AFURLSessionManager.h"
#import "AFHTTPSessionManager.h"

这里又引入了两个头文件 "AFURLSessionManager.h""AFHTTPSessionManager.h"

最后,代码块的结束部分是 #endif,用于结束条件编译的代码块。

整个结构的目的是为了确保头文件的内容只会被编译一次,避免了重复定义和冲突。

文章来源:https://blog.csdn.net/weixin_61639290/article/details/130680844
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。