iOS开发系列--C语言之预处理

简介:

概述

大家都知道一个C程序的运行包括编译和链接两个阶段,其实在编译之前预处理器首先要进行预处理操作,将处理完产生的一个新的源文件进行编译。由于预处理指令是在编译之前就进行了,因此很多时候它要比在程序运行时进行操作效率高。在C语言中包括三类预处理指令,今天将一一介绍:

  1. 宏定义
  2. 条件编译
  3. 文件包含

宏定义

对于程序中经常用到的一些常量或者简短的函数我们通常使用宏定义来处理,这样做的好处是对于程序中所有的配置我们可以统一在宏定义中进行管理,而且由于宏定义是在程序编译之前进行替换相比定义成全局变量或函数效率更高。

//
//  main.c
//  Pretreatment
//
//  Created by Kenshin Cui on 14-6-28.
//  Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//

#include <stdio.h>
#define PI 3.14 //宏定义一般大写
#define R 10
#define S 2*PI*R //在另一个宏里面引用了上面的宏

int main(int argc, const char * argv[]) {
    float r=10.5;
    double area=PI*r*r;
    printf("area=%.2f\n",area);
    
    double a=S;
    printf("a=%.2f\n",a);
    printf("PI=3.14\n");//注意输出结果不是3.14=3.14而是PI=3.14,字符串中的PI并不会被替换
#undef PI //强制终止宏定义,否则它的范围一直到文件结束
    int PI=3.1415926;
    double area2=PI*r*r;
    printf("area2=%.2f\n",area2);
    
    
    return 0;
}

宏定义实际的操作就是在预处理时进行对应替换,这个阶段不管语法是否正确,而且对于字符串中出现的宏名不会进行替换。宏定义的功能事实上是非常强大的,除了简单的常量替换还可以传入参数:

//
//  1.2.c
//  Pretreatment
//
//  Created by Kenshin Cui on 14-7-17.
//  Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//

#include <stdio.h>
#define SUM(a,b) a+b
#define SUB(a,b) (a-b)
#define MUL (a,b) (a*b) //这么定义是错误的,预处理器会认为宏名为”MUL“,替换内容为”(a,b) (a*b)“


int main(int argc, const char * argv[]) {
    
    int a=2,b=3,c,d;
    c=SUM(a, b);
    printf("c=%d\n",c); //结果:c=5
    d=SUM(a, b)*2;
    printf("d=%d\n"); //结果:8,为什么不是10呢?因为替换后:d=a+b*2也就是2+3*2=8
    
    int e=SUB(b, a)*2;
    printf("(b-a)*2=%d\n",e); //结果:2,如果SUB定义时不加括号这里应该是-1
    
    return 0;
}
上面我们可以看出带参数的宏功能很强大,有点类似于函数,同函数不同的是它只是简单的替换,不涉及存储空间分配,参数、返回值等问题,但是由于它在预处理阶段展开,所以一般效率较高。使用带参数的宏需要注意的就是结果最好用括号括起来否则很容易出现问题(在上面的SUM例子中我们应该已经看到了);还有一点就是带参数的宏定义时名称和参数之间不要有空格。

条件编译

条件编译其实就是在编译之前预处理器根据预处理指令判断对应的条件,如果条件满足就将对应的代码编译进去,否则代码就根本不进入编译环节(相当于根本就没有这段代码)。

//
//  main.c
//  Pretreatment
//
//  Created by Kenshin Cui on 14-06-28.
//  Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//

#include <stdio.h>
#define COUNT 1

int main(int argc, const char * argv[]) {
    
//判断是否定义了 COUNT 宏
#if defined(COUNT) //等价于:#ifdef COUNT,相反如果判断没有定义过则可以通过#if !defined(COUNT)或者#ifndef COUNT
    printf("COUNT defined\n");
#endif
    
//判断宏定义COUNT是否等于1
#if COUNT==1
    showMessage("hello,world!\n");
#else
    say();
#endif
    
    return 0;
}

文件包含

文件包含指令#include在前面也多次使用过,这里再次强调一下。首先使用#include“xxx”包含和使用#include <xxx>包含的不同之处就是使用<>包含时,预处理器会搜索C函数库头文件路径下的文件,而使用“”包含时首先搜索程序所在目录,其次搜索系统Path定义目录,如果还是找不到才会搜索C函数库头文件所在目录。

另外在使用#include的时候我们需要注意包含文件的时候是不能递归包含的,例如a.h文件包含b.h,而b.h就不能再包含a.h了;还有就是重复包含虽然是允许的(这里指的是重复包含头文件)但是这会降低编译性能,不妨看一下下面的例子:

