0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

C语言程序时经常使用库函数之前的预处理是什么?

GReq_mcu168 ? 来源:CSDN ? 作者:木槿花better ? 2021-04-16 09:47 ? 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

我们在写C语言程序时经常使用库函数之前,应该用#include引入对应的头文件。这种以#号开头的命令称为预处理命令。但是你对C语言的预处理了解多少呢?快来跟着斌哥一起学习一下C语言中的预处理吧!推荐关注下方公众号学习更多电子技术知识!

一、预处理是什么?预处理指令是以#号开头的代码行。#号必须是该行除了任何空白字符外的第一个字符。#后是指令关键字,在关键字和#号之间允许存在任意个数的空白字符。整行语句构成了一条预处理指令,该指令将在编译器进行编译之前对源代码做某些转换。下面是部分预处理指令:

a0257bc0-9e2c-11eb-8b86-12bb97331649.png

还有下列几种预处理宏(是双下划线)

__LINE__ 表示正在编译的文件的行号__FILE__表示正在编译的文件的名字__DATE__表示编译时刻的日期字符串__TIME__ 表示编译时刻的时间字符串__STDC__ 判断该文件是不是定义成标准 C 程序

二、预处理有什么用?在集成开发环境中,编译,链接是同时完成的。其实,C语言编译器在对源代码编译之前,还需要进一步的处理:预编译。

所以,完整的步骤是:预编译 -》 编译 -》 链接预编译的主要作用如下:

1.将源文件中以”include”格式包含的文件复制到编译的源文件中。2.用实际值替换用“#define”定义的字符串。3.根据“#if”后面的条件决定需要编译的代码。

预处理是C语言的一个重要功能,由预处理程序完成。当对一个源文件进行编译时,系统将自动调用预处理程序对源程序中的预处理部分作处理,处理完毕自动进入对源程序的编译。

预处理的行为是由指令控制的。这些指令是由#字符开头的一些命令。

#define指令定义了一个宏---用来代表其他东西的一个命令,通常是某一个类型的常量。预处理会通过将宏的名字和它的定义存储在一起来响应#define指令。当这个宏在后面的程序中使用到时,预处理器”扩展”了宏,将宏替换为它所定义的值。例如:下面这行命令:

1#define PI 3.141592654

#include指令告诉预处理器打开一个特定的文件,将它的内容作为正在编译的文件的一部分“包含”进来。例如:下面这行命令:

1#include《stdio.h》

指示预处理器打开一个名字为stdio.h的文件,并将它的内容加到当前的程序中。

预处理器的输入是一个C语言程序,程序可能包含指令。预处理器会执行这些指令,并在处理过程中删除这些指令。预处理器的输出是另外一个程序:原程序的一个编辑后的版本,不再包含指令。预处理器的输出被直接交给编译器,编译器检查程序是否有错误,并经程序翻译为目标代码。

三、3种预处理详解1、宏定义指令

宏定义了一个代表特定内容的标识符。预处理过程会把源代码中出现的宏标识符替换成宏定义时的值。宏最常见的用法是定义代表某个值的全局符号。宏的第二种用 法是定义带参数的宏(宏函数),这样的宏可以象函数一样被调用,但它是在调用语句处展开宏,并用调用时的实际参数来代替定义中的形式参数。

1.1 #define指令

1.1.1 #define预处理指令用来定义宏。该指令最简单的格式是:声明一个标识符,给出这个标识符代表的代码(比如像圆周率这样的数)。在后面的源代码中,我们就可以使用定义的宏取代要使用的代码,代码举例:

#define PI 3.141592654

1.1.2 使用宏的好处有两点

一是使用方便。如下:

#define PI 3.1415926

PI显然比3.1415926写着方便。

二是定义的宏有了意义,可读性强。如例1,MAX_NUM,望文生意便知是最大数量的意思,比单纯使用10这个数字可读性要强的多。

三是容易修改。如例1,如果在程序中有几十次会使用到MAX_NUM,修改只需要在宏定义里面修改一次就可以,否则你会修改到崩溃。

