C语言中条件编译使用分析

--事物的难度远远低于对事物的恐惧!

    最近出差较多,没什么时间记录博客笔记,刚好乘五一假期好好写一点。今天我们来看看C语言条件编译使用分析。

在C语言中,我们很熟悉if...else...这样的条件语句,而我们这章所说的条件编译指令#if...#else...(当然条件编译指令还有#ifndef、#ifdef等等)很类似if...else...条件语句,那么他们二者有什么区别?我们先来分别用预处理器处理下边一段代码。

#define FLAG 1

int main()
{
    char *p1 = "";
    char *p2 = "";

//使用条件编译指令
#if(1 == FLAG)
    p = "FLAG is Defined!";
#else
    p = "FLAG is not Defined";
#endif

//普通if...else...语句
    if(1 == FLAG)

	p2 = "FLAG is Defined!";
    else
	p2 = "FLAG is not Defined";

    return 0;
}

预处理器处理后的结果如下:

#line 1 "main.c"

int main()
{
    char *p1 = "";
    char *p2 = "";

    p1 = "FLAG is Defined!";

#line 16 "main.c"

    if(1 == 1)

	p2 = "FLAG is Defined!";
    else
	p2 = "FLAG is not Defined";

    return 0;
}

 

从预处理后的结果我们知道:被条件编译指令修饰的不符合条件的代码,已经被预处理器去掉了。

 

其实本质来说,条件编译就是预处理指示命令,用于控制是否否编译某段代码。

上段代码中,预处理指示命令就把 p1 = "FLAG is not Defined"这段代码给去掉了,使得编译器不对其进行编译;而普通的if...else...语句,则编译器会对其进行完整的编译。

条件编译的本质:

    -预编译器根据条件编译指令有选择的删除代码

    -编译器不知道代码分支的存在

    -if...else...语句在运行期进行分支判断

    -条件编译指令在预编译期进行分支判断

    -可以通过命令行定义宏

    gcc环境下: gcc -Dmacro=value file.c 或 gcc -Dmacro file.c

    vc环境下:cl -Dmacro=value file.c 或  cl -Dmacro file.c

对于上边的代码,我们屏蔽掉宏定义语句:#define FLAG 1,然后通过命令行定义宏,结果是一样的,大家可以自行实验。

 

通过以上的讲解,相信大家对条件编译有了一个比较清晰的认识了,同理,条件编译指令还有#ifdef、#ifndef等。下边我们来看看#include,带#的我们都可以理解为预处理器指令,都会在预处理阶段进行处理。

    -#include的本质是将已经存在的文件内容嵌入至当前文件中

    -#include的间接包含同样会产生嵌入文件内容的操作

为防止间接包含同一个头文件产生的重复定义的编译错误,我们在写头文件时,通常需要加上条件编译,如下:

#ifndef __FILENAME_H__    //名称一般与头文件名一致且为大写,例如此处的头文件名就为:filename.h
#define __FILENAME_H__

//头文件内容

#endif

在头文件中加上预编译指令,这样就能防止间接包含同一个头文件产生的重定义的编译错误。

条件编译的意义:

    -条件编译使得我们可以按不同的条件编译不同的代码段,因而可以产生不同的目标代码

    -#if...#else...#endif被预编译器处理,而if...else...被编译器处理,必然被编译进目标代码

    -实际工程中条件编译主要用于以下两种情况

        a、不同的产品线公用一份代码

        b、区分编译产品的调试版和发布版

请看下边的代码,实际工程中是怎么通过条件 编译来实现不同产品、调试版、发布版的区分

//product.h头文件
#define DEBUG 1
#define HIGH  1
//main.c文件
#include <stdio.h>
#include "product.h"

#if DEBUG
    #define LOG(s) printf("[%s:%d] %s\n", __FILE__, __LINE__, s)
#else
    #define LOG(s) NULL
#endif

#if HIGH
void f()
{
    printf("This is the high level product!\n");
}
#else
void f()
{
}
#endif

int main()
{
    LOG("Enter main() ...");
    
    f();
    
    printf("1. Query Information.\n");
    printf("2. Record Information.\n");
    printf("3. Delete Information.\n");
    
    #if HIGH
    printf("4. High Level Query.\n");
    printf("5. Mannul Service.\n");
    printf("6. Exit.\n");
    #else
    printf("4. Exit.\n");
    #endif
    
    LOG("Exit main() ...");
    
    return 0;
}

我们来对两个文件进行编译运行,看看结果是什么:

这样,我们就可以通过修改product.h头文件中的宏,就能产生不同版本的可执行文件了。

 

总结:

    -通过编译器命令行能够定义预处理器使用的宏

    -条件编译可以避免重复包含同一个头文件

    -条件编译是在工程开发中可以区别不同产品线的代码

    -条件编译可以定义产品的发布版和调试版

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值