常见c语言预处理指令(c语言预处理指令)
常见c语言预处理指令(c语言预处理指令)#include “filename.h”其中,filename头文件名,使用尖括号表示在包含文件目录中去查找(包含目录是由用户在设置环境时设置的include目录),而不在当前源文件目录去查找,简单点说,就是这个头文件不是用户自己编写的,在用户源文件中是没有的,但是用户使用的环境中有公用的头文件,就可以用#include <filename.h>来调用。通常,在单片机c语言编程应用中该文件是后缀名为".h"的头文件。在程序设计中,文件包含是很有用的。一个大程序可以分为多个模块,由多个程序员分别编程。有些公用的符号常量或宏定义等可单独组成一个文件,在其它文件的开头用包含命令包含该文件即可使用。这样,可避免在每个文件开头都去书写那些公用量,从而节省时间,并减少出错。#include头文件包含有两种方式,并且这两种方式是有区别的,下面就分别介绍这两种包含方式。#in
乘续上篇文章,接着分享完其他预处理指令
宏定义文件包含#include
文件包含是预处理的一个重要功能,它可用来把多个源文件连接成一个源文件进行编译,结果将生成一个目标文件。C语言提供#include 命令来实现文件包含的操作,其一般形式为:
#include “文件名”或者#include <文件名>
通常,在单片机c语言编程应用中该文件是后缀名为".h"的头文件。在程序设计中,文件包含是很有用的。一个大程序可以分为多个模块,由多个程序员分别编程。有些公用的符号常量或宏定义等可单独组成一个文件,在其它文件的开头用包含命令包含该文件即可使用。这样,可避免在每个文件开头都去书写那些公用量,从而节省时间,并减少出错。
#include头文件包含有两种方式,并且这两种方式是有区别的,下面就分别介绍这两种包含方式。
#include <filename.h>
其中,filename头文件名,使用尖括号表示在包含文件目录中去查找(包含目录是由用户在设置环境时设置的include目录),而不在当前源文件目录去查找,简单点说,就是这个头文件不是用户自己编写的,在用户源文件中是没有的,但是用户使用的环境中有公用的头文件,就可以用#include <filename.h>来调用。
#include “filename.h”
其中,filename头文件名。使用双引号则表示首先在当前源文件目录中查找,若未找到才到包含目录中去查找。用户编程时可根据自己文件所在的目录来选择某一种命令形式。
另外一个include命令只能指定一个被包含文件,若有多个文件要包含,则需用多个include命令。同时文件包含也允许嵌套,即在一个被包含的文件中又可以包含另一个文件,这对程序结构的精简是很有帮助的。
条件编译语句#if /# else/#elif/#endif/#ifdef/#ifndef
条件编译语句的作用是程序可以选择性的进行编译,这在程序调试过程中是非常有用的,有时候程序员在设计算法的时候,往往有不同的想法或者分支,亦或者不同的客户在应用程序中有某一部分稍有差异,出现这种情况下,为了维护程序方便,我们通常在一个程序上维护多套方案,通过条件编译的方式来选择区分不同方案之间的差异。条件编译的用法主要有如下几种。
第一种形式
#if 常量表达式
程序段1
#else
程序段2
#endif
注释:如常量表达式的值为真(非0),编译程序段1(程序段2相当于没有,这跟不执行有本质的差异,需要特别注意),否则对程序段2进行编译。
第二种形式
#if 常量表达式1
程序段1
#else if常量表达式2
程序段2
#else
程序段3
#endif
注释:如常量表达式1的值为真(非0),则对程序段1 进行编译,否则判断常量表达式2的值是否为真,如果为真则对程序段2进行编译。如果上述表达式都不为真,则编译程序段3.
第三种形式:
#ifdef 标识符
程序段1
#else
程序段2
#endif
注释:如果标识符已被#define宏定义过则对程序段1 进行编译;否则对程序段2进行编译。如果没有程序段2(它为空),本格式中的#else 可以没有,即可以写为:
#ifdef 标识符
程序段
#endif
第四种形式:
#ifndef 标识符
程序段1
#else
程序段2
#endif
注释:与第三种形式的区别是将“ifdef”改为“ifndef”。它的功能是,如果标识符未被#define 命令定义过则对程序段1 进行编译,否则对程序段2 进行编译。这与第三种形式的功能正相反。
条件编译语句# line
#line是一种用的比较少的预处理指令,它的作用是改变当前行数和文件名称,它是在编译程序中预先定义的标识符命令,其格式如下
#line number["filename"]
其中[]内的文件名可以省略。例如:
#line 30 a.h
其中,文件名a.h 可以省略不写。
这条指令可以改变当前的行号和文件名,例如上面的这条预处理指令就可以改变当前的行号为30,文件名是a.h。初看起来似乎没有什么用,不过,他还是有点用的,那就是用在编译器的编写中,我们知道编译器对C 源码编译过程中会产生一些中间文件,通过这条指令,可以保证文件名是固定的,不会被这些中间文件代替,有利于进行分析。
条件编译语句# error
语句的意思是,当预处理器预处理到#error命令时将停止编译并输出用户自定义的错误消息。其格式为:
#error [用户自定义的错误消息]。 // “[]”代表用户自定义的错误消息可以省略不写。
条件编译语句#pragma
在所有的预处理指令中,#pragma 指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作。#pragma 指令对每个编译器给出了一个方法 。依据定义 编译指示是机器或操作系统专有的 且对于每个编译器都是不同的。其格式一般为:
#pragma para
其中para 为参数,基于#pragma的复杂度,对于初学者来说,可以暂时先搁着,等基础掌握的更深入一点,项目开发有一定经验的时候可以着重研究一下,此处就不作展开了
C51单片机特殊寄存器定义语句SFR/SBIT
这两个语句应该算是C51单片机的特殊专有语句,sfr全称为:special function register(翻译为:特殊功能寄存器),他的作用就是把单片机的特殊功能寄存器,用通俗的字母表示,方便开发者调用。
举个简单的例子,C51单片机端口0寄存器地址为0X80,直观来说,用户如果要去用C51单片机的端口0的话,就要对端口0进行配置(输出高低配置),实际上就是要往端口0特殊配置寄存器地址0X80里面写如配置值,如果每次都要直接找到0X80这个地址去写值得话,程序会变得非常难以维护。而SFR得作用就是将0X80这种不直观得寄存器地址,用直观得标识来替代,如
SFR P0 = 0x80; //以后配置端口0输出得话,只要直接给P0赋值就好了
SBIT用法意义跟SFR基本一样,只不过SBIT是用来定义位的。