c语言预处理详解(修正一些明显错误)

目录
 

一.预处理的工作方式... 3
1.1.预处理的功能... 3
1.2预处理的工作方式... 3
二.预处理指令... 4
2.1.预处理指令... 4
2.2.指令规则... 4
三.宏定义命令----#define. 4
3.1.无参数的宏... 4
3.2带参数的宏... 5
3.3.预处理操作符#和##. 6
3.3.1.操作符#. 6
3.3.2.操作符##. 6
四.文件包含------include. 6
五.条件编译... 7
5.1使用#if 7
5.2使用#ifdef和#ifndef 9
5.3使用#defined和#undef 10
六.其他预处理命令... 11
6.1.预定义的宏名... 11
6.2.重置行号和文件名命令------------#line. 11
6.3.修改编译器设置命令 ------------#pragma. 12
6.4.产生错误信息命令 ------------#error 12
七.内联函数... 13

 

 

 

在嵌入式系统编程中不管是内核的驱动程序还是应用程序的编写,涉及到大量的预处理与条件编译,这样做的好处主要体现在代码的移植性强以及代码的修改方便等方面。因此引入了预处理与条件编译的概念。
在C语言的程序中可包括各种以符号#开头的编译指令,这些指令称为预处理命令。预处理命令属于C语言编译器,而不是C语言的组成部分。通过预处理命令可扩展C语言程序设计的环境。

一.预处理的工作方式

 
1.1.预处理的功能

 
    在集成开发环境中,编译,链接是同时完成的。其实,C语言编译器在对源代码编译之前,还需要进一步的处理:预编译。预编译的主要作用如下:
●将源文件中以”include”格式包含的文件复制到编译的源文件中。
●用实际值替换用“#define”定义的字符串。
●根据“#if”后面的条件决定需要编译的代码。
 


1.2预处理的工作方式

 
预处理的行为是由指令控制的。这些指令是由#字符开头的一些命令。
#define指令定义了一个宏---用来代表其他东西的一个命令,通常是某一个类型的常量。预处理会通过将宏的名字和它的定义存储在一起来响应#define指令。当这个宏在后面的程序中使用到时,预处理器”扩展”了宏,将宏替换为它所定义的值。
#include指令告诉预处理器打开一个特定的文件,将它的内容作为正在编译的文件的一部分“包含”进来。例如:下面这行命令:
#include

指示预处理器打开一个名字为stdio.h的文件,并将它的内容加到当前的程序中。
预处理器的输入是一个C语言程序,程序可能包含指令。预处理器会执行这些指令,并在处理过程中删除这些指令。预处理器的输出是另外一个程序:原程序的一个编辑后的版本,不再包含指令。预处理器的输出被直接交给编译器,编译器检查程序是否有错误,并经程序翻译为目标代码。
 


二.预处理指令

 
2.1.预处理指令
 
大多数预处理器指令属于下面3种类型:
●宏定义:#define 指令定义一个宏,#undef指令删除一个宏定义。
●文件包含:#include指令导致一个指定文件的内容被包含到程序中。
●条件编译:#if,#ifdef,#ifndef,#elif,#else和#dendif指令可以根据编译器可以测试的条件来将一段文本包含到程序中或排除在程序之外。
剩下的#error,#line和#pragma指令更特殊的指令,较少用到。
 


2.2.指令规则

 
●指令都是以#开始。#符号不需要在一行的行首,只要她之前有空白字符就行。在#后是指令名,接着是指令所需要的其他信息。
●在指令的符号之间可以插入任意数量的空格或横向制表符。
●指令总是第一个换行符处结束,除非明确地指明要继续。
●指令可以出现在程序中的任何地方。我们通常将#define和#include指令放在文件的开始,其他指令则放在后面,甚至在函数定义的中间。
●注释可以与指令放在同一行。

 


三.宏定义命令----#define   
      
使用#define命令并不是真正的定义符号常量,而是定义一个可以替换的宏。被定义为宏的标示符称为“宏名”。在编译预处理过程时,对程序中所有出现的“宏名”,都用宏定义中的字符串去代换,这称为“宏代换”或“宏展开”。
在C语言中,宏分为有参数和无参数两种。
 

      
使用#define命令并不是真正的定义符号常量,而是定义一个可以替换的宏。被定义为宏的标示符称为“宏名”。在编译预处理过程时,对程序中所有出现的“宏名”,都用宏定义中的字符串去代换,这称为“宏代换”或“宏展开”。
在C语言中,宏分为有参数和无参数两种。
 


3.1.无参数的宏

 其定义格式如下:

#define 宏名  字符串

在以上宏定义语句中,各部分的含义如下:

● #:表示这是一条预处理命令(凡是以“#”开始的均为预处理命令)。
●define:关键字“define”为宏定义命令。
●宏名:是一个标示符,必须符合C语言标示符的规定,一般以大写字母标示宏名。
●字符串:可以是常数,表达式,格式串等。在前面使用的符号常量的定义就是一个无参数宏定义。


Notice:

预处理命令语句后面一般不会添加分号,如果在#define最后有分号,在宏替换时分号也将替换到源代码中去。在宏名和字符串之间可以有任意个空格。
Eg:#define PI 3.14

在使用宏定义时,还需要注意以下几点:
●宏定义是宏名来表示一个字符串,在宏展开时又以该字符串取代宏名。这只是一种简单的代换,字符串中可以含任何字符,可以是常数,也可以是表达式,预处理程序对它不作任何检查。如有错误,只能在编译已被宏展开后的源程序时发现。
●宏定义必须写在函数之外,其作用域为宏定义命令起到源程序结束。
●宏名在源程序只能够若用引号括起来,则预处理程序不对其作宏替换。
●宏定义允许嵌套,在宏定义的字符串中可以使用已经定义的宏名。在宏展开时由预处理程序层层替换。
●习惯上宏名可用大写字母表示,以方便与变量区别。但也允许用小写字母。
 


3.2带参数的宏
 
#define命令定义宏时,还可以为宏设置参数。与函数中的参数类似,在宏定于中的参数为形式参数,在宏调用中的参数称为实际参数。对带参数的宏,在调用中,不仅要宏展开,还要用实参去代换形参。
带参宏定义的一般形式为:
#define 宏名(形参表)  字符串
在定义带参数的宏时,宏名和形参表之间不能有空格出现,否则,就将宏定义成为无参数形式,而导致程序出错。
Eg:#define ABS(x) (x)<0?-(x):(x)

 以上的宏定义中,如果x的值小于0,则使用一元运算符(-)对其取负,得到正数。
带参的宏和带参的函数相似,但其本质是不同的。使用带参宏时,在预处理时将程序源代码替换到相应的位置,编译时得到完整的目标代码,而不进行函数调用,因此程序执行效率要高些。而函数调用只需要编译一次函数,代码量较少,一般情况下,对于简单的功能,可使用宏替换的形式来使用。
 


3.3.预处理操作符#和##
 
3.3.1.操作符#
 
在使用#define定义

你可能感兴趣的:(c,c,编译预处理)