includeRepeat

上面有三段代码,在main.c和person.h中都包含了message.h而main.c自身又包含了person.h,这样程序在预处理阶段会对包含内容进行替换,替换后mian.c中包含了两个#include “message.h”虽然没有报错,但这会影响编译的性能,正确的做法应该是这样的:

correctInclude

其实就是用宏定义判断一个宏是否定义了,如果没有定义则会定义这个宏,这样以来如果已经包含过则这个宏定义肯定已经定义过了,即使再包含也不会重新定义了,下面的代码也就不会包含进去。

目录
相关文章
|
1月前
|
编译器 C语言
C语言--预处理详解(1)
【10月更文挑战第3天】
|
1月前
|
Java Android开发 Swift
安卓与iOS开发对比:平台选择对项目成功的影响
【10月更文挑战第4天】在移动应用开发的世界中,选择合适的平台是至关重要的。本文将深入探讨安卓和iOS两大主流平台的开发环境、用户基础、市场份额和开发成本等方面的差异,并分析这些差异如何影响项目的最终成果。通过比较这两个平台的优势与挑战,开发者可以更好地决定哪个平台更适合他们的项目需求。
109 1
|
1月前
|
编译器 Linux C语言
C语言--预处理详解(3)
【10月更文挑战第3天】
|
4天前
|
安全 数据处理 Swift
深入探索iOS开发中的Swift语言特性
本文旨在为开发者提供对Swift语言在iOS平台开发的深度理解,涵盖从基础语法到高级特性的全面分析。通过具体案例和代码示例,揭示Swift如何简化编程过程、提高代码效率,并促进iOS应用的创新。文章不仅适合初学者作为入门指南,也适合有经验的开发者深化对Swift语言的认识。
19 9
|
3天前
|
Android开发 Swift iOS开发
探索安卓与iOS开发的差异和挑战
【10月更文挑战第37天】在移动应用开发的广阔舞台上,安卓和iOS这两大操作系统扮演着主角。它们各自拥有独特的特性、优势以及面临的开发挑战。本文将深入探讨这两个平台在开发过程中的主要差异,从编程语言到用户界面设计,再到市场分布的不同影响,旨在为开发者提供一个全面的视角,帮助他们更好地理解并应对在不同平台上进行应用开发时可能遇到的难题和机遇。
|
2天前
|
iOS开发 开发者
探索iOS开发中的SwiftUI框架
【10月更文挑战第39天】在苹果的生态系统中,SwiftUI框架以其声明式语法和易用性成为开发者的新宠。本文将深入SwiftUI的核心概念,通过实际案例展示如何利用这一框架快速构建用户界面,并探讨其对iOS应用开发流程的影响。
|
5天前
|
JSON 前端开发 API
探索iOS开发之旅:打造你的第一个天气应用
【10月更文挑战第36天】在这篇文章中,我们将踏上一段激动人心的旅程,一起构建属于我们自己的iOS天气应用。通过这个实战项目,你将学习到如何从零开始搭建一个iOS应用,掌握基本的用户界面设计、网络请求处理以及数据解析等核心技能。无论你是编程新手还是希望扩展你的iOS开发技能,这个项目都将为你提供宝贵的实践经验。准备好了吗?让我们开始吧!
|
9天前
|
设计模式 前端开发 Swift
探索iOS开发:从初级到高级的旅程
【10月更文挑战第31天】在这篇文章中,我们将一起踏上iOS开发的旅程。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的信息和技巧。我们将从基础开始,逐步深入到更高级的技术和概念。让我们一起探索iOS开发的世界吧!
|
12天前
|
设计模式 前端开发 Swift
探索iOS开发:从初级到高级的旅程
【10月更文挑战第28天】在这篇技术性文章中,我们将一起踏上一段探索iOS开发的旅程。无论你是刚入门的新手,还是希望提升技能的开发者,这篇文章都将为你提供宝贵的指导和灵感。我们将从基础概念开始,逐步深入到高级主题,如设计模式、性能优化等。通过阅读这篇文章,你将获得一个清晰的学习路径,帮助你在iOS开发领域不断成长。
38 2
|
15天前
|
C语言
【c语言】你绝对没见过的预处理技巧
本文介绍了C语言中预处理(预编译)的相关知识和指令,包括预定义符号、`#define`定义常量和宏、宏与函数的对比、`#`和`##`操作符、`#undef`撤销宏定义、条件编译以及头文件的包含方式。通过具体示例详细解释了各指令的使用方法和注意事项,帮助读者更好地理解和应用预处理技术。
19 2