文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

C语言深入讲解条件编译的用处

2024-04-02 19:55

关注

一、基本概念

下面看一段简单的条件编译的代码:

#include <stdio.h>
 
#define C 1
 
int main()
{
    const char* s;
 
    #if( C == 1 )
        s = "This is first printf...\n";
    #else
        s = "This is second printf...\n";
    #endif
 
    printf("%s", s);
    
    return 0;
}

下面为输出结果:

可以输入gcc -E Test.c -o file.i 命令,看看预编译阶段发生了什么,下面是部分输出结果:

# 2 "Test.c" 2
 
int main()
{
    const char* s;
 
        s = "This is first printf...\n";
 
    printf("%s", s);
 
    return 0;
}

可以看到宏定义和条件编译都没有了,由相应内容取而代之。

二、条件编译的本质

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

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

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

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

可以通过命令行定义宏

下面看一个通过命令行定义宏的代码:

#include <stdio.h>
int main()
{
    const char* s;
 
    #ifdef C
        s = "This is first printf...\n";
    #else
        s = "This is second printf...\n";
    #endif
 
    printf("%s", s);
    
    return 0;
}

终端输入gcc -DC Test.c,输出结果如下:

三、#include 的本质

这就出现一个问题,间接包含同一个头文件是否会产生编译错误?

下面就来通过一段代码深入探究:

global.h:

// global.h
int global = 10;

test.h:

// test.h
 
#include "global.h"
 
const char* NAME = "test.h";
 
char* hello_world()
{
    return "hello world!\n";
}

test.c:

#include <stdio.h>
#include "test.h"
#include "global.h"
int main()
{
    const char* s = hello_world();
    int g = global;
    
    printf("%s\n", NAME);
    printf("%d\n", g);
    
    return 0;
}

编译后编译器报错,global 重定义:

为什么 global 会重定义呢?下面开始单步编译,输入gcc -E test.c -o test.i,输出部分结果如下:

# 2 "test.c" 2
# 1 "test.h" 1
 
 
# 1 "global.h" 1
 
 
int global = 10;
# 4 "test.h" 2
 
const char* NAME = "test.h";
 
char* hello_world()
{
    return "hello world!\n";
}
# 3 "test.c" 2
# 1 "global.h" 1
 
 
int global = 10;
# 4 "test.c" 2
 
int main()
{
    const char* s = hello_world();
    int g = global;
 
    printf("%s\n", NAME);
    printf("%d\n", g);
 
    return 0;
}

这样就很明显了,程序先将 test.h 里面的东西复制进 test.c,由于 test.h 里面有一个 include "global.h",就把int global = 10; 复制过来,然后复制

const char* NAME = "test.h";

char* hello_world()

{undefined

return "hello world!\n";

}

在然后由于test.c 里面又定义一个#include "global.h",又把int global = 10; 复制过来,造成了重复定义。

条件编译可以解决头文件重复包含的编译错误

#ifndef _HEADER_FILE_H_
#define _HEADER_FILE_H_
//source code
#endif

如果没有定义 header_file.h,则定义,且执行里面的代码;否则,如果定义了,里面的代码就不会执行。

所以上述代码中可以这么改:

global.h:

// global.h
#ifndef _GLOBAL_H_
#define _GLOBAL_H_
int global = 10;
 
#endif

test.h:

// test.h
#ifndef _TEST_H_
#define _TEST_H_
#include "global.h"
const char* NAME = "test.h";
char* hello_world()
{
    return "hello world!\n";
}
#endif

这样编译就能通过了

四、条件编译的意义

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

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

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

下面看一段产品线区分及调试代码:

product.h:

#define DEBUG 1
#define HIGH  1

test.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;
}

宏 DEBUG 是指产品是调试版还是发布版,调试版为 1,发布版为 0, 宏 HIGH指的是产品是高端产品还是低端产品,高端产品为 1,低端产品为 0

如果我们想测试调试版的高端产品,令 DEBUG 为 1,HIGH为 0 即可:

同理,我们想测试发布版的低端产品,令 DEBUG 为 0,HIGH为 0 即可:

五、小结

到此这篇关于C语言 深入讲解条件编译的用处的文章就介绍到这了,更多相关C语言 条件编译内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