2、条件编译指令

程序员可以通过定义不同的宏来决定编译程序对哪些代码进行处理。条件编译指令将决定哪些代码被编译,而哪些是不被编译的。可以根据表达式的值或者某个特定的宏是否被定义来确定编译条件。

2.1 #if/#endif/#else/#elif指令

#if指令检测跟在制造另关键字后的常量表达式。如果表达式为真,则编译后面的代码,直到出现#else、#elif或#endif为止;否则就不编译。

#endif用于终止#if预处理指令。#else指令用于某个#if指令之后,当前面的#if指令的条件不为真时,就编译#else后面的代码。

代码举例

#define DEBUG //此时#ifdef DEBUG为真//#define DEBUG 0 //此时为假int main(){ #ifdef DEBUG printf(“Debugging

”); #else printf(“Not debugging

”); #endif printf(“Running

”); return 0;}

这样我们就可以实现debug功能,每次要输出调试信息前,只需要#ifdef DEBUG判断一次。不需要了就在文件开始定义#define DEBUG 0

#elif预处理指令综合了#else和#if指令的作用。

3、头文件包含指令

采用头文件的目的主要是为了使某些定义可以供多个不同的C源程序使用。因为在需要用到这些定义的C源程序中,只需加上一条#include语句即可,而不必再在此文件中将这些定义重复一遍。预编译程序将把头文件中的定义统统都加入到它所产生的输出文件中,以供编译程序对之进行处理。

#include预处理指令的作用是在指令处展开被包含的文件。包含可以是多重的,也就是说一个被包含的文件中还可以包含其他文件。标准C编译器至少支持八重嵌套包含。预处理过程不检查在转换单元中是否已经包含了某个文件并阻止对它的多次包含,这个的处理办法上面已经给出。

在程序中包含头文件有两种格式:

#include 《my.h》 #include “my.h”

第一种方法是用尖括号把头文件括起来。这种格式告诉预处理程序在编译器自带的或外部库的头文件中搜索被包含的头文件。第二种方法是用双引号把头文件括起 来。这种格式告诉预处理程序在当前被编译的应用程序的源代码文件中搜索被包含的头文件,如果找不到,再搜索编译器自带的头文件。

采用两种不同包含格式的理由在于,编译器是安装在公共子目录下的,而被编译的应用程序是在它们自己的私有子目录下的。一个应用程序既包含编译器提供的公共 头文件,也包含自定义的私有头文件。采用两种不同的包含格式使得编译器能够在很多头文件中区别出一组公共的头文件。

四、小结预编译程序所完成的基本上是对源程序的“替代”工作。经过此种替代,生成一个没有宏定义、没有条件编译指令、没有特殊符号的输出文件。这个文件的含义同没有经过预处理的源文件是相同的,但内容有所不同。下一步,此输出文件将作为编译程序的输出而被翻译成为机器指令。

原文标题:C语言预处理命令你知道多少?

文章出处:【微信公众号:玩转单片机】欢迎添加关注!文章转载请注明出处。

责任编辑:haq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • C语言
    +关注

    关注

    180

    文章

    7633

    浏览量

    142174
  • 预处理
    +关注

    关注

    0

    文章

    33

    浏览量

    10674

原文标题:C语言预处理命令你知道多少?

