C语言程序设计第八章预处理命令
- 格式:docx
- 大小:26.12 KB
- 文档页数:9
c语⾔的预处理指令分3种 1宏定义 2条件编译 3⽂件包含宏简介1.C语⾔在对源程序进⾏编译之前,会先对⼀些特殊的预处理指令作解释(⽐如之前使⽤的#include⽂件包含指令),产⽣⼀个新的源程序(这个过程称为编译预处理),之后再进⾏通常的编译所有的预处理指令都是以#开头,并且结尾不⽤分号2.预处理指令分3种 1> 宏定义 2> 条件编译 3> ⽂件包含3.预处理指令在代码翻译成0和1之前执⾏4.预处理的位置是随便写的5.预处理指令的作⽤域:从编写指令的那⼀⾏开始,⼀直到⽂件结尾,可以⽤#undef取消宏定义的作⽤6.宏名⼀般⽤⼤写或者以k开头,变量名⼀般⽤⼩写 宏定义可以分为2种:不带参数的宏定义和带参数的宏定义。
⼀、不带参数的宏定义1.⼀般形式#define 宏名字符串⽐如#define ABC 10右边的字符串也可以省略,⽐如#define ABC2.作⽤它的作⽤是在编译预处理时,将源程序中所有"宏名"替换成右边的"字符串",常⽤来定义常量.3.使⽤习惯与注意1> 宏名⼀般⽤⼤写字母,以便与变量名区别开来,但⽤⼩写也没有语法错误2> 对程序中⽤双引号扩起来的字符串内的字符,不进⾏宏的替换操作。
3> 在编译预处理⽤字符串替换宏名时,不作语法检查,只是简单的字符串替换。
只有在编译的时候才对已经展开宏名的源程序进⾏语法检查4> 宏名的有效范围是从定义位置到⽂件结束。
如果需要终⽌宏定义的作⽤域,可以⽤#undef命令5> 定义⼀个宏时可以引⽤已经定义的宏名#define R 3.0#define PI 3.14#define L 2*PI*R#define S PI*R*R举例1 #include <stdio.h>2#define COUNT 434int main()5 {6char *name = "COUNT";78 printf("%s\n", name);910int ages[COUNT] = {1, 2, 67, 89};1112#define kCount 41314for ( int i = 0; i<COUNT; i++) {15 printf("%d\n", ages[i]);16 }1718// 从这⾏开始,COUNT这个宏就失效19#undef COUNT2021//int a = COUNT 写这个报错2223return0;24 }⼆、带参数的宏定义1.⼀般形式#define 宏名(参数列表) 字符串2.作⽤在编译预处理时,将源程序中所有宏名替换成字符串,并且将字符串中的参数⽤宏名右边参数列表中的参数替换3.使⽤注意1> 宏名和参数列表之间不能有空格,否则空格后⾯的所有字符串都作为替换的字符串2> 带参数的宏在展开时,只作简单的字符和参数的替换,不进⾏任何计算操作。
c语言第8章-编译预处理及位运算习题答案编译预处理习题一.单项选择题1.在宏定义#define A 3.897678中,宏名A代替一个()。
A)单精度数 B)双精度数 C)常量 D)字符串2.以下叙述中正确的是A)预处理命令行必须位于源文件的开头 B)在源文件的一行上可以有多条预处理命令C)宏名必须用大写字母表示D)宏替换不占用程序的运行时间3.C语言的编译系统对宏命令的处理()。
A)在程序运行时进行的B)在程序连接时进行的C)和C程序中的其它语句同时进行的D)在对源程序中其它语句正式编译之前进行的4.在文件包含预处理语句的中,被包含文件名用“< >”括起时,寻找被包含文件的方式是()。
A)直接按系统设定的标准方式搜索目录B)先在源程序所在目录搜索,再按系统设定的标准方式搜索C)仅仅在源程序所在目录搜索D)仅仅搜索当前目录5.以下说法中正确的是A)#define和printf都是C语句 B)#define是C语句,而printf不是C)printf是C语句,但#define不是D)#define和printf都不是C 语句6.#define A 3.897678#include <stdio.h>main( ){ printf(“A=%f ”,A);}程序运行结果为()。
A) 3.897678=3.897678 B) 3.897678=A C) A=3.897678 D)无结果7.有宏定义:#define LI(a,b) a*b#define LJ(a,b) (a)*(b)在后面的程序中有宏引用:x=LI(3+2,5+8);y=LJ(3+2,5+8);则x、y的值是()。
A) x=65,y=65 B) x=21,y=65 C) x=65,y=21 D)x=21,y=218.有以下程序# define f(x) (x*x)main(){ int i1, i2;i1=f(8)/f(4) ; i2=f(4+4)/f(2+2) ;printf("%d, %d\n",i1,i2);}程序运行后的输出结果是A)64, 28 B)4, 4 C)4, 3D)64, 649.以下程序的输出结果是#define M(x,y,z) x*y+zmain(){ int a=1,b=2, c=3;printf(“%d\n”, M(a+b,b+c, c+a));}A) 19 B) 17 C) 15 D) 1210.有以下程序#define N 5#define M1 N*3#define M2 N*2main(){ int i;i=M1+M2; printf(“%d\n”,i);}程序编译后运行的输出结果是:A) 10 B) 20 C) 25 D) 3011.有如下程序#define N 2#define M N+1#define NUM 2*M+1#main(){ int i;for(i=1;i<=NUM;i++)printf(“%d\n”,i);}该程序中的for循环执行的次数是A) 5 B) 6C) 7 D) 812.位运算是对运算对象按二进制位进行操作的运算,运算的对象是____数据,以___的形式参与运算。
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语言中的预处理详解目录一.预处理的工作方式 (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.1编译预处理编译预处理是在对源程序正式编译之前的处理,以“#”开头,如文件包含“#include”、宏定义“#define”等。
预处理命令不是C语言本身的组成部分,不能直接对它进行编译。
所有的预处理指令都是在编译之前完成的,不占用程序运行时间。
C语言提供了3中预处理功能,即宏定义、文件包含、条件编译。
以“#”开头,占用一个单独的书写行,语句结尾不适用分号。
宏定义:#define文件包含:#include条件编译:#ifndef…#if…#else…#endif等1.2宏定义1.2.1不带参数的宏定义语法格式:#define 宏名[宏体](宏体可省略,如果没有则作为一个标识用于#if语句中)功能:用指定标识符(宏名)代替字符序列(宏体)说明:宏名要是一个合法的标识符,通常采用大写字母表示;宏体可以是常数、表达式和语句,甚至可以是多条语句。
举例:#define PI 3.1415926 //定义π的值为3.1415926,以后要用到π,就可以直接用PI #define OUT printf(“Hello World!\n”); //定义宏OUT替换后面的函数用#undef可以终止宏名作用域,格式为:#undef 宏名举例:void main(){#define YES 1 //定义宏YESprintf("%d\n",YES);#undef YES //结束宏YES的作用域#define YES 0 //重新定义宏YESprintf("%d\n",YES);}有关宏定义的使用,需注意以下几点:1宏名习惯采用大写,以便与普通变量区分;2宏定义不是C语句,所以不能在行尾加分号;否则,宏展开时,会将分号也算在内3在宏展开时,预处理程序仅按宏定义简单替换宏名,不做任何检查。
如果有错误,只能由编译器在编译宏展开后的源程序时发现。
4宏定义的位置是任意的,宏名的有效范围是从定义命令处到本模块结束。
C语言-预处理C 预处理器不是编译器的组成部分,但是它是编译过程中一个单独的步骤。
简言之,C 预处理器只不过是一个文本替换工具而已,它们预处理器实例分析下面的实例来理解不同的指令。
这个指令告诉CPP 把所有的MAX_ARRAY_LENGTH 定义为20。
使用#define定义常量来增强可读性。
这些指令告诉CPP 从系统库中获取stdio.h,并添加文本到当前的源文件中。
下一行告诉CPP 从本地目录中获取myheader.h,并添加内容到当前的源文件中。
这个指令告诉CPP 取消已定义的FILE_SIZE,并定义它为42。
这个指令告诉CPP 只有当MESSAGE 未定义时,才定义MESSAGE。
这个指令告诉CPP 如果定义了DEBUG,则执行处理语句。
在编译时,如果您向gcc 编译器传递了-DDEBUG开关量,这个指令就非常有用。
它定义了DEBUG,您可以在编译期间随时开启或关闭调试。
预定义宏让我们来尝试下面的实例:实例当上面的代码(在文件test.c中)被编译和执行时,它会产生下列结果:预处理器运算符C 预处理器提供了下列的运算符来帮助您创建宏:宏延续运算符(\)一个宏通常写在一个单行上。
但是如果宏太长,一个单行容纳不下,则使用宏延续运算符(\)。
例如:字符串常量化运算符(#)在宏定义中,当需要把一个宏的参数转换为字符串常量时,则使用字符串常量化运算符(#)。
在宏中使用的该运算符有一个特定的参数或参数列表。
例如:实例当上面的代码被编译和执行时,它会产生下列结果:标记粘贴运算符(##)宏定义内的标记粘贴运算符(##)会合并两个参数。
它允许在宏定义中两个独立的标记被合并为一个标记。
例如:实例当上面的代码被编译和执行时,它会产生下列结果:这是怎么发生的,因为这个实例会从编译器产生下列的实际输出:这个实例演示了token##n 会连接到token34 中,在这里,我们使用了字符串常量化运算符(#)和标记粘贴运算符(##)。
由ANSI的标准规定, 预处理指令主要包括:#define#error#if#else#elif#endif#ifdef#ifndef#undef#line#pragma由上述指令可以看出, 每个预处理指令均带有符号"#"。
下面只介绍一些常用指令。
1. #define 指令#define指令是一个宏定义指令, 定义的一般形式是:#define 宏替换名字符串(或数值)由#define指令定义后, 在程序中每次遇到该宏替换名时就用所定义的字符串(或数值)代替它。
例如: 可用下面语句定义TRUE表示数值1, FALSE表示0。
#define TRUE 1#define FALSE 0一旦在源程序中使用了TRUE和FALSE, 编译时会自动的用1和0代替。
注意:1. 在宏定义语名后没有";"2. 在Turbo C程序中习惯上用大写字符作为宏替换名, 而且常放在程序开头。
3. 宏定义还有一个特点, 就是宏替换名可以带有形式参数, 在程序中用到时, 实际参数会代替这些形式参数。
例如:#define MAX(x, y) (x>y)?x:ymain(){int i=10, j=15;printf("The Maxmum is %d", MAX(i, j));}上例宏定义语句的含义是用宏替换名MAX(x, y)代替x, y中较大者, 同样也可定义:#define MIN(x, y) (x<y)?x:y表示用宏替换名MIN(x, y)代替x, y中较小者。
2. #error指令该指令用于程序的调试, 当编译中遇到#error指令就停止编译。
其一般形式为:#error 出错信息出错信息不加引号, 当编译器遇到这个指令时, 显示下列信息并停止编译。
Fatal: filename linename error directive3. #include 指令#include 指令的作用是指示编译器将该指令所指出的另一个源文件嵌入#include指令所在的程序中, 文件应使用双引号或尖括号括起来。
我们可以在C源程序中插入传给编译程序的各中指令,这些指令被称为预处理器指令,它们扩充了程序设计的环境。
现把常用的预处理命令总结如下:1. 预处理程序按照ANSI标准的定义,预处理程序应该处理以下指令:#if #ifdef #ifndef #else #elif#endif#define#undef#line#error#pragma#include显然,上述所有的12个预处理指令都以符号#开始,,每条预处理指令必须独占一行。
2. #define#define指令定义一个标识符和一个串(也就是字符集),在源程序中发现该标识符时,都用该串替换之。
这种标识符称为宏名字,相应的替换称为宏代换。
一般形式如下:#define macro-name char-sequence这种语句不用分号结尾。
宏名字和串之间可以有多个空白符,但串开始后只能以新行终止。
例如:我们使用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 \String that i s used as an example”3. #error#error指令强制编译程序停止编译,它主要用于程序调试。
#error指令的一般形式是:#error error-message注意,宏串error-message不用双引号包围。
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。
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的功能是将标识符定义为其后的常量。
一经定义,程序中就可以直接用标识符来表示这个常量。
是不是与定义变量类似?但是要区分开!变量名表示的是一个变量,但宏名表示的是一个常量。