习题七 编译预处理命令
C语言习题集(预处理命令篇)
第六章预处理命令6.1 选择题1.下面叙述中正确的是()。
A. 带参数的宏定义中参数是没有类型的B. 宏展开将占用程序的运行时间C. 宏定义命令是C语言中的一种特殊语句D. 使用#include命令包含的头文件必须以“.h”为后缀2.下面叙述中正确的是()。
A. 宏定义是C语句,所以要在行末加分号B. 可以使用#undef命令来终止宏定义的作用域C. 在进行宏定义时,宏定义不能层层嵌套D. 对程序中用双引号括起来的字符串内的字符,与宏名相同的要进行置换3.在“文件包含”预处理语句中,当#include后面的文件名用双引号括起时,寻找被包含文件的方式为()。
A. 直接按系统设定的标准方式搜索目录B. 先在源程序所在目录搜索,若找不到,再按系统设定的标准方式搜索C. 仅仅搜索源程序所在目录D. 仅仅搜索当前目录4.下面叙述中不正确的是()。
A. 函数调用时,先求出实参表达式,然后带入形参。
而使用带参的宏只是进行简单的字符替换B. 函数调用是在程序运行时处理的,分配临时的内存单元。
而宏展开则是在编译时进行的,在展开时也要分配内存单元,进行值传递C. 对于函数中的实参和形参都要定义类型,二者的类型要求一致,而宏不存在类型问题,宏没有类型D. 调用函数只可得到一个返回值,而用宏可以设法得到几个结果5.下面叙述中不正确的是()。
A. 使用宏的次数较多时,宏展开后源程序长度增长。
而函数调用不会使源程序变长B. 函数调用是在程序运行时处理的,分配临时的内存单元。
而宏展开则是在编译时进行的,在展开时不分配内存单元,不进行值传递C. 宏替换占用编译时间D. 函数调用占用编译时间6.下面叙述中正确的是( )。
A. 可以把define和if定义为用户标识符B. 可以把define定义为用户标识符,但不能把if定义为用户标识符C. 可以把if定义为用户标识符,但不能把define定义为用户标识符D. define和if都不能定义为用户标识符7.下面叙述中正确的是()。
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语句。
编译预处理
编译预处理1概述:编译预处理是在源程序正式编译前的处理。
预处理名令一般写在程序的最开头,并且以#开头的命令。
编译预处理命令不是c语言本身的组成部分,也不属于c语句,不能直接对他们编译。
在代码的正式编译之前(编译即指转换成二进制的机器语言),系统先对预处理命令进行处理,然后再由编译程序对处理后的程序进行正常的编译,得到可执行文件。
即对一个源程序进行编译时,系统会先引用预处理命令对源程序中的预处理部分进行处理,然后自动进行源程序的编译。
C语言提供3中预处理命令:宏替换文件包含条件编译他们均以#开头,并独占一个书写行,语句结尾不用;作为结束符。
2 宏替换(宏定义)分为两种:(1)无参数的宏替换是指用一个指定的标识符(即宏名)来代表程序中的一个字符串。
格式#define 宏名字符串如#define SIZE 10SIZE为宏名,此命令执行后,预处理程序对源程序中的所有SIZE的标识符用10替换。
说明:①宏名一般用大写字符,但不是必须的。
②字符串可以是常量,表达式,语句或多条语句可以是任何语句如输出语句,赋值语句等等③宏定义与变量定义不同,只是做字符的简单替换,不占内存空间,也不赋值④结尾不能加;,如果加了;,则;也作为字符串的一部分,一同参与替换。
⑤宏定义允许嵌套定义,即在宏定义的字符串中可以使用已经定义的宏名。
⑥宏定义要写在函数之外的,一般写在程序的开头,作用范围是从定义到本文件结束,出来这个文件失去作用了。
若要终止其作用,在需要终止前面加#undef 宏名⑦若宏名出现在双引号中,则将不会发生宏替换。
如printf(“ADD”) ADD是宏,这里不会进行宏替换了⑧替换文本不替换用户标识符中的成分宏名ADD不会替换标识符ADDIP中的ADD(2)有参数的宏替换宏定义中的参数为形式参数,在宏调用中的参数为实际参数。
格式:#define 宏名(形参)字符串各参数间用,隔开。
替换时,不仅要将宏展开,还要将形参替换为实参,但是仅仅是替换而不会去运算得出一个值,这点千万注意。
第7章 预编译命令
如果表达式的值为真(非零) 时,对程序段1进行编译;否则 (为零时)对程序段2进行编译。
24
C语言程序设计教程
7.4 条件编译
例7.5 条件编译#if~#else~#endif的用法
#include <stdio.h> #define MAX 10 int main( ){ #if MAX>99 printf("选用大于99值编译源程序.\n"); #else printf("选用较小的值编译.\n"); #endif 程序运行结果为: return 0; 输出: 选用较小的值编译. }
18
7.2.2 带参宏定义
C语言程序设计教程
7.2.2 带参宏定义
sq=SQ1(a+1); printf("SQ1: sq=%d\n",sq); sq=SQ2(a+1); 程序运行结果: printf("SQ2: sq=%d\n",sq); 输入: input a number: 3 sq=SQ3(a+1); 输出: SQ1: sq=16 printf("SQ3: sq=%d\n",sq); SQ2: sq=7 sq=160/SQ1(a+1); printf("SQ1: sq=%d\n",sq); SQ3: sq=16 sq=160/SQ2(a+1); SQ1: sq=160 printf("SQ2: sq=%d\n",sq); SQ2: sq=57 sq=160/SQ3(a+1); SQ3: sq=10 printf("SQ3: sq=%d\n",sq); return 0; }
C语言习题七编译预处理
习题七编译预处理1.有一个名为init.txt的文件,内容如下:#define HDY(A,B) A/B#define PRINT(Y) printf("y=%d\n",Y)有以下程序#include "init.txt"main(){ int a=1,b=2,c=3,d=4,k;k=HDY(a+c,b+d);PRINT(k);}下面针对该程序的叙述正确的是______。
A、编译出错B、运行出错C、运行结果为 y=0D、运行结果为 y=6解析:本题考查的是带参数的宏定义。
宏替换后,表达式k=HDY(a+c,b+d)即变为k=a+c/b+d=1+3/2+4=6。
故本题答案选D。
2.有以下程序#include <stdio.h>#define N 5#define M N+1#define f(x) (x*M)main(){ int i1,i2;i1=f(2);i2=f(1+1);printf ("%d %d\n",i1,i2);}程序的运行结果是______。
A、12 12B、11 7C、11 11D、12 7解析:本题考查的是宏定义。
在编译时预处理程序用"替换文本"来替换宏,并用对应的实参来替换"替换文本"。
此题中的替换文本分别为:N+1、(x*M)。
引用带参的宏名i1=f(2),在经过宏替换后i1=2*N+1=2*5+1=11(注:因为在对宏 M 的替换中N+1没有加括号,所以对宏f(x)的替换文本展开后就变为:x*N+1形式);与上相同 i2在引用带参的宏名并替换展开后变为:i2=1+1*N+1=1+1*5+1=7。
故本题答案为B。
3.以下叙述中错误的是______。
A、C程序中的#include和#define行均不是C语句B、除逗号运算符外,赋值运算符的优先级最低C、C程序中,j++;是赋值语句D、C程序中,+、-、*、/、%号是算术运算符,可用于整型和实型数的运算解析:本题考查的是C语言运算符。
第7章-编译预处理
练习:P199选择題10
多文件组织
通常为了程序设计和调试,将一个大的程序分成多个源文件存储,每
个源文件包含一个或多个函数(一个函数不能存储在两个文件中)。
当一个程序由多个源文件组成时,某源文件中定义的标识符(如全局
变量名、函数名等)能否被其他源文件中的函数访问,取决于该标识 符的连接属性。连接属性有两种:内部连接和外部连接。
7.1.1 不带参数的宏_注意事项
(4)尽管宏名也是一个标识符,但它不是变量,不分配内
存空间,因此,不能作为变量使用。 (5)宏定义中可以没有替换文本,例如:#define DEBUG 这种宏定义通常作为条件编译检测的一个标志。
7.1.2 带参数的宏
1.
定义形式:
#define 标识符(参数表) [字符序列]
//File1.cpp static int iMax(int x, int y) { return x>y?x:y ; }
//File2.cpp void main() { int M; int iMax(int,int); M=iMax(6,2); }
说明:由于static修饰,File2.cpp中的不能调用File1.cpp的iMax()函数。
7.1.2带参数宏和函数的区别
(3)函数调用时,要求实参和形参的数据类型一致,如不 一致,系统自动把实参转换为形参的类型; 宏扩展不存在类型问题,宏名和它的参数都是一种符号 表示,没有类型;宏扩展也没有返回值。
7.1.2带参数宏和函数的区别
例7.1.1:比较下面的MAX宏和max( )函数。 # include <stdio.h> # define MAX(x,y) ((x)>(y)?(x):(y)) int max(int x, int y) { return x>y?x:y;} void main() { int a=10, b=20; 运行结果: 运行结果? float x=3.14, y=31.5; 20 31.500000 printf("%d\n",MAX(a,b)); 20 printf("%f\n",MAX(x,y)); 31 printf("%d\n",max(a,b)); 0.000000 printf("%d\n",max(x,y)); printf("%f\n",max(x,y)); }
第七讲 编译预处理
z = square(a + b);
展开后变成
明显错了
z = a + b * a + b;
13
带参宏与函数调用不同
只是在程序预加工阶段中在源代码中展开。并不会在 程序执行阶段执行调用动作。 宏定义及调用中没有类型问题。 一个宏能否使用、使用中发生什么、能否得到预期效 果,完全看展开后的情况。 注意
#include #define #undef #if #else #elif #endif
3
1. 文件包含命令
把指定文件内容包含到当前源文件 形式1
#include <文件名> 形式1 #include "文件名" 形式2
形式2
用于包含系统头文件,预处理程序到指定目录找文件(通 常指定几个系统文件目录)。 用于包含自己的文件。预处理程序先在源文件所在的目录 里找,找不到时再到指定目录中去找。 在文件系统中查找指定的文件 如果找到,就用找到的文件的内容取代该命令行。 被包含文件里如有预处理行也会处理。
21
本章总结
编译预处理过程 文件包含 宏和条件编译的概念与使用方法
22
3. 带参数宏定义
#define 宏名字(参数列表) 替代正文 注意
宏名字与括号间不能有空格 用逗号分隔的标识符看作参数。 替换正文为任意正文序列。
使用形式与函数调用类似,以类似参数的形 式给出宏参数的替代段,用逗号分隔,称为 宏调用。
11
例
为什么加 括号?
C语言程序设计答案——清华大学出版社(第二版)
第13章 编译预处理命令(培训)
7.1 宏定义
7.1 宏定义
◆宏定义的目的是允许程序员以指定标识符代替一个较复杂 的字符串。 ■C语言的宏定义分为两种:简单宏定义与带参数的定义。
一. 简单宏定义
◆语法形式: #define 标识符 字符串 ■ #define为预编译符; ◆标识符称为“宏名”,通常使用大写英文字母和有直观意 义的标识符命名,以区别于源程序中的其它标识符; ■字符串构成“宏体”,由ASCII字符集中的字符组成. 7.1 宏定义
#ifndef 标识符 语句 #endif 或形式为: #ifndef 标识符 语句1 #else 语句2 #endif
若标识符未定义,则编译语句。
若所指标识符未定义,则编译语 句1;否则编译语句2。
7.3 条件编译
三. #undef命令行
#undef 标识符 其中#undef为预编译符。 功能:使所指标识符变为无定义。
二. 控制条件为定义标识符的条件编译
1.#ifdef命令行
#ifdef 标识符 语句 #endif 或形式为: #ifdef 标识符 语句1 #else 语句2 #endif 7.3 条件编译
若标识符已定义,则编译语句。
若所指标识符已定义,则编 译语句1;否则编译语句2。
2.#ifndef命令行
2.宏展开
◆带参数的宏展开是按#define命令行中指定的字符串从左 到右进行置换。 ◆如果宏体字符串中包含宏名中的形参,则将程序语句中 相应的实参代替形参,如果字符串中的字符不是参数字符, 则保留。 例7-2,求a,b,c三个数中最大者。 #include <stdio.h> #define MAX(a,b) (a>b)?a:b 程序运行结果: void main() {int a,b,c,max; 462 scanf("%d%d%d",&a,&b,&c); max=6 max=MAX(a,b); max=MAX(max,c); printf("max=%d\n",max); } 7.1 宏定义
编译预处理
a=1,b=2,c=3 a=1,b=2,c=3;
宏使用例题
3.以下程序的输出结果是 ) 以下程序的输出结果是( 以下程序的输出结果是 #define MCRA(m) 2*m #define MCRB(n,m) 2*MCRA(n)+m main(){ int i=2,j=3; printf(“%d\n",MCRB(j,MCRA(i)));} 4.下面程序的运行结果是 ) 下面程序的运行结果是( 下面程序的运行结果是 #define N 10 #define s(x) x*x #define f(x) (x*x) main(){ int i1,i2; i1=1000/s(N); i2=1000/f(N); printf(“%d %d\n”,i1,i2);}
宏使用例题
2.有如下程序,该程序中的for循环执行的次数是 有如下程序,该程序中的for循环执行的次数是 for A)5 B)6 C)7 D)8 A)5 B)6 C)7 D)8 #define N 2 N+1 #define M N+1 #define NUM 2*M+1 *M+1 main() {int i; (i=1 i<=NUM; printf("% n",i); for (i=1;i<=NUM;i++) printf("%d\n",i);}
宏使用例题
程序头文件type type1 的内容是: 1.程序头文件type1.h的内容是:程序编译后的输出结果 A)10 B)20 C)25 D)30 是:A)10 B)20 C)25 D)30 #define N 5 N*3 #define M1 N*3 程序如下: "type1 程序如下:#include "type1.h" N*2 #define M2 N*2 printf("%d\ main(){ int i; i=M1+M2; printf("%d\n& 不带参数宏定义的一般形式为: 不带参数宏定义的一般形式为: #define 宏名 宏体 其中, 是宏定义命令, 其中 , #define是宏定义命令 , 宏名是一个标识符 , 宏 是宏定义命令 宏名是一个标识符, 体是一个字符序列。 体是一个字符序列。 功能:用指定的宏名(标识符)代替宏体(字符序列) 功能:用指定的宏名(标识符)代替宏体(字符序列)。
C语言编译预处理和预处理命令
C语⾔编译预处理和预处理命令1.预处理概念:编译程序时,编译器将对程序⽂件作⾄少两个阶段的编译预处理,预处理程序预处理阶段和编译程序预处理阶段。
预处理程序预处理阶段:C预处理程序先于C编译程序运⾏。
预处理程序从前向后根据预处理命令做相应的处理。
预处理命令分为三类: ①⽂件包含命令 ②宏定义命令 ③条件编译命令编译程序预处理阶段: ①将注释替换为空格字符 ②将续⾏符连接的物理⾏合并成逻辑⾏ ③将仅⽤空⽩字符分隔的多个字符串直接连接2.⽂件包含命令:在预处理程序⽂件时,遇到包含⽂件预处理命令⾏,都⽤filename⽂件中的全部内容替代这⼀⾏,使其成为程序⽂件的⼀部分参与编译。
双引号包含的⽂件名优先在程序⽂件所在的⽬录查找,如果找不到,再从C编译系统指定的⽬录中查找。
#inlcude <filename.h>#include "filname.h"3.宏定义命令:指⽤⼀个标识符来代替⼀个字符序列。
有两种宏形式:类对象宏(object-like macro)定义与类函数宏(function-like macro)定义。
前者时不带参数的宏定义形式,后者时带参数的宏定义形式。
带参数宏定义中宏名和左括号之间不能有空格,右括号和宏主体之间⾄少有⼀个空格。
仅有括号(没有宏参数)是允许的。
#define宏名(宏参数1, 宏参数2, ...) 宏主体调⽤形式:宏名(替换参数1, 替换参数2,...),宏参数与替换参数只有参数个数和顺序的对应关系,不存在类型⼀致性的问题。
#define MAX(A,B) ((A)>(B)?(A):(B))......源⽂件:x=MAX(p+q,r+s);替换成:x=((p+q)>(r+s)?(p+q):(r+s));......对于出现在宏主体中的宏名,宏展开时不做任何替换;但它之前定义的宏名出现在宏主体时,宏展开要实施替换。
包含在字符串直接常量和注释中的宏调⽤形式不进⾏替换。
编译预处理
条件编译
– 预处理程序除了提供上面介绍的宏定义和 文件包含功能,其还提供了条件编译的功 能。条件编译可以按不同的条件去编译不 同的程序部分,因而产生不同的目标代码 文件。这对于程序的移植和调试是很有用 的。C++中的条件编译有三种形式 : – #ifdef形式:是指该形式的第一个编译命令 为#ifdef 。 – #ifndef形式:是指该形式的第一个编译命 令为#ifndef 。 – #if形式:是指该形式的第一个编译命令为
第六讲:编译预处理
课程内容安排
– 预处理命令 –宏 – 文件包含 – 条件编译 – 其他命令 – 综合练习 – 思考和习题
预处理命令
– 预处理就是对源文件进行编译前,先对预 处理部分进行处理,然后对处理后的代码 进行编译。这样做的好处是,经过处理后 的代码,将会变的很精短。为让用户更好 使用预处理,C++提供了丰富的预处理命 令,主要包括如下几种:#define、/#error、 #if、#else、#elif、#endif、#ifdef、#ifndef、 #undef、#line和#pragma。 – 由上述命令读者可以看出,每个预处理指 令均带有符号“#”。简单来说,上面的这 些预处理命令可以划分为文件包含,条件
示例代码
– 1 //file1.cpp – 2 double Add(double a,double b) //file1文件中包含的函数 – 3{ – 4 return a+b; //返回两个浮点数之和 – 5} – 6 //file2.cpp – 7 #include "file1.cpp" //包含file1.cpp文件 – 8 #include <iostream.h> – 9 void main() – 10 { – 11 double a,b; //定义变量 – 12 double e,f; – 13 a=3; //初始化变量 – 14 b=2;
编译预处理命令
编译
说明: 说明:
① 宏定义的作用域是从定义处开始到源文件结束, 宏定义的作用域是从定义处开始到源文件结束, 但根据需要可用undef命令终止其作用域。形式为: undef命令终止其作用域 但根据需要可用undef命令终止其作用域。形式为: #undef 宏名
②为了增加程序的可读性,建议宏名用大写字母,其 为了增加程序的可读性,建议宏名用大写字母,
带参数的宏定义
【例】分析下面程序运行后的输出结果。 分析下面程序运行后的输出结果。 #define MA(x) x*(x-1) 特别注意: 特别注意: 由于替换文本中的x 由于替换文本中的x main( ) 没有用括号括起, 没有用括号括起, { int a=1,b=2; 因此,1+a+b也不能 因此,1+a+b也不能 printf("%d\n", MA(1+a+b)); 用括号括起。 用括号括起。 } 程序输出结果:8 程序输出结果: 分两次替换: 分两次替换: ①MA(1+a+b) 用x*(x-1) 替换。 替换。 MA(1+a+b) x*(x1+a+b替换 替换x ②用1+a+b替换x。 printf语句被展开为 语句被展开为: printf语句被展开为: printf("%d\ 1+a+b*(1+a+bprintf("%d\n", 1+a+b*(1+a+b-1));
编译预处理命令
源文件 *.c
目标文件 编译编译 编译 编译 编译 连接 连接 *.obj
运行文件 *.exe
编译预处理
编译预处理包括: 编译预处理包括: 宏定义 编 译 文件包含 条件编译
第7章 编译预处理命令
(2) 例如: 例如: #define S(r) area=S(a+b) 宏展开后形式 PI*r*r #define S(r) PI*(r)*(r)
area=S(a+b) 宏展开后形式
PI*a+b*a+b
PБайду номын сангаас*(a+b)*(a+b)
(3) 在宏定义时,在宏名与带参数的括号之间不应加 在宏定义时, 空格, 空格,否则将空格以后的字符都作为代换字符串的一 部分。 部分。
(3) 函数中的形参和实参的类型要求一致;而宏名无类型, 函数中的形参和实参的类型要求一致;而宏名无类型, 它的参数也无类型, 它的参数也无类型,宏展开时只是把指定的字符串代替宏名 即可。 即可。 (4) 调用函数时只可得到一个返回值,而用宏可以设法得到 调用函数时只可得到一个返回值, 多个值。 多个值。 (5) 使用宏次数多时,宏展开后源程序会变长;而函数调用 使用宏次数多时,宏展开后源程序会变长; 不会使程序变长。 不会使程序变长。 (6) 宏替换不占运行时间,只占编译时间;而函数调用则占 宏替换不占运行时间,只占编译时间; 用运行时间。 用运行时间。
例如: 例如: #define PI 3.1415926
PI来代替字符串 来代替字符串 “3.1415926”
注意: 在预编译处理时, ※ 注意: 在预编译处理时,将程序中在该命令以后 出现的所有的PI都用 都用“ 代替。 出现的所有的 都用“3.1415926”代替。 代替 【例7.1】 输入圆半径,求圆周长、圆面积、球体积。 】 输入圆半径,求圆周长、圆面积、球体积。 #include <iostream.h> #define PI 3.1415926 void main() { double l,s,r,v; cout<<"inputradius:"<<endl; cin>>r; l=2*PI*r; s=PI*r*r; v=4.0/3.0*PI*r*r*r;
C语言编译预处理命令
编译预处理命令文件包含:把指定的文件插入到预处理命令行所在的位置并取代该命令行,即把指定的文件与当前的源程序文件连接成一个源文件。
#include<文件名>在文件包含目录中去查找指定的文件,并将该文件添加到源文件中。
一个被包含的文件中可以含有文件包含命令来包含另一个文件。
#include“文件名”命令中文件名的位置是当前源文件的位置,若在当前目录中未找到该文件,则再到“包含目录”中去查找。
宏用一个标识符表示一个字符串,称为宏,被定义为宏的标识符称为宏名。
在编译预处理时对程序中所有出现的宏名用宏定义中的字符串去代换,这就是宏替换。
它是由系统编译程序时自动完成的。
无参宏定义#define 标识符字符串如#define PI 3.14使用宏时要注意:(1)宏定义是用宏名来表示一个字符串,在宏展开时用字符串取代宏名。
(2)宏定义不是变量定义或语句,在行末不能加分号,如果加上分号则分号也成为字符串的一部分。
(3)宏定义可以出现在程序的任何地方,其作用域是宏定义命令所在位置开始到源程序结束。
如果要终止其作用域可使用#undef命令。
(4)宏定义允许嵌套,在宏定义的字符串中可以使用已经定义的宏名。
在宏展开时将逐层替换。
(5)#define PI 3.1415926#define AREA PI*y*y有参宏定义#define 宏名(形参表)字符串对带参数的宏,在调用中不仅要进行宏展开,而且还要用实参去替换形参。
带参宏调用的语法格式如下:宏名(实参表);#define M(x) x+1K=M(3);K=3+1定义有参宏时要注意以下几点:(1)有参宏定义中,宏名与形参表之间不能有空格出现。
(2)在函数中,调用时要把实参的值赋给形参,进行“值传递”。
而在带参宏调用中,只是符号替换,不存在值传递问题。
(3)宏定义中的形参只能是标识符,而宏调用中的实参可以是表达式。
宏替换中对实参表达式不做计算直接照原样替换,字符串内的形参通常用括号括起来以避免出错。
第7章 编译预处理命令
条件编译命令的作用是实现对源程序代码有选择地进行编译。 条件编译命令的格式1: #ifdef 符号常量 程序段1 #else 程序段2 #endif
编译预处理时,如果#ifdef后面的符号常量已经被定义,则 编译程序段1,否则编译程序段2。其中, 可以没有程序段2的 部分,相当于程序段2为空语句。
条件编译命令的格式2:
• • • • • • • • #if 表达式 程序段1 #else
程序段2 #endif
编译预处理时,若表达式的值为非0,则编译程序段1 ,否则编译程序段2。与格式1相同,程序段2的部分可以 没有,相当于程序段2为空语句。
把file2.c插入file1.c的 #include命令的位置处, 使file2.c成为源程序 file1.c的一部分。
【例7-2】 设有宏定义
#define
S(a,b) a*b
试完成下列宏替换:S(3,4), S(x+y,z), S((x+y),z) 。 S(3,4) 3*4
3替换a, 4替换b
S(x+y,z) x+y替换a,z替换b S((x+y),z) (x+y) 替换a,z替换b 注意: 虽然带参数宏的使用形式与函数相似,但是它们在本质 上却是完全不同的,使用带参数的宏只是进行简单的字符替 换,没有函数调用中复杂的参数传递过程。 (x+y)*z x+y*z
• • •
【例7-3】 main()
条件编译命令应用示例之一
定义一个宏名为 MAX的符号常量
#define MAX 10
•
• • • • • • •
{
#ifdef MAX
该部分语句将不被编译
编译预处理语句
编译预处理语句
在编译过程中,预处理器是第一步,它会对源代码进行处理,生成新的代码。
以下是几个常见的编译预处理语句:
1. `#include`:用于在程序中包含头文件,实现代码的模块化。
例如:`#include <stdio.h>`
2. `#define`:用于定义宏,可以将一些常量或函数进行简化。
例如:`#define PI 3.14159`
3. `#ifdef`和`#ifndef`:用于条件编译,根据条件决定是否编译
某些代码块。
例如:
```
#ifdef DEBUG
printf("Debug mode is enabled.\n");
#endif
```
4. `#if`和`#endif`:用于条件编译,根据条件决定是否编译某些代码块。
例如:
```
#if X > 0
...
#endif
```
5. `#pragma`:用于向编译器发出特定的指令。
例如:`#pragma pack(1)`用于设定结构体以字节对齐方式进行排列。
这些预处理语句是在编译过程中进行处理的,可以根据需要进行使用,以便更好地管理和控制代码的编译过程。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
习题七编译预处理命令
一.选择题
1. 在宏定义#include PI 3.14159中,宏名PI代替一个( )
A)单精度数B)双精度数
C)常量D)字符串
2. 下列描述中,正确的是( )
A)预处理是指完成宏替换和文件包含中指定的文件的调用
B)预处理指令也是C语言
C)源程序中,凡是行首以#标识的控制行都是预处理指令
D)预处理就是完成C编译程序对C源程序的第一遍扫描,为编译的词法分析
和语法分析做准备
3. 在#include<文件名>的使用格式中,寻找被包含文件的方式是( )
A)直接按系统设定的标准子目录搜索
B)先在源程序所在的目录搜索,再在系统设定的标准子目录搜索
C)仅仅在源程序所在的目录搜索
D)仅仅搜索当前目录
4. 在任何情况下都不会引起二义性的宏定义是( )
A)#define POWER (x) x*x
B)#define POWER(x) (x*x)
C)#define POWER(x) (x)*(x)
D)#define POWER(x) ((x)*(x))
5. 对于宏替换的说法正确的是( )
A)宏名必须用大定字母
B)宏替换只是字符替换
C)宏替换要占用运行时间
D)宏名必须定义类型
6. 下列程序执行后,输出的结果是( )
#include <stdio.h>
#define EX(y) 3.66+y
#define PRINT(x) printf (“%d”,(int)(x))
void main ()
{int m=4;
PRINT(EX(5)*m);
}
A)23 B)20 C)10 D)0
7. 设有以下宏定义:
#define N 3
#define Y(n) ((N+1)*n)
执行语句z=2*(N+Y(5+1));后,z的值为( )
A)出错B)42 C)48 D)54
8. 下列程序执行后,输出的结果是( )
#include <stdio.h>
#define SQR(x) x*x
void main( )
{int a=10,k=2,m=1;
a/=SQR(k+m)/SQR(k+m);
printf(“%d”,a);
}
A) 10 B)1 C)9 D)0
9. 下列程序执行后,输出的结果是( )
#include <stdio.h>
#define N 2
#define M N+2
#define CUBE(x) (x*x*x)
void main( )
{ int j;
j=M;
j =CUBE(j);
printf(“%d\n”,j);
}
A)8 B)10 C)12 D)64
10.设有以下宏定义:
#define S(x) x/x
int a=4,b=3,area;
执行语句area=S(a+b);后,area的值为( )
A)1 B)4 C)7 D)8
二.填空题
三.编程题。