第2讲预处理命令2(11级)
C语言中的预处理指令
C语言中的预处理指令在C语言编程中,预处理指令是一种特殊的指令,用于在编译阶段之前对源代码进行处理。
预处理指令以井号(#)开头,并且不是被编译器执行的实际指令,而是由预处理器处理的。
本文将详细介绍C语言中的预处理指令,并探讨其在程序开发中的作用和用法。
一、什么是预处理指令预处理指令是在编译阶段之前对源代码进行处理的指令。
它的作用是在编译之前对源文件进行一些文本替换、条件编译或者简单的文本粘贴工作。
预处理指令以井号(#)开头,且位于编译单位(源文件或头文件)的最开始位置。
二、预处理指令的作用1. 宏定义宏定义是预处理指令中使用最广泛的功能之一。
通过宏定义,可以为一段代码或者一个常量起一个易于记忆和使用的名字,从而提高代码的可读性和维护性。
下面是一个宏定义的示例:```c#define MAX_NUM 100```在这个例子中,宏定义了一个名为MAX_NUM的常量,它的值为100。
在后续的代码中,可以使用MAX_NUM来代表100,避免了重复书写代码的问题。
2. 文件包含预处理指令还可以使用#include指令将其他文件的内容包含到当前文件中。
这种方式可以在不同的源文件中共享代码,提高代码的复用性。
下面是一个文件包含的示例:```c#include <stdio.h>```通过#include指令,可以将系统库文件stdio.h中的代码包含到当前文件中,以便后续代码可以使用stdio.h中定义的函数和类型。
3.条件编译条件编译是预处理指令中非常重要的概念。
通过条件编译,可以根据条件的真假选择性地编译代码。
这在不同的操作系统、不同的编译器或者不同的编译选项下具有重要的意义。
下面是一个条件编译的示例:```c#ifdef DEBUGprintf("Debug mode\n");#endif```在这个例子中,只有在编译时定义了DEBUG宏的情况下,才会编译并执行printf语句。
C语言的预处理命令有哪些?
问:关于C语言中的预处理命令?答:我们可以在C源程序中插入传给编译程序的各种指令,这些指令被称为预处理器指令(等价于汇编语言中的伪指令),它们扩充了程序设计的环境。
现把常用的预处理命令总结如下:1. 预处理程序按照ANSI标准的定义,预处理程序应该处理以下12条指令:#if、#ifdef、#ifndef、#else、#elif、#endif、#define、#undef、#line、#error、#pragma、#include。
显然,所有的12个预处理指令都以符号#开始,,每条预处理指令必须独占一行。
2. #define#define指令定义一个标识符和一个串(也就是字符集),在源程序中发现该标识符时,都用该串替换之(原样替换,不要附加任何人为理解上的符号)。
这种标识符称为宏名字,相应的替换称为宏代换。
一般形式如下:#define macro-name char-sequence这种语句不用分号结尾。
宏名字和串之间可以有多个空格符,但串开始后只能以新行终止。
在C语言里宏定义只用来做的宏名替换,而不做语法检查的,因而它不是C语句,所以宏定义的语句结尾不需要加分号。
宏也在C里也叫预处理命令,因为宏是在程序编译前先进行字符替换的,所以叫预处理.例如:我们使用LEFT代表1,用RIGHT代表0,我们使用两个#define指令:#define LEFT 1#define RIGHT 0每当在源程序中遇到LEFT或RIGHT时,编译程序都用1或0替换。
定义一个宏名字之后,可以在其他宏定义中使用,例如:#define ONE 1#define TWO ONE+ONE#define THREE ONE+TWO宏代换就是用相关的串替代标识符。
因此,如果希望定义一条标准错误信息时,可以如下定义:#define ERROR_MS “Standard error on input \n”如果一个串长于一行,可在行尾用反斜线”\”续行,如下:#define LONG_STRING “This is a very very long \s tring that is used as an example”3. #error#error指令强制编译程序停止编译,它主要用于程序调试(放在错误的分支中,一旦进入错误的分支就显示该信息)。
C语言基本语法——预处理器和预处理指令
C语⾔基本语法——预处理器和预处理指令 1、什么是预处理器 2、什么是预处理器指令 3、预处理器指令 4、宏指令 5、宏函数 6、宏函数的优缺点 7、条件编译指令1、什么是预处理器 • 预处理器是⼀个程序,⽤来处理源程序中的预处理指令。
• ⼀个程序在编译之前⼀般都要经过预处理。
2、什么是预处理器指令 • 以“#”开头的指令叫预处理指令 • 可以出现在任何位置,必须⼀⾏结束 • 如果要换⾏,须得⽤"\"来连接两⾏内容3、预处理器指令 • ⽂件包含#include <>#include “” • 宏定义⽆参宏定义有参宏定义 • 条件编译#if#ifdef#ifndef#endif#elif#else#undef#if defined4、宏指令 宏相当于⽂本的替换操作 • 语法格式:-定义在函数的外⾯-格式:#define PI 3.14 PI为宏的⽂本内容在编译前将PI的内容替换成3.145、宏函数 • 语法格式: #define MianJi(r) PI*r*r 宏函数只是⽂本,只是相当于做了内容替换的操作,注意参数是没有数据类型6、宏函数的优缺点 • 宏函数的优缺点可以代码更简单、更容易,避免⼤量使⽤。
• 宏函数注意事项– 宏函数中的参数⼀定要⽤括号括起来,以防⽌替换后的优先级问题。
– 宏函数的整个表达式也需要⽤括号括起来,以防⽌宏函数参于表达式的运算– 宏函数中的多条语句时,应写成复合语句,以防⽌重复定义变量。
– 调⽤宏函数时,不要将++,--的表达式做为参数传递,可以先++,--后调⽤,或者,调⽤后++,--,以防⽌在宏函数中重复地计算++,--– 宏函数也可以调⽤另⼀个宏函数7、条件编译指令 • 在代码中设置编译条件根据编译条件进⾏代码的编译并运⾏。
(跨平台) • 在编译⽂件的时候传⼊⼀个参数,根据参数就可以对代码进⾏有选择的编译。
gcc -DZHAOBENSHAN main3.c • 条件指令#if 如果 #ifdef 如果定义#ifndef 如果没定义 #elif 如果 //else if#else 否则与 #if 对应关系#endif 结束标识#undef 取消宏和#define 定义宏 • 编译⽅式 根据参数编译gcc -DXXX main.c 根据宏值(参数)#define ZHAOBENSHAN 1 根据宏"值(逻辑)"进⾏编译#if ZHAOBENSHAN==1。
C语言中的预处理详解
C语言中的预处理详解目录一.预处理的工作方式 (3)1.1.预处理的功能 (3)1.2预处理的工作方式 (3)二.预处理指令 (4)2.1.预处理指令 (4)2.2.指令规则 (4)三.宏定义命令----#define. 43.1.无参数的宏 (4)3.2带参数的宏 (5)3.3.预处理操作符#和##. 63.3.1.操作符#. 63.3.2.操作符##. 6四.文件包含------include. 6五.条件编译 (7)5.1使用#if 75.2使用#ifdef和#ifndef 95.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指令定义了一个宏---用来代表其他东西的一个命令,通常是某一个类型的常量。
预处理指令——精选推荐
预处理指令预处理命令1 . 基本介绍使⽤库函数之前,应该⽤#include引⼊对应的头⽂件,这种以#开头的命令称为预处理命令这些在编译之前对源⽂件进⾏简单加⼯的过程,就称为预处理(即预先处理,提前处理)预处理主要是处理以#开头的命令。
例如#include<stdio.h>,预处理命令要放在所有函数之外,⽽且⼀般都放在源⽂件的前⾯预处理是C语⾔的⼀个重要功能,由预处理程序完成,当对⼀个源⽂件进⾏编译时,系统将⾃动调⽤预处理程序对源程序中的预处理部分做处理,处理完毕⾃动进⼊对源程序的编译C语⾔提供了多种预处理功能,如宏定义,⽂件包含,条件编译,合理的使⽤会使编写的程序便于阅读,修改,移植和调试,也有利于程序模块化设计2 . 快速⼊门2.1 具体要求开发⼀个C语⾔程序,让它暂停5秒以后再输出内容“hello 尚硅⾕”,并且要求跨平台,在Windows和Linux下都能运⾏2.2 提⽰Windows平台下的暂停函数的原型是void Sleep(DWORD dwMilliseconds),参数的单位是“毫秒”,位于<windows.h>头⽂件linux平台下暂停函数的原型是unsigned int sleep(unsigned int second),参数的单位是“秒”,位于<unistd.h>头⽂件if ,#endif ,就是预处理命令,他们都是在编译之前由预处理程序来执⾏的2.3 代码实现#include<stdio.h>//说明:在Windows操作系统和Linux操作系统下,⽣成源码不⼀样#incLude<windows.h>int main(){Sleep(5000);puts("hello ,尚硅⾕");getchar();rerurn 0;}#if_WIN32 //如果是windows平台,就执⾏#include<windows.h>#include<windows.h>#elif_linux_//否则判断是不是linux,如果是linux就引⼊<unistd.h>#include<unistd.h>#endifint main(){//不同的平台调⽤不同的函数#if_WIN32Sleep(5000);#elif_linux_sleep(5);#endifputs("hello,尚硅⾕");getchar();return 0;}3 . 宏定义3.1 基本介绍define叫做宏定义命令,它⼜是C语⾔预处理命令的⼀种。
预处理指令
预处理指令,宏和运算符当编译程序时,它做的第一件事是进行预处理。
这一阶段中,甚至可以人为地将编译器视为一个不同的实体——预处理器。
该阶段中,编译器读入头文件、决定编译哪些行的源代码并执行文本替换。
预编译阶段的优越性在于它的编译及运行之前执行了某些特定的操作。
这些操作并不添加额外的程序执行时间。
同时,这些命令也不与程序运行时所发出的任何指令相对应。
所以,在使用预处理指令时就需要兼顾实际的运行情况。
预处理的三个基本元素:指令:在程序编译前执行的特定命令。
预定义宏:在编译前所执行的特定命令。
预处理运算符:在#if和#define中使用。
预处理指令语法与C++的其它语法有所不同。
指令以行末结束,而不需要分号。
但你可以用续行符(\)来摆脱物理行的限制。
另外,指令必须从第一行开始。
指令:有一半预处理指令提供了对条件编译的支持,条件编译的作用是用来维护同一程序的不同版本。
这些指令包括:#if #ifdef #elif #ifndef #else #end其余的预处理指令提供了对其它功能的支持,例如包括头文件和宏定义:#define #include #pragma #error #line #undef详解:★#define [定义符号或宏]目的:一:提供了创建符号常量的有效信息途径。
二:使编写人员能写宏指令,这些宏指令看上去像函数调用,但实际上是通过文本替换来实现。
三:简单地定义某些符号作为#ifdef指令的开关。
语法格式:#define标识符替代值#define 标识符[(参数1,.....,参数n)] 替代值其中,在”替代值”中出现的形参将在使用时被实参替代. 就象写函数一样.#define 标识符◆用法一:符号常量有些程序用到了一些很重要但又非常难忘或难以输入的数字。
最好事先将它们转化成为符号常量。
在转化时,通常是以大写形式表示,以便将它们与变量名区分开来。
例:#define E 2.718281828459这条指令的意思是每当程序中出现E时,预处理器就会将E替换成2.718281828459。
2022年预处理命令(2)
结果:“系统提示编译有错”!
7.1.2 带参数宏定义
• 一般形式: #define 宏名(参数表) 宏体
例 #define S(a,b) ((a)*(b)) 不能加空格
………..
#define S (r) PI*r*r
area=S(3,2);
被认为 S是符号常量(不带参的宏名
宏展开:
area=3*2;它代表字符串“(r) PI r r”。
➢ 预处理命令包括:
1. 宏定义
#define
2. 文件包含 #include
3. 条件编译 #if--#else--#endif等
7.1 宏定义#define、#undef命令
➢ 宏定义就是利用#define命令,用一个标识符(即名字) 代表一个字符串.
➢ 已经定义的宏还可以用命令#undef撤消。
条件编译 #if--#else--#endif等
1415926*r*r; */
宏展开:#vairn= c80l+u40d*2e; "stdio.h"
# define G 9.8
main() 有些公用的符号常量等宏定义,可以单独组成一个文件,然后其它文件都可以用“#include命令”将这些宏定义包含在自己的源文件中,
t= max(a+b,c+d);
} 函数
7.1.3 撤消宏定义命令#undef
➢ 宏定义命令#define应该写在函数外面,其作用 域为该命令之后到该源文件结束;
(1➢)#ifde也f 标识可符 以用命令#undef撤消已定义的宏,终止该
宏定义的作用域。 { printf("%f\n",PI);
宏定义,使标识符PI代表字符串“3.
预处理命令
10.2预处理指令主要有三种类型:1、宏定义:#define和#undef指令2、文件包含:#include指令3、条件编译:#if、#ifdef、#ifndef、#elif、#else和#endif指令宏定义包含带参数的宏和不带参数的宏两种;带参数的宏定义格式为:#define 标识符(X1,X2,X3…)替换列表其与函数调用的结果完全不同,详见12/22程序macro with parameter通过程序实例得出,为了避免宏名参与的运算结果不混淆,一般采用如下两种形式的定义方式:1、#define AREA(X)(X)*(X)2、#define AREA(X)(X*X)替代#define AREA(X)X*X避免在宏定义中使用自增符号,如对于宏定义#define AREA(X)(X*X),AREA(++X),被展开为++X*++X,假如X初值为5,则其运算结果可能为42或者49,由于未规定运算顺序,编译器可能会出现不同的结果宏定义与函数有类似的地方,宏代替函数有以下优点:1、从效率角度考虑,程序执行起来会更快些,在调用函数时总会有些额外的开销,如保存调用点的信息以便函数调用结束后能正确返回调用点,而宏调用则没有这些运行时的开销;2、宏更加通用。
与函数不同,宏的参数是没有类型的,因此,宏可以接收任何类型的参数,因此它的使用范围更加广泛同时,也会以下缺点:1、源程序编译后代码量会增加,预处理过程中会在每一处宏调用的地方插入宏的替换列表,显然会使源程序的代码增加;2、预处理器不会检查宏参数的类型,也不会进行类型转换,这样采用宏调用可能会产生错误的结果3、自增、自减运算不能在宏中进行,可能会导致错误的结果;#运算符和##运算符只能出现在带参数宏的替换列表中,例如x为一个宏的参数,那么#x就可以将参数名转化为相应的字符串,该过程称为字符串化(stringization),程序实例详见12.23 stringization##运算符,如果##连接的两个操作数中其中一个为宏的参数,那么会先进行参数替换,然后再执行##运算符的操作。
预处理指令
9.1.2 有参宏定义
1.带参宏定义的一般格式 . #define 宏名 形参表 语言符号字符串 宏名(形参表 形参表) 2.带参宏的调用和宏展开 . 实参表) (1)调用格式:宏名 实参表 )调用格式:宏名(实参表 (2)宏展开:用宏调用提供的实参字符串,直接置换 )宏展开:用宏调用提供的实参字符串, 宏定义命令行中、相应形参字符串,非形参字符保持不变。 宏定义命令行中、相应形参字符串,非形参字符保持不变。 3.说明 . (1)定义有参宏时,宏名与左圆括号之间不能留有空 )定义有参宏时, 否则, 格。否则,C编译系统将空格以后的所有字符均作为替代 字符串,而将该宏视为无参宏。 字符串,而将该宏视为无参宏。 (2)有参宏的展开,只是将实参作为字符串,简单地 )有参宏的展开,只是将实参作为字符串, 置换形参字符串,而不做任何语法检查。在定义有参宏时, 置换形参字符串, 而不做任何语法检查。在定义有参宏时, 在所有形参外和整个字符串外,均加一对圆括号。 在所有形参外和整个字符串外,均加一对圆括号。
第9章
预处理命令
ห้องสมุดไป่ตู้
所谓预处理命令是指,在对源程序进行编译之前, 所谓预处理命令是指,在对源程序进行编译之前,先 对源程序中的编译预处理命令进行处理; 对源程序中的编译预处理命令进行处理;然后再将处理的 结果,和源程序一起进行编译,以得到目标代码。 结果,和源程序一起进行编译,以得到目标代码。 9.1 宏定义 9.2 文件包含 9.3 条件编译
9.3 条件编译
条件编译可有效地提高程序的可移植性, 条件编译可有效地提高程序的可移植性,并广泛地应 用在商业软件中,为一个程序提供各种不同的版本。 用在商业软件中,为一个程序提供各种不同的版本。 1.一般格式 . #if 常量表达式 程序段1; 程序段 ; [#else # 程序段2; 程序段 ;] #endif 2.功能:当表达式为非0(“逻辑真”)时,编译程序 .功能:当表达式为非 ( 逻辑真” 段1,否则编译程序段 。 ,否则编译程序段2。
预处理命令——精选推荐
预处理命令1,所有的预处理指令都是以#号开头的
2,预处理指令分3种:
1>宏定义:#define COUNT 4 //后边没有任何符号 #undef COUNT结束宏定义
2>条件编译
#define A 5
#if (A==5)
printf("A是5");
#elif
printf("A是10");
#else
printf("A是其他");
#endif
return 0;
#if defined(A)//如果A是宏定义
3>⽂件包含
#include "lisi.h"
为了减少过多次的引⼊⽂件造成的编译效率的降低,建议在每个被引⼊⽂件内都加⼊#ifndef LISI_H //以⽂件名定义宏变量
#define LISI_H 123
int sum(int a,int b);
#endif
3.1 <>表⽰系统⾃带的⽂件,""表⽰⾃定义⽂件
3.2 不允许循环包含,⽐如说a.h包含b.h ,⽽b.h⼜包含a.h
3,预处理指令在代码翻译晨0和1之前执⾏
4,预处理指令的位置是随便写的
5,预处理指令的作⽤范围:从编写指令的那⼀⾏开始,⼀直到⽂件的结尾
6,宏名⼀般⽤⼤写或者以k开头,变量名⼀般⼩写
带参数的宏定义效率⽐函数⾼:
#define sum(v1,v2) ((v1)+(v2))
#define pingfang(v1,v2) ((v1)*(v2))。
预处理命令
3 条件编译 条件编译指令有:#if、#elif、#else、#ifdef、#ifndef,例子如下: #define URMD 0 #if URMD == 0
程序块 1 #elif URMD == 1
程序块 2 #else
预处理命令
C 语言的预处理指令有三类,一是宏定义,二是文件包含,三是条件编译。 预处理命令以符号“#”开头
1 宏定义 宏定义主要是#define,其又分为带参数定义和不带参数定义,例子如下 带参数定义 #define PI 3.14 不带参数定义 #define ST STR 在一些头文件定义中常使用 #define EXAMPLE(标识符) 其把 EXAMPLE 定义为空值,目的是为了防止头文件被多次包含,虽然可 以省略,但是一般不能省略 此外,#undef 可以终止宏名的定义 宏展开只是简单的字符串替换,简单宏常用于定义常量,宏没有类型,也没 有优先级的概念,使用定义常量主要用于指定数组长度 #define ayyLength 256 ,建 议尽量使用 const 或 enum 代替宏定义常量 constint arrLen 256; 。建议不使用宏定 义类型 #define Status int 而是用 typedef 关键字 typedef Statusint; 。
ห้องสมุดไป่ตู้
程序块 3 #endif 上述条件编译例子,是在宏条件符合时,编译器就编译这段代码,否则不编
译,它跟不带“#”的区别就在于一般的条件语句使所有条件的代码都会被编译 生成执行代码,而预处理条件语句则是只编译符合条件的那部分代码,其它不合 条件的不会生成执行代码。
因此,一般条件在编译前就确定了,那么就使用预处理条件,如果需要在程 序运行过程中才能判断,则使用一般的条件语句
预处理命令
预处理命令预处理命令的作用:对源程序编译之前做一些处理,生成扩展C源程序。
可以简化程序开发过程,提高程序的可读性,也更有利于移植和调试C语言程序。
一、宏定义1.不带参数的宏定义(1)格式:#define 宏名标识符宏内容字符序列(2)说明:①“#”开头;②占单独书写行;③行的尾部不以分号作为结束标记。
(3)宏展开(即宏替换)在用“宏内容字符序列”替换“宏名标识符”时,必须原样替换。
例如,有程序:#define NUM1 10#define NUM2 20#define NUM NUM1 + NUM2 main ( ){int a=2, b=3;a*=NUM; b=b*NUM;printf("a=%d, b=%d\n",a,b); }宏替换后程序内容如下:main ( ){int a=2, b=3;a*=10+20;b=b*10+20; /*初学者容易理解成b=b*(10+20); 从而得到错误的b值90*/ printf("a=%d,b=%d\n",a,b); }程序的运行结果为:a=60,b=50若想使b得到90的结果,可以将“#define NUM NUM1 + NUM2”改为“#define NUM (NUM1 + NUM2)”,即在“NUM1 + NUM2”外加一个(),从而在宏替换时,会将此括号原样展开出来。
【注意:程序中字符串常量即双引号中的字符与宏名相同时,不作为宏进行宏替换操作。
】例如,有程序:#define PRINT "Hello!"main(){printf("PRINT:%s\n",PRINT);} 宏替换后程序内容如下:main(){printf("PRINT:%s\n","Hello!");} 程序的运行结果是:PRINT: Hello!2.带参数的宏定义(1)格式:#define宏名标识符(参数列表)宏内容字符序列(2)说明:①参数列表由一个或多个参数构成,参数只有参数名,没有数据类型符,用逗号分隔②“宏内容字符序列”中通常会引用宏的参数(3)宏展开(即宏替换)首先将“宏内容字符序列”中的宏参数用实参替换,再将这个宏的实际内容文本替换掉源程序中的“宏名标识符(参数列表)”。
C语言预处理命令详解
C语⾔预处理命令详解⼀前⾔预处理(或称预编译)是指在进⾏编译的第⼀遍扫描(词法扫描和语法分析)之前所作的⼯作。
预处理指令指⽰在程序正式编译前就由编译器进⾏的操作,可放在程序中任何位置。
预处理是C语⾔的⼀个重要功能,它由预处理程序负责完成。
当对⼀个源⽂件进⾏编译时,系统将⾃动引⽤预处理程序对源程序中的预处理部分作处理,处理完毕⾃动进⼊对源程序的编译。
C语⾔提供多种预处理功能,主要处理#开始的预编译指令,如宏定义(#define)、⽂件包含(#include)、条件编译(#ifdef)等。
合理使⽤预处理功能编写的程序便于阅读、修改、移植和调试,也有利于模块化程序设计。
本⽂参考诸多资料,详细介绍常⽤的⼏种预处理功能。
因成⽂较早,资料来源⼤多已不可考,敬请谅解。
⼆宏定义C语⾔源程序中允许⽤⼀个标识符来表⽰⼀个字符串,称为“宏”。
被定义为宏的标识符称为“宏名”。
在编译预处理时,对程序中所有出现的宏名,都⽤宏定义中的字符串去代换,这称为宏替换或宏展开。
宏定义是由源程序中的宏定义命令完成的。
宏替换是由预处理程序⾃动完成的。
在C语⾔中,宏定义分为有参数和⽆参数两种。
下⾯分别讨论这两种宏的定义和调⽤。
2.1 ⽆参宏定义⽆参宏的宏名后不带参数。
其定义的⼀般形式为:#define 标识符字符串其中,“#”表⽰这是⼀条预处理命令(以#开头的均为预处理命令)。
“define”为宏定义命令。
“标识符”为符号常量,即宏名。
“字符串”可以是常数、表达式、格式串等。
宏定义⽤宏名来表⽰⼀个字符串,在宏展开时⼜以该字符串取代宏名。
这只是⼀种简单的⽂本替换,预处理程序对它不作任何检查。
如有错误,只能在编译已被宏展开后的源程序时发现。
注意理解宏替换中“换”的概念,即在对相关命令或语句的含义和功能作具体分析之前就要进⾏⽂本替换。
【例1】定义常量:1#define MAX_TIME 1000若在程序⾥⾯写if(time < MAX_TIME){.........},则编译器在处理该代码前会将MAX_TIME替换为1000。
预处理命令
area=PI*(a+B)*(a+B);为了得到这个结果,应当在定 义时,在字符串中的形式参数外面加一个括弧。即 #define S(r) PI*(r)*(r)在对S(a+B)进行宏展开时,将 a+B代替r,就成了PI*(a+B)*(a+B)这就达到了目的。 (2) 在宏定义时,在宏名与带参数的括弧之间不应加空 格,否则将空格以后的字符都作为替代字符串的一部 分。例如,如果有
CHAR1和a不需要定义类型,它们不是变量,在程 序中凡遇CHAR1均以CHINA代之;凡遇a均以3.6代 之,显然不需定义类型。同样,对带参的宏:
#define S(r) PI*r*r
r也不是变量,如果在语句中有S(3.6),则展开后为 PI*3.6*3.6,语句中并不出现r。当然也不必定义r 的类型。
例9.1
#define PI 3.1415926
main() {float l,s,r,v; printf("input raDiuS∶"); scanf("%f",&r);
l=2.0*PI*r;
s=PI*r*r;
v=3.0/4*PI*r*r*r; printf("l=%10.4f\nS=%10.4f\nv=%10.4f\n",l,s, v);
(6) 宏替换不占运行时间,只占编译时间。而函数调 用则占运行时间(分配单元、保留现场、值传递、 返回)。
一般用宏来代表简短的表达式比较合适。有些 问题,用宏和函数都可以。如:
#define MAX(x,y) (x)>(y)?(x)∶(y)
main() {int a,b,c,d,t;
…
t=MAX(a+b,c+d);
C语言编程中的预处理命令你会用吗?
C语言编程中的预处理命令你会用吗?什么是预处理命令预处理命令在我之前看过的C语言基础教程中好像并没有详细说到,在现在的一些项目中预处理命令的出现频率却越来越多。
事物的存在必有其存在的理由,于是就花时间去琢磨了一下,以及查阅相关资料,发现使用预处理命令去优化代码可以达到很好的效果。
预处理命令在某资料中是这样描述的'C程序的源代码中可包括各种编译指令,这些指令称为预处理命令。
虽然它们实际上不是C语言的一部分,但却扩展了C程序设计的环境'。
预处理命令实质上是运行在编译器编译过程的指令。
所以说在嵌入式程序设计中使用预处理命令不会占用最终目标运行系统的存储空间。
预处理命令有哪些在ANSI标准定义的C语言预处理程序中包括下列命令:#include,#define,#if,#else,#elif,#endif,#ifdef,#ifndef,#error,#undef,#line,#pragma等。
从以上可以看出预处理命令的共同特点就是以'#'开头。
下面就分别介绍几个在项目中使用比较多的预处理命令。
1.#include这个预处理命令算是使用的最多而又最重要的一个预处理命令了。
它的作用你是否还记得?include就是'包含'的意思,在程序编译的时候预处理器看到#include就会把<>尖括号或者' '中的那个文件找到,然后用该文件的内容替换掉#include <>这一行。
使用方法或者格式:#include <xxx.h>2.#define#define叫做宏定义,标识符为所定义的宏名,简称宏。
标识符的命名规则与前面讲的变量的命名规则是一样的。
#define的功能是将标识符定义为其后的常量。
一经定义,程序中就可以直接用标识符来表示这个常量。
是不是与定义变量类似?但是要区分开!变量名表示的是一个变量,但宏名表示的是一个常量。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
预处理命令
主讲:王克朝
学习内容
∗ 预处理命令:
∗ 宏定义命令 ∗ 文件包含命令 ∗ 条件编译命令
编译预处理
∗ 编译预处理命令 ∗ 在C++程序的源代码中可以使用各种编译指令,这些指 令称为编译预处理命令。
∗ C++提供的预处理命令主要有以下三种: ∗ 宏定义命令 ∗ 文件包含命令 ∗ 条件编译命令 ∗ 特点: ∗ 这些命令在程序中都是以“#”来引导, ∗ 每条预处理命令必须单独占用一行; ∗ 它们不是C++的语句,因此在结尾没有分号“;”
宏定义命令
∗ 宏定义的一般形式为: ∗ #define 宏名 字符串 ∗ 例子: ∗ #define PI 3.1415926 ∗ 说明: ∗ ∗ ∗ ∗ ∗ define是宏替换的关键字, 宏名”是需要替换的标识符, “字符串”是被指定用来替换的字符序列。
#define、宏名和字符串之间一定要有空格。
宏名一般用大写字母表示,以区别于普通标识符。
宏定义命令的几点说明
∗ 宏被定义以后,一般不能再重新定义。
但可以用 #undef 来终止宏定义。
∗ 一个定义过的宏名可以用来定义其他新的宏,但要注意 其中的括号。
∗ 如:#define A 20
∗
#define B (A+10) MAX(a,b) ((a)>(b)?(a):(b))
∗ 还可以有带参数的宏替换。
∗ 如: #define
文件包含命令
∗ 文件包含
所谓“文件包含”是指将另一个源 文件的内容合并到当前程序中。
文件包含命令的一般形式为:
#include<文件名>
按标准方式搜索,文件位于C++系统 目录的include子目录下 首先在当前目录中搜索,若没有, 再按标准方式搜索
或 #include”文件名”
作用
说明 (1)文件名一般是以.h为扩展名,因而称 它为“头文件” (2)文件包含的两种格式区别在于: 将文件名用“< >”括起来,用来包含那些 由系统提供的并放在指定子目录中头文件; 将文件名用双引号括起来的,用来包含用 户自己定义的放在当前目录或其他目录下 的头文件或其他源文件。
(3)一条#include命令只能包含一个文件, 若想包含多个文件,则应使用多条包含命 令
文件包含可以将头文件中的内容直 接引入,而不必再重复定义,减少 了重复劳动,节省了编程时间。
条件编译命令
∗ 条件编译
∗ 在一般情况下,源程序中的所有语句都会参加编译, ∗ 但是有时候会希望根据一定的条件编译源文件的部分 语句,这就是“条件编译”。
∗ 条件编译使得同一源程序在不同的编译条件下得到不 同的目标代码。
条件编译命令
#ifdef 标识符 程序段1 #else 程序段2 #endif
该条件编译命令的功能是:
如果在程序中定义了指定的“标识符”时,就用程序段 1参与编译,否则,用程序段2参与编译。
条件编译命令
#ifndef 标识符 程序段1 #else 程序段2 #endif
该条件编译命令的功能是:
如果在程序中未定义指定的“标识符”时,就用程序段 1参与编译,否则,用程序段2参与编译。
条件编译指令 #if 和 #endif
#if 常量表达式 //当“ 常量表达式”非零时编译 程序正文 #endif ......
条件编译指令——#else
#if 常量表达式 //当“ 常量表达式”非零时编译 程序正文1 #else //当“ 常量表达式”为零时编译 程序正文2 #endif
条件编译命令
#if 常量表达式1 程序段1 #elif常量表达式2 程序段2 …… #elif常量表达式n 程序段n #else 程序段n+1 #endif
该条件编译命令的功能是: 依次计算常量表达式的值,当表 达式的值为真时,则用相应的程 序段参与编译, 如果全部表达式的值都为假,则 用else后的程序段参与编译。
多文件结构
∗ 一个源程序可以划分为多个源文件:
∗ 类声明文件(.h文件) ∗ 类实现文件(.cpp文件) ∗ 类的使用文件(main()所在的.cpp文件)
∗ 利用工程来组合各个文件。
不使用条件编译的头文件
//main.cpp #include "file1.h" #include "file2.h" void main() { … } //file1.h #include "head.h" … //file2.h #include "head.h" … //head.h … class Point { … } …
多文件结构
使用条件编译的头文件
//head.h #ifndef HEAD_H #define HEAD_H … class Point { … } … #endif
多文件结构
学到了什么
∗ 预处理命令:
∗ 宏定义命令 ∗ 文件包含命令 ∗ 条件编译命令
。