文章出处:【微信号:mcu168,微信公众号:硬件攻城狮】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    详解hal_entry入口函数

    当使用RTOS时,程序从main函数开始进行线程调度;当没有使用RTOS时,C语言程序的入口函数
    的头像 发表于 07-25 15:34 ?1113次阅读

    C语言中的内联函数与宏

    C编程中,内联函数和宏都用于避免函数调用的开销并编写可复用的逻辑部分,但它们在工作方式和安全性方面存在显著差异。
    的头像 发表于 07-25 15:10 ?1301次阅读
    <b class='flag-5'>C</b><b class='flag-5'>语言</b>中的内联<b class='flag-5'>函数</b>与宏

    深入理解C语言函数—编程中的“积木块”艺术

    在编程的世界里,函数就像建筑中的“积木块”——它们是构建复杂程序的基石。通过灵活组合这些模块,开发者能打造出功能强大且结构清晰的代码。函数之所以成为C
    的头像 发表于 06-30 17:26 ?976次阅读
    深入理解<b class='flag-5'>C</b><b class='flag-5'>语言</b>:<b class='flag-5'>函数</b>—编程中的“积木块”艺术

    JTAG上挂了不同型号的DSP,在Connect to Target时经常出错怎么解决?

    行ADSP-BF516仿真的时候,新建Session时,只能选两个相同型号的DSP,我选择的是ADSP-BF516。 在Connect to Target时经常出错,很少能联接成功。可有解决方法?
    发表于 04-28 07:02

    C语言的历史及程序介绍

    电子发烧友网站提供《C语言的历史及程序介绍.pdf》资料免费下载
    发表于 04-09 16:10 ?0次下载

    FPGA Verilog HDL语法之编译预处理

    Verilog HDL语言C语言一样也提供了编译预处理的功能。“编译预处理”是Verilog HDL编译系统的一个组成部分。Verilog
    的头像 发表于 03-27 13:30 ?665次阅读
    FPGA Verilog HDL语法之编译<b class='flag-5'>预处理</b>

    使用mpc5675k器件,调试时经常莫名其妙地触发中断,怎么解决?

    我正在使用mpc5675k器件、我在调试时经常莫名其妙地触发中断。 我知道,因为我没有配置相应的中断,所以程序经常会遇到 DefaultInterrupt 函数。 让我困惑的是,我知道
    发表于 03-27 06:42

    为什么学了C语言,却写不出像样的项目?

    在学习编程的路上,C语言几乎是每个程序员的“必修课”。不管你是打算从事嵌入式开发、系统编程,还是想要深入理解操作系统的底层原理,C语言都是一
    的头像 发表于 03-14 17:37 ?468次阅读
    为什么学了<b class='flag-5'>C</b><b class='flag-5'>语言</b>,却写不出像样的项目?

    全套C语言培训资料—PPT课件

    全套C语言培训资料,共427页,13个章节:C语言概述、程序的灵魂—算法、数据类型 & 运算符与表达式、顺序
    发表于 03-12 14:50

    C语言如何处理函数的返回值

    当你在函数的最后写上 return 0 的时候,它是如何返回给调用函数的? 比如 test 函数,为了待会更好的看懂汇编代码,我写成了 return 1234。 处理
    的头像 发表于 01-16 09:21 ?481次阅读

    EE-128:C语言中的DSP:从C调用汇编类成员函数

    电子发烧友网站提供《EE-128:C语言中的DSP:从C调用汇编类成员函数.pdf》资料免费下载
    发表于 01-07 13:48 ?0次下载
    EE-128:<b class='flag-5'>C</b><b class='flag-5'>语言</b>中的DSP:从<b class='flag-5'>C</b>调用汇编类成员<b class='flag-5'>函数</b>

    同样是函数,在CC++中有什么区别

    同样是函数,在 CC++ 中有什么区别? 第一个返回值。 C语言函数可以不写返回值类型,
    的头像 发表于 11-29 10:25 ?959次阅读

    使用C语言实现函数模板

      用C语言能不能实现一个通用的函数,既能完成整数的相加,又能完成浮点数的相加?
    的头像 发表于 11-09 11:38 ?989次阅读

    C语言中的socket编程基础

    Socket编程简介 Socket是一种通信机制,允许程序之间进行通信。在C语言中,socket编程是网络编程的基础。通过使用socket,程序可以发送和接收数据,实现不同计算机之间的
    的头像 发表于 11-01 16:51 ?1315次阅读

    C55x CSL音频预处理

    电子发烧友网站提供《C55x CSL音频预处理.pdf》资料免费下载
    发表于 09-19 11:30 ?0次下载
    <b class='flag-5'>C</b>55x CSL音频<b class='flag-5'>预处理</b>