第九章编译预处理与带参数的主函数
- 格式:doc
- 大小:43.50 KB
- 文档页数:6
第九章编译预处理课题:第九章编译预处理教学目的:1、了解预处理的概念及特点2、掌握有参宏与无参宏的定义及使用,领会文件包含的使用及效果教学重点:教学难点:掌握宏的使用,文件包含有参宏与无参宏的使用步骤一复习引导ANSI C标准规定可以在C源程序中加入一些“预处理命令”,以改进程序设计环境,提高编程效率。
这些预处理命令是由ANSI C统一规定的,但它不是C语言本身的组成部分,不能直接对它们进行编译。
必须在对程序进行通常的编译之前,先对程序中这些特殊的命令进行“预处理”,即根据预处理命令对程序作相应的处理。
经过预处理后程序不再包括预处理命令了,最后再由编译程序对预处理后的源程序进行通常的编译处理,得到可供执行的目标代码。
步骤二讲授新课C语言与其他高级语言的一个重要区别是可以使用预处理命令和具有预处理的功能。
C 提供的预处理功能主要有以下三种:宏定义、文件包含、条件编译。
分别用宏定义命令、文件包含命令、条件编译命令来实现。
为了与一般C语句相区别,这些命令以符号“ #” 开头。
§9.1宏定义宏:代表一个字符串的标识符。
宏名:被定义为“宏”的标识符。
宏代换(展开):在编译预处理时,对程序中所有出现的“宏名”,用宏定义中的字符串去代换的过程。
一、不带参数的宏定义一般形式:#define 标识符字符串#define PI 3.1415926main(){ 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(“%10.4f,%10.4f,%10.4\n”, l, s, v);}例如:由键盘输入y值,求表达式:3(y2+3y)+ 4(y2+3y)+ y(y2+3y)#define M (y*y+3*y)main(){ int s, y;printf( “Input a number :”); scanf (“%d”,&y);s=3*M+4*M+y*M; p rintf(“s=%d\n”,s);}先宏展开:s=3*(y*y+3*y) +4*( y*y+3*y) + y*(y*y+3*y)再与源程序合并说明:⑴宏名一般用大写表示,以便与变量名区分。
第九章编译预处理与带参数的主函数第九章编译预处理与带参数的主函数一、单项选择题1.C程序中,以#号带头的行是预编译(A)。
A.命令B.语句C.函数D.字符串2.下列正确的预编译命令是(B)。
A.define PI 3.14159B.#define p(a,b) strcpy(a,b)C. #include stdio.hD. # define PI3.141593.下列命令或语句中,正确的是(C)。
A.#define MYNAME= “ABC”B.#include stdio.hC. for(i=0;i<10;i++);D.struct int stu{int name};4.下列命令或语句中,正确的是(A)。
A.#define PI 3.14159B. include “stdio.h”C.for(i=0,i<10,i++)a++D.static struct {int i;}b={2};5.下列命令或语句中,错误的是(B)。
A. #define PI 3.14159B.#includeC.if(2);D.for(; ;) if(1) break;6.定义带参数的宏计算两式乘积(如x2+3x-5与x-6),下列定义中哪个是正确的(C)。
A.#define muit(u,v)u*vB.#define muit(u,v)u*v;C.#define muit(u,v)(u)*(v)D.#define muit(u,v)=(u)*(v)7.宏定义#define div(a,b) a/b的引用div(x+5,y-5)替换展开后是(A)。
A.x+5/y-5B.x+5/y-5;C.(x+5)/(y-5)D.(x+5)/(y-5);8.定义带参数的宏“#define jh(a,b,t)t=a;a=b;b=t”,使两个参数a、b的值交换,下列表述中哪个是正确的(D)。
A.不定义参数a和b将导致编译错误B.不定义参数a、b、t将导致编译错误C.不定义参数t将导致运行错误D.不必定义参数a、b、t类型9.设有宏定义#define AREA(a,b) a*b,则正确的“宏调用”是(D)。
编译预处理习题与答案第九章编译预处理9.1 选择题【题9.1】以下叙述中不正确的是。
A)预处理命令⾏都必须以#号开始B)在程序中凡是以#号开始的语句⾏都是预处理命令⾏C)C程序在执⾏过程中对预处理命令⾏进⾏处理D)以下是正确的宏定义#define IBM_PC【题9.2】以下叙述中正确的是。
A)在程序的⼀⾏上可以出现多个有效的预处理命令⾏B)使⽤带参的宏时,参数的类型应与宏定义时的⼀致C)宏替换不占⽤运⾏时间,只占编译时间D)在以下定义中C R是称为“宏名”的标识符#define C R 045【题9.3】请读程序:#define ADD(x) x+xmain(){int m=1,n=2,k=3;int sum=ADD(m+n)*k;printf(“sum=%d”,sum);}上⾯程序的运⾏结果是。
A)sum=9 B)sum=10 C)sum=12 D)sum=18【题9.4】以下程序的运⾏结果是。
#define MIN(x,y) (x)<(y)?(x):(y)main(){int i=10,j=15,k;k=10*MIN(i,j);printf(“%d\n”,k);}A)常量B)单精度数C)双精度数D)字符串【题9.6】以下程序的运⾏结果是。
#include#define FUDGE(y) 2.84+y#define PR(a) printf(“%d”,(int)(a))#define PRINT1(a) PR(a); putchar(‘\n’)main(){int x=2;PRINT1(FUDGE(5)*x);}A)11 B)12 C)13 D)15【题9.7】以下有关宏替换的叙述不正确的是。
A)宏替换不占⽤运⾏时间B)宏名⽆类型C)宏替换只是字符替换D)宏名必须⽤⼤写字母表⽰【题9.8】C语⾔的编译系统对宏命令的处理是。
A)在程序运⾏时进⾏的B)在程序连接时进⾏的C)和C程序中的其它语句同时进⾏编译的D)在对源程序中其它成份正式编译之前进⾏的【题9.9】若有宏定义如下:#define X 5#define Y X+1#define Z Y*X/2则执⾏以下printf语句后,输出结果是。
C/C++程序设计第9 章编译预处理计算机学院C/C++程序设计课程组C/C++程序设计第1 章主要内容C语言有三种预处理命令,分别是宏定义、文件包含和条件编译。
本章主要介绍宏定义与引用、文件包含处理和条件编译命令。
C/C++程序设计9.1 宏定义所谓“宏”就是将一个标识符定义成一个字符串符,完成定义的命令称为“宏定义”或预处理命令,其中,“标识符”称为“宏名”;当定义了宏名后,在源程序中就可以“引用宏”。
带有宏的程序,源程序开始编译前,系统将会把源程序清单中所引用的宏名替换成对应的一串字符,然后再编译源程序。
替换的过程称为“宏替换”,也称为“宏展开”。
9.1.1 不带参数的宏定义#define 宏名字符串关于宏定义注意以下几点:(1)字符串不带双引号。
(2)宏名的前后应有空格,以便准确的辨认宏名。
(3)C预处理命令都是以换行符(\n)结尾的,即每条C预处理命令都占用一行;本命令不是语句,其后不要跟分号(;)。
(4)在字符串中如果出现运算符,要注意替换后的结果,通常可以在合适的位置上加括号。
C/C++程序设计【例9.1】求园的周长、面积和球的体积。
#include <stdio.h>#define PI 3.14159//定义宏名PI为3.14159 void main( ) {float l,s,r,v;printf("input redius:\n" );scanf("%f",&r);l=2.0*PI*r;s=P I*r*r;v=3.0/4*PI*r*r*r; // 宏展开后为:v=3.0/4*3.14159*r*r*r printf("l=%10.4f\ns=%10.4f\nv=%10.4f\n",l,s,v);}(5) 宏定义也有定义域,它的定义域是从开始定义处到本程序文件的结尾。
所以一般都将宏定义放在源程序开头。
第九章编译预处理与带参数的主函数一、单项选择题1.C程序中,以#号带头的行是预编译(A)。
A.命令B.语句C.函数D.字符串2.下列正确的预编译命令是(B)。
A.define PI 3.14159B.#define p(a,b) strcpy(a,b)C. #include stdio.hD. # define PI3.141593.下列命令或语句中,正确的是(C)。
A.#define MYNAME= “ABC”B.#include stdio.hC. for(i=0;i<10;i++);D.struct int stu{int name};4.下列命令或语句中,正确的是(A)。
A.#define PI 3.14159B. include “stdio.h”C.for(i=0,i<10,i++)a++D.static struct {int i;}b={2};5.下列命令或语句中,错误的是(B)。
A. #define PI 3.14159B.#include<math.h>C.if(2);D.for(; ;) if(1) break;6.定义带参数的宏计算两式乘积(如x2+3x-5与x-6),下列定义中哪个是正确的(C)。
A.#define muit(u,v)u*vB.#define muit(u,v)u*v;C.#define muit(u,v)(u)*(v)D.#define muit(u,v)=(u)*(v)7.宏定义#define div(a,b) a/b的引用div(x+5,y-5)替换展开后是(A)。
A.x+5/y-5B.x+5/y-5;C.(x+5)/(y-5)D.(x+5)/(y-5);8.定义带参数的宏“#define jh(a,b,t)t=a;a=b;b=t”,使两个参数a、b的值交换,下列表述中哪个是正确的(D)。
A.不定义参数a和b将导致编译错误B.不定义参数a、b、t将导致编译错误C.不定义参数t将导致运行错误D.不必定义参数a、b、t类型9.设有宏定义#define AREA(a,b) a*b,则正确的“宏调用”是(D)。
A.s=AREA(r*r)B.s=AREA(x*y)C.s=AREAD.s=c*AREA((x+3.5),(y+4.1))10.设有以下宏定义,则执行语句z=2*(N+Y(5+1));后,z的值为(C)。
#define N 3#define Y(n) ((N+1)*n)A.出错B.42C.48D.5411.设有以下宏定义,int x,m=5, n=1时,执行语句IFABC(m+n,m,x);后,x的值为(B)。
#define IFABC(a,b,c) c=a>b?a:bA.5B.6C.11D.出错12.以下程序中的for循环执行的次数是(C)。
#include “stdio.h”#define N 2#define M N+1# define NUM (M+1)*M/2void main( ){ int i,n=0;for(i=1;i<=NUM;i++){n++; printf(“%d”,n);}printf(“\n”);}A.5B.6C.8D.913.设有一程序编译连接成目标程序名为psl.exe,如果输入如下的命令:psl 123 456 AAA ↙(其中的↙表示回车),则程序运行时,会出错的语句是(B)。
A.printf(“%d”,argc);B.printf(“%ds”,argv[4]);C.printf(“%s”,argv[3]);D.printf(“%s”,argv[2]);14.格式1 #include “文件名”格式2 #include <文件名>下面4个结论,正确的是(D)。
A.格式1中的文件名能带路径,而格式2不能B.格式1中的文件名不能带路径,而格式2可以C.如果被包含文件在当前目录下,两种格式都能用D.如果文件名中不带路径,格式1能搜索当前目标和系统规定的路径中搜索包含文件,而格式2不行。
15.程序ccw1.c中有函数max1( ),程序ccw2.c中有调用函数max1( )的语句,则当程序ccw.c中有包含命令时,正确的写法是(C)。
A.#include “ccw2.c”B.#include <ccw1.c>#include “ccw1.c”#include <ccw2.c>C.#include “ccw1.c”D.两个包含命令次序可以任意#include “ccw2.c”二、填充题1.C程序中,以“#”符号开头的命令是在源程序正式编译前进行处理的,称为编译预处理命令。
2.使用分别编译方法时,在不同的编译单位间能传递的变量和函数是非静态存储类型变量和外部函数。
3.设有定义如下:#include F(N) 2*N,则表达式F(2+3)的值是7 。
4.宏定义语句#define f(x,y) printf(x,y)的引用f(“%d\n”,m);置换展开printf(“%d\n”,m) 。
5.宏定义语句#define f(x,y)fopen(x,y)的引用f(“a.txt”, “rw”);置换展开后为forpen(“a.txt”, “rw”; 。
6.宏定义语句#define f(c) c> ‘A’&&c<= ‘Z’的引用f(x[i])置换展开后为x[i]>= ‘A’&&x[i]<= ‘Z’。
7.设有如下的宏定义:#include P(r,a) printf(r,a)当程序中执行“P(str,3);”语句后会输出i=3,则在程序中应有定义语句char *str= “i=%d\n”;8.设有下列程序:#include <stdio.h>void main (int argc, char *argv[ ]){ while (--argc>c) printf(“%s”,argv[argc]);printf(“\n”);}假定上述程序编译连接成目标程序名为p.exe,如果输入如下的命令:p 123 AAA BBB ↙(其中的↙表示回车)则输出结果是BBB AAA 123 命令行中有4个字符串(包括p),因此,argc=4, argv[0]→p, argv[1]→123, argv[2]→AAA, argv[3]→BBB。
三、程序分析题1.阅读下面程序,写出运行结果。
#define M 5#define N M*3+4#define MN N*Mvoid main( ){ printf(“%d,%d\n”,2*MN, MN/2);}程序运行结果为:50 252.阅读下面程序,写出运行结果。
#define EXCH(a,b) { int t; t=a;a=b;b=t}void main( ){ int x=5,y=9;EXCH(x,y);printf(“x=%d,y=%d\m”,x,y);}程序运行结果为:x=9, y=53.阅读下面程序,写出运行结果。
#define PR(ar) printf(“%d,”,ar)void main( ){ int j,a[]={1,3,5,7,9,11,13,15},*p=a+5;for(j=3;j;j--)switch(j){ case 1:case 2:PR(*p++);break;case 3: PR(*--p));}}程序运行结果为:9 9 114.阅读下面程序,写出运行结果。
#include <stdio.h> 输出结果:x|y&z=3#define PR(x,y)printf(“%s=\t%d\n”,x,y) x^y&~z=1void main( ) x&y&z=0{ int x=03,y=02,z=01; !x|x=1PR(“x|y&z”,(x|y&z);PR(“x^y&~z”,x^y&~z); -x|x=-1PR(“x&y&z”,x&y&z);x=1;y=-1;PR(“!x|x”,!x|x);PR(“~x|x”,~x|x);}5.设下面的程序经编译连接后生成的目标程序名为:ABC.EXE,写出输入以下命令行后的输出:ABC FILE1 FTLE2↙(其中的↙表示回车)#include “stdio.h ”void main(int argc, char *argv[]){ int i;printf(“%d\n ”,argc);for(i=0;i<argc;i++) printf(“%s ”,argv[i])printf(“\n ”);}程序输出:3ABC FILE1 FILE26.读程序,写功能。
#include <stdio.h>void main(int argc,char*argv[]){ FILE *f1,*f2;char ch;if(argc<3){printf(“Parameter missing!\n ”);exit(0);}if(((f1=fopen(argv[1], “r ”))= =NULL||(f2=fopen(argv[2], “w ”))= =NULL{printf(“Can not open file!\n ”);exit(0);}while(!feof(f1)) fputc(fgetc(f1),f2);fclose(f1); fclose(f2);}该程序的功能是:在用命令行的形式运行本程序时,必须在程序名后加二个参数,这二个参数分别表示磁盘上的二个文件名。
程序运行后,能把第一个文件的内容拷贝到第二个文件。
如果命令行缺少参数或文件打不开,程序终止运行并显示出错情况。
四、程序设计题1.三角形的面积为))()((c s b s a s s area ---=其中s=0.5(a+b+c), a 、b 、c 为三角形的三边。
定义两个带参的宏,一个用来求s ,另一个用来求area 。
写程序,在程序中用宏来求三角形的周长和面积。
#include <stdio.h>#include <math.h>#define S(a,b,c) 0.5*(a+b+c)#define AREA(a,b,c) sqrt(S(a,b,c)*(S(a,b,c)-a)*S(a,b,c)-b)*S(a,b,c)-c)void main( ){ float a,b,c;printf(“输入三角形的三条边长:a,b,c\n ”);scanf(“%f,%f,%f ”,&a,&b,&c);if((a+b>c)&&(b+c>a)&&(c+a>b)){ printf(“周长=%f\n ”,2*S(a,b,c));printf(“面积=%f\n ”,AREA(a,b,c));}else printf(“a,b,c 的长度不能构成三角形\n ”); }2.设计一个复制文本文件的程序,源文件名和目标文件名随程序执行时输入。