C语言之预处理

预处理是c语言(也包括OC)的一部分,它们是一些特殊的命令.在编译器对C程序(或者 OC程序)进行编译之前,编译器会对这些预处理命令进行处理,然后将这些处理的结构与源程序一起进行编译.

预处理命令有如下特征.
1)预处理命令必须以#号开头
2)预处理通常位于程序的开头部分

下面一起来看一下几种使用情况:

1: 使用#define,#undef执行宏定义

#define PI 3.14159

-(void)testOne{

    /*#define的作用就是为字符串起一个名字.例如: #define PI 3.14159. 这里的PI就代表3.14159
      注意事项:1)宏定义不是c语言,因此不需要在宏名称与字符串之间使用=进行赋值.
              2)宏定义不是变量,也不是常量,所以不要对宏名称进行赋值.
              3)编译器处理宏定义只是进行"査找,替换"----将所有出现宏名称的地方替换成为该宏中对应的字符串.
              4)通常来说,宏名称会使用所有字母大写形式.
              5)执行宏定义开始后,该宏的作用域为宏定义开始直至源码结束.如果希望提前结束宏定义,可以使用.#undef 宏名称.
    */


    NSLog(@"%f",PI*2); //预处理 6.283180

    //添加
    //#undef PI
    //NSLog("%f",PI*2);//如果再次使用将提示错误,没有声明PI.

}

2: 带参数的宏定义

#define AREA(r)  PI * r * r 
#define AREAONE(r)  (PI * (r) * (r))

-(void)testTwo{

    //定义带参数宏的语法: #define 宏名称(参数列表) 字符串

    NSLog(@"%f",AREA(2)); //预处理 12.566360

    //但是这里存在一个风险,因为编译器对宏只是执行简单的"査找,替换".因此,如果我们调用如下参数:
    NSLog(@"%f",AREA(10+2));// 预处理 53.415900.
    //那么计算公式就成为了PI * 10 +2 * 10 +2 ,所以这里并不是我们原来希望的,先计算10+2.然后再作为参数计算.

    //为了能够正确处理宏定义,所以使用圆括号将参数括起来.如:#define AREAONE(r)  (PI * (r) * (r))
    NSLog(@"%f",AREAONE(10+2));//预处理 452.388960
}

3: 使用#ifdef,#ifndef,#else,#endif执行条件编译

通常来说,源代码中所有的代码行都会参与编译,最后生成执行性代码,但是有些时候,
程序需要根据机器环境进行选择性的编译–对于特定的设备,只编译该设备相关的代码,
这可以借助条件编译来完成.

c语言支持两组条件编译指令,第一条是#ifdef,#ifndef,#else,#endif,语法如下:

1):
#ifdef 宏名称
//任意语句(可以编写多个语句)
#endif
这里表示:如果定义了指定的宏,则执行#ifdef和#endif之间的语句.

也可以如下:

#ifdef 宏名称
//任意语句
#else
//任意语句
#endif
这里表示:如果定义了指定的宏定义,则执行#ifdef和#else之间的语句.否则执行#else和 #endif之间的语句.

2):
对于 #ifdef指令还有一种否定写法:
#ifndef 宏名称
//任意语句
#endif
这里表示:如果没有定义指定的宏,则执行#ifndef和#endif之间的语句.

同样也有:

#ifndef 宏名称
//任意语句
#else
//任意语句
#endif

这里表示:如果没有定义指定的宏定义,则执行#ifndef和#else之间的语句.否则执行#else和 #endif之间的语句.

#define iPhone
-(void)testThree{

           #ifdef iPhone
                  NSLog(@"下面执行iPhone相关代码");
           #else
                  NSLog(@"下面执行iPad相关代码");
           #endif

          //预处理 下面执行iPhone相关代码.

          一个很好的实际应用例子就是NSLog的使用:
          #ifndef __OPTIMIZE__  // __OPTIMIZE__ 是release 默认会加的宏
          #define NSLog(...) NSLog(__VA_ARGS__)
          #else
          #define NSLog(...){}
          #endif

}

4: 使用#if,#elif,#else,#endif执行条件编译

#if,#elif,#else,#endif提供了更通用的条件编译,它可以对指定的表达式进行推断,
根据表达式的值决定是否要编译指定的语句.语法格式如下:

#if 表达式
//任意语句
#elif 表达式
//任意语句
…可以有0个或者多个#elif语句
#else(注:最后的#else语句可以省略)
//任意语句
#endif

这个条件编译指令的用法与前面差不多,只是该编译器指令中使用的条件要么是常量表达式,要么是基于已有的宏的表达式.

#define AGE 30
-(void)testFour{

        #if AGE > 60
            NSLog(@"老年人");
        #elif AGE > 40
            NSLog(@"中年人");
        #elif AGE > 20
            NSLog(@"年轻人");
        #else
            NSLog(@"少年人");
        #endif

      // 预处理[4793:1211851] 年轻人
}

5: #和##运算符

#define STR(s) # s
#define CONCAT(a, b) a##b // ##运算符在宏表达式中连接几个参数
#define VERSION \
3                         // 因为有换行符\ 所以上句等价于 #define VERSION 3

-(void)testFive{

    NSLog(@"%s",STR(3));
    NSLog(@"%d",CONCAT(3, 4));

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值