第九章编译预处理
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+x
main()
{
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)10 B)15 C)100 D)150
【题9.5】在宏定义#define PI 3.14159中,用宏名PI代替一个。
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语句后,输出结果是。
int a; a=Y;
printf(“%d\n”,Z);
printf(“%d\n”,--a);
A)7 B)12 C)12 D)7
6 6 5 5
【题9.10】若有以下宏定义如下:
#define N 2
#define Y(n) ((N+1)*n)
则执行语句z=2*(N+Y(5));后的结果是。
A)语句有错误B)z=34 C)z=70 D)z无定值
【题9.11】若有宏定义:#define MOD(x,y) x%y
则执行以下语句后的输出为。
int z,a=15,b=100;
z=MOD(b,a);
printf(“%d\n”,z++);
A)11 B)10 C)6 D)宏定义不合法
【题9.12】以下程序的运行结果是。
#define MAX(A,B) (A)>(B)?(A):(B)
#define PRINT(Y) printf(“Y=%d\t”,Y)
main()
{
int a=1,b=2,c=3,d=4,t;
t=MAX(a+b,c+d);
PRINT(t);
}
A)Y=3 B)存在语法错误C)Y=7 D)Y=0
【题9.13】以下程序段中存在错误的是。
A)#define array_size 100
int array1[array_size];
B)#define PI 3.14159
#define S(r) PI*(r)*(r)
…
area=S(3.2);
C)#define PI 3.14159
#define S(r) PI*(r)*(r)
…
area=S(a+b);
D)#define PI 3.14159
#define S(r) PI*(r)*(r)
…
area=S(a);
【题9.14】请读程序:
#include
#define MUL(x,y) (x)*y
main()
{
int a=3,b=4,c;
c=MUL(a++,b++);
printf(“%d\n”,c);
}
上面程序的输出结果是。
A)12 B)15 C)20 D)16
【题9.15】#define能作简单的替代,用宏替代计算多项式4*x*x+3*x+2之值的函数f,正确的宏定义是。
A)#define f(x) 4*x*x+3*x+2
B)#define f 4*x*x+3*x+2
C)#define f(a) (4*a*a+3*a+2)
D)#define (4*a*a+3*a+2) f(a)
【题9.16】对下面程序段:
#define A 3
#define B(a) ((A+1)*a)
…
x=3*(A+B(7));
正确的判断是。
A)程序错误,不许嵌套宏定义
B)x=93
C)x=21
D)程序错误,宏定义不许有参数
【题9.17】以下程序中,第一个输出值是(1),第二个输出值是(2)。
#include
#define M 3
#define N (M+1)
#define NN N*N/2
main()
{
printf(“%d\n”,NN);
printf(“%d”,5*NN);
}
【1】A)3 B)4 C)6 D)8
【2】A)17 B)18 C)30 D)40
【题9.18】以下程序的输出结果为。
#include
#define F(y) 3.84+y
#define PR(a) printf(“%d”,(int)(a))
#define PRINT(a) PR(a); putchar(‘\n’)
main()
{
int x=2;
PRINT(F(3)*x);
}
A)8 B)9 C)10 D)11
【题9.19】以下程序的输出结果为。
#define PT 5.5
#define S(x) PT*x*x
main()
{
int a=1,b=2;
printf(“%4.1f\n”,S(a+b));
}
A)12.0 B)9.5 C)12.5 D)33.5
【题9.20】以下在任何情况下计算平方数时都不会引起二义性的宏定义是。
A)#define POWER(x) x*x
B)#define POWER(x) (x)*(x)
C)#define POWER(x) (x*x)
D)#define POWER(x) ((x)*(x))
【题9.21】在“文件包含”预处理语句的使用形式中,当#include后面的文件名用“”(双引号)括起时,寻找被包含文件的方式是。
A)直接按系统设定的标准方式搜索目录
B)先在源程序所在目录搜索,再按系统设定的标准方式搜索
C)仅仅搜索源程序所在目录
D)仅仅搜索当前目录
【题9.22】在“文件包含”预处理语句的使用形式中,当#include后面的文件名用< >(尖括号)括起时,寻找被包含文件的方式是。
A)仅仅搜索当前目录
B)仅仅搜索源程序所在目录
C)直接按系统设定的标准方式搜索目录
D)先在源程序所在目录搜索,再按系统设定的标准方式搜索
【题9.23】请读程序:
#define LETTER 0
main()
{
char str[20]=“C Language”,c;
int i;
i=0;
while((c=str[i])!=‘\0’)
{
i++;
#if LETTER
if(c>=‘a’&&c<=‘z’)
c=c-32;
#else
if(c>=‘A’&&c<=‘Z’)
c=c+32;
#endif
printf(“%c”,c);
}
}
上面程序的运行结果是。
A)C Language B)c language C)C LANGUAGE D)c lANGUAGE
【题9.24】以下正确的描述是。
A)C语言的预处理功能是指完成宏替换和包含文件的调用
B)预处理指令只能位于C源程序文件的首部
C)凡是C源程序中行首以“#”标识的控制行都是预处理指令
D)C语言的编译预处理就是对源程序进行初步的语法检查
【题9.25】C语言提供的预处理功能包括条件编译,其基本形式为:
#XXX 标记符
程序段1
#else
程序段2
#endif
这里XXX可以是。
A)define或include B)ifdef或include
C)ifdef或ifndef或define D)ifdef或ifndef或if
9.2 填空题
【题9.26】设有以下宏定义:#define WIDTH 80
#define LENGTH WIDTH+40
则执行赋值语句:v=LENGTH*20; (v为int型变量)后,v的值是。
【题9.27】设有以下宏定义:#define WIDTH 80
#define LENGTH (WIDTH+40)
则执行赋值语句:k=LENGTH*20; (k为int型变量)后,k的值是。
【题9.28】下面程序的运行结果是。
#define DOUBLE(r) r*r
main()
{
int x=1,y=2,t;
t=DOUBLE(x+y);
pri ntf(“%d\n”,t);
}
【题9.29】下面程序的运行结果是。
#define MUL(z) (z)*(z)
main()
printf(“%d\n”,MUL(1+2)+3);
}
【题9.30】下面程序的运行结果是。
#define POWER(x) ((x)*(x))
main()
{
int i=1;
while(i<=4) printf(“%d\t”,POWER(i++));
printf(“\n”);
}
【题9.31】下面程序的运行结果是。
#define EXCH(a,b) { int t; t=a; a=b; b=t; }
main()
{
int x=5,y=9;
EXCH(x,y);
printf(“x=%d,y=%d\n”,x,y);
}
【题9.32】下面程序的运行结果是。
#define MAX(a,b,c) ((a)>(b)?((a)>(c)?(a):(c)):((b)>(c)?(b):(c)))
main()
{
int x,y,z;
x=1; y=2; z=3;
printf(“%d,”,MAX(x,y,z));
printf(“%d,”,MAX(x+y,y,y+x));
printf(“%d\n”,MAX(x,y+z,z));
}
【题9.33】下面程序的运行结果是。
#define SELECT(a,b) a
main()
{
int m=2,n=4;
printf(“%d\n”,SELECT(m,n));
}
【题9.34】下面程序的运行结果是。
#define MAX(a,b) (a>b?a:b)+1
main()
int i=6,j=8,k;
printf(“%d\n”,MAX(i,j));
}
【题9.35】设有宏定义如下:
#define MIN(x,y) (x)<(y)?(x):(y)
#define T(x,y,r) x*r*y/4
则执行以下语句后,s1的值为【1】,s2的值为【2】。
int a=1,b=3,c=5,s1,s2;
s1=MIN(a=b,b-a);
s2=T(a++,a*++b,a+b+c);
【题9.36】请读程序:
#include
#define BOT (-2)
#define TOP (BOT+5)
#define PRI(arg) printf(“%d\n”,arg)
#define FOR(arg) for(;(arg);(arg)--)
main()
{
int i=BOT,j=TOP;
FOR(j)
switch(j)
{
case 1: PRI(i++);
case 2: PRI(j); break;
default: PRI(i);
}
}
执行FOR循环时,j的初值是【1】,终值是【2】。
【题9.37】下面程序的运行结果是。
#define PR(ar) printf(“%d”,ar)
main()
{
int j,a[]={1,3,5,7,9,11,13,15},i=5;
for(j=3;j;j--)
{
switch(j)
{
case 1:
case 2: PR(a[i++]); break;
case 3: PR(a[--i]);
}
}
}
【题9.38】下面程序的运行结果是。
#define PRI printf
#define NL “\n”
#define D “%d”
#define D1 D NL
#define D2 D D NL
#define D3 D D D NL
#define D4 D D D D NL
#define S “%s”
main()
{
int a,b,c,d;
char string[]=“TABLE”;
a=1; b=2; c=3; d=4;
PRI(D1,a);
PRI(D2,a,b);
PRI(D3,a,b,c);
PRI(D4,a,b,c,d);
PRI(S,string);
}
【题9.39】以下程序的运行结果是。
#define A 4
#define B(x) A*x/2
main()
{
float c,a=4.5;
c=B(a);
printf(“%5.1f\n”,c);
}
【题9.40】以下程序的运行结果是。
#include
#define sw(x,y) { x^=y; y^=x; x^=y; }
main()
{
int a=10,b=01;
sw(a,b);
printf(“%d,%d\n”,a,b);
}
【题9.41】以下程序的输出结果是。
#define PR(a) printf(“%d\t”,(int)(a))
#define PRINT(a) PR(a); printf(“ok!”)
main()
{
int i,a=1;
for(i=0;i<3;i++)
PRINT(a+i);
printf(“\n”);
}
【题9.42】以下程序的输出结果是。
main()
{
int b=5;
#define b2
#define f(x) b*(x)
int y=3;
printf(“%d\n”,f(y+1));
#undef b
printf(“%d\n”,f(y+1));
#define b3
printf(“%d\n”,f(y+1));
}
【题9.43】设有以下程序,为使之正确运行,请在【】中填入应包含的命令行。(注:try_me()函数在a:\myfile.txt中有定义。)
【】
main()
{
printf(“\n”);
try_me();
printf(“\n”);
}
【题9.44】设有以下程序,为使之正确运行,请在【】中填入应包含的命令行。
/* a.c */
【1】
【2】
main()
{
printf(“\n”);
try_me(); /* 函数调用 */
printf(“\n”);
}
注:try_me()函数在myfile.txt中有定义,其内容如下:
/* myfile.txt */
try_me()
{
char c;
if((c=getchar())!=‘\n’)
try_me();
putchar(c);
}
【题9.45】设有以下程序,为使之正确运行,请在【】中填入应包含的命令行。
【】
main()
{
int x=2,y=3;
printf(“%d\n”,pow(x,y));
}
【题9.46】以下程序的运行结果是。
main()
{
int a=10,b=20,c;
c=a/b;
#ifdef DEBUG
printf(“a=%d,b=%d,”,a,b);
#endif
printf(“c=%d\n”,c);
}
【题9.47】以下程序的运行结果是。
#define DEBUG
main()
{
int a=14,b=15,c;
c=a/b;
#ifdef DEBUG
printf(“a=%o,b=%o,”,a,b);
#endif
printf(“c=%d\n”,c);
}
【题9.48】以下程序的运行结果是。
#define DEBUG
main()
{
int a=20,b=10,c;
c=a/b;
#ifndef DEBUG
printf(“a=%o,b=%o,”,a,b);
#endif
printf(“c=%d\n”,c);
}
9.3 编程题
【题9.49】输入两个整数,求它们相除的余数。用带参的宏来编程实现。
【题9.50】试定义一个带参的宏swap(x,y),以实现两个整数之间的交换,并利用它将一维数组a和b的值进行交换。
C语言预处理命令之条件编译(#ifdef,#else,#endif,#if等) 预处理过程扫描源代码,对其进行初步的转换,产生新的源代码提供给编译器。可见预处理过程先于编译器对源代码进行处理。 在C语言中,并没有任何内在的机制来完成如下一些功能:在编译时包含其他源文件、定义宏、根据条件决定编译时是否包含某些代码。要完成这些工作,就需要使用预处理程序。尽管在目前绝大多数编译器都包含了预处理程序,但通常认为它们是独立于编译器的。预处理过程读入源代码,检查包含预处理指令的语句和宏定义,并对源代码进行响应的转换。预处理过程还会删除程序中的注释和多余的空白字符。 预处理指令是以#号开头的代码行。#号必须是该行除了任何空白字符外的第一个字符。#后是指令关键字,在关键字和#号之间允许存在任意个数的空白字符。整行语句构成了一条预处理指令,该指令将在编译器进行编译之前对源代码做某些转换。下面是部分预处理指令: 指令用途 #空指令,无任何效果 #include包含一个源代码文件 #define定义宏 #undef取消已定义的宏 #if如果给定条件为真,则编译下面代码 #ifdef如果宏已经定义,则编译下面代码 #ifndef如果宏没有定义,则编译下面代码 #elif如果前面的#if给定条件不为真,当前条件为真,则编译下面代码 #endif结束一个#if……#else条件编译块 #error停止编译并显示错误信息 一、文件包含 #include预处理指令的作用是在指令处展开被包含的文件。包含可以是多重的,也就是说一个被包含的文件中还可以包含其他文件。标准C编译器至少支持八重嵌套包含。 预处理过程不检查在转换单元中是否已经包含了某个文件并阻止对它的多次包含。这样就可以在多次包含同一个头文件时,通过给定编译时的条件来达到不同的效果。例如: #defineAAA #include"t.c" #undefAAA #include"t.c" 为了避免那些只能包含一次的头文件被多次包含,可以在头文件中用编译时条件来进行控制。例如: /*my.h*/ #ifndefMY_H
第九章编译预处理 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+x main() { 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)10 B)15 C)100 D)150 【题9.5】在宏定义#define PI 3.14159中,用宏名PI代替一个。 A)常量B)单精度数C)双精度数D)字符串
【题9.6】以下程序的运行结果是。 #include
C语言1-3章习题(部分) 一、判断题 1、C程序的注释部分可以出现在程序的任何位置,它对程序的编译与运行不 起任何作用。但就是可以增加程序的可读性。(√ ) 2、自增运算符(++)或自减运算符(--)只能用于变量,不能用于常量或表达式。 ( √) 3、c程序可由若干个源程序文件组成。( √) 4、宏替换时先求出实参表达式的值,然后代入形参运算求值。(×) 5、用%s格式符输出字符串时,输出字符不包括结束符’\0’。(√ ) 6、#define指令就是一个预处理编译器指令,不就是程序语句,因此,#define不 能用分号结尾。(√ ) 7、一个程序应包括对数据的描述与对操作的描述,其中对数据的描述也就就 是算法。(× ) 8、在C程序中对用到的所有数据都必须指定其数据类型。(√ ) 9、一个实型变量的值肯定就是精确的。(× ) 10、do-while循环的while后的分号可以省略。(× ) 11、c语言中函数定义不允许嵌套,但调用可嵌套。(√ ) 12、与其她语句一样,预处理命令必须以分号结尾。(× ) 13、在一个源程序中,main函数的位置必须在最开始。(×) 14、函数可以调用自己。(√) 15、scanf函数一次只能读取一个值。 (×) 16、一个函数中可以有一个以上的return语句,执行到哪一个return语句,哪一 个语句起作用。(√) 17、字符串“a”只包含1个字符。( ×) 18、在C语言中,要求对所有用到的变量作强制定义,也就就是“先定义,后使 用”。( √) 19、C程序中,函数的定义可以嵌套,但函数的调用不可以嵌套。(×) 20、C程序中,无论就是整数还就是实数,都能被准确无误地表示。(×) 21、一个C源程序中有且仅有一个main()函数。(√) 22、语句可以用分号或句号结尾。(×)
编译预处理习题 一.单项选择题 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
第九章编译预处理 一、单选题 1.以下对宏替换的叙述不正确的是 A)宏替换只是字符的替换B)宏替换不占运行时间 C)宏名无类型,其参数也无类型 D)带参的宏替换在替换时,先求出实参表达式的值,然后代入形参运算求值2.宏定义#define PI 3.14中的宏名PI代替 A)一个单精度实数)B)一个双精度实数 C)一个字符串 D)不确定类型的数 3.有以下宏定义 #define k 2 #define X(k) ((k+1)*k) 当C程序中的语句y = 2 * (K + X(5));被执行后, A)y中的值不确定 B)y中的值为65 C)语句报错 D)y中的值为34 4.以下程序的输出结果是 #define MIN(x, y) (x) < (y) ? (x) : (y) main() { int i , j, k; i = 10; j = 15; k = 10 * MIN(i, j); printf(“%d\n”, k); }
A)15 B)100 C)10 D)150 5.以下程序中的for循环执行的次数是 #define N 2 #define M N + 1 #define NUM (M + 1) * M / 2 main() { int i; for(i = 1; i <= NUM; i++); pritnf(“%d\n”, i ); } A)5 B)6 C)8 D)9 6.以下程序的输出结果是 #include “stdio.h” #define FUDGF(y) 2.84 + y #define PR(a) printf(“%d”, (int) ( a ) ) #define PRINT1(a) PR(a); putchar(‘\n’) main() { int x = 2; PRINTF1(FUDGF(5) * X); } A)11 B)12 C)13 D)15 7.以下程序的输出结果是 #define FMT “%d,” main()
第八章函数 一、选择题 1、以下正确的函数定义是(A ) A) double fun(int x,int y) { } B) double fun(int x;int y) { } C) float fun(int x;y) { } D) float fun(int x,y) { } 2、C语言中,函数返回值的类型是由( D )决定。 A)主调函数的类型 B)return语句中表达式的类型 C)由系统临时指定 D)定义该函数时所指定的函数类型 3、下列有关函数的说法正确的是( D )。 A)在C语言中,若对函数类型未加说明,则系统隐含类型为void。 B)C函数必须有返回值,否则无法使用。 C)C函数既可以嵌套定义,又可以可递归调用。 D)C函数中,形式参数必须指定为确定的类型。 4、用一维数组名作函数的实际参数,则传递给形式参数的是(A ) A)数组首元素的地址 B)数组中第一个元素的值 C)数组中元素的个数 D)数组中全部元素的值 5、若已定义的函数有返回值,则有关该函数调用的叙述中错误的是(B ) A)调用可以作为独立的语句存在 B)调用可以作为一个函数的形参 C)调用可以作为一个函数的实参 D)调用可以出现在表达式中 6、关于C语言中return语句正确的说法是(C ) A)只能在主函数中出现 B)在每个函数中都必须出现 C)可以在一个函数中出现多次 D)只能在除主函数之外的函数中出现 7、如果在程序中使用了C库函数中的字符串函数,则应在源程序中使用的文件包含命令是(D ) A)#include
第九章编译预处理 课题:第九章编译预处理 教学目的:1、了解预处理的概念及特点 2、掌握有参宏与无参宏的定义及使用,领会文件包含的使用及效果 教学重点:教学难点:掌握宏的使用,文件包含有参宏与无参宏的使用 步骤一复习引导 ANSI C标准规定可以在C源程序中加入一些“预处理命令”,以改进程序设计环境,提高编程效率。 这些预处理命令是由ANSI C统一规定的,但它不是C语言本身的组成部分,不能直接对它们进行编译。必须在对程序进行通常的编译之前,先对程序中这些特殊的命令进行“预处理”,即根据预处理命令对程序作相应的处理。经过预处理后程序不再包括预处理命令了,最后再由编译程序对预处理后的源程序进行通常的编译处理,得到可供执行的目标代码。 步骤二讲授新课 C语言与其他高级语言的一个重要区别是可以使用预处理命令和具有预处理的功能。C 提供的预处理功能主要有以下三种:宏定义、文件包含、条件编译。 分别用宏定义命令、文件包含命令、条件编译命令来实现。为了与一般C语句相区别,这些命令以符号“ #” 开头。 §9.1宏定义 宏:代表一个字符串的标识符。 宏名:被定义为“宏”的标识符。 宏代换(展开):在编译预处理时,对程序中所有出现的“宏名”,用宏定义中的字符串去代换的过程。 一、不带参数的宏定义 一般形式:#define 标识符字符串 #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(“%10.4f,%10.4f,%10.4\n”, l, s, v); }
第9章预处理命令 宏定义不是C语句,所以不能在行尾加分号。如果加了分号则会连分号一起进行臵换。 可以用#undef命令终止宏定义的作用域。 对程序中用“”括起来的内容(即字符串内的字符),即使与宏名相同,也不进行臵换。宏定义只做字符替换,不分配内存空间。 宏名不是变量,不分配存储空间,也不能对其进行赋值。 在宏展开时,预处理程序仅对宏名作简单的字符串替换,不作任何检查。 在进行宏定义时,可以引用已定义的宏名 无参宏定义的一般格式: #define 标识符字符串 将这个标识符(名字)称为“宏名”,在用预编译时将宏名替换成字符串的过程称为“宏展开”。#define是宏定义命令。 带参宏定义的一般格式: #define 宏名(形参表)字符串 带参宏的调用和宏展开: 调用格式:宏名(实参表); 宏展开(又称为宏替换)的方法:用宏调用提供的实参直接臵换宏定义中相应的形参,非形参字符保持不变。 定义有参宏时,宏名与左圆括号之间不能留有空格。否则,C编译系统会将空格以后的所有字符均作为替代字符串,而将该宏视为无参宏。 有参宏的展开,只是将实参作为字符串,简单地臵换形参字符串,而不做任何语法检查。 为了避免出错,可以在所有形参外,甚至整个字符串外,均加上一对圆括号。 如: #define S(r) 3.14*(r)*(r) 则:area=S(a+b); 展开后为: area=3.14*(a+b)*(a+b); 调用有参函数时,是先求出实参的值,然后再复制一份给形参。而展开有参宏时,只是将实参简单地臵换形参。函数调用是在程序运行时处理的,为形参分配临时的内存单元;而宏展开则是在编译前进行的,在展开时不分配内存单元,不进行值的传递,也没有“返回值”的概念。调用函数只可得到一个返回值,而用宏可以设法得到几个结果。 在有参函数中,形参都是有类型的,所以要求实参的类型与其一致;而在有参宏中,形参和宏名都没有类型,只是一个简单的符号代表,因此,宏定义时,字符串可以是任何类型的数据。 使用宏次数多时,宏展开后源程序变长,因为每展开一次都是程序增长,而函数调用不会使源程序变长。 宏替换不占用运行时间,只占编译时间。而函数调用则占用运行时间(分配单元、保留现场、值传递、返回)。 在程序中如果有带实参的宏,则按#define命令行中指定的字符串从左到右进行臵换。如果字符串中包含宏中的形参,则将程序语句中相应的实参(可以是常量、变量或表达式)代替形参。如果宏定义中的字符串中的字符不是参数字符,则保留。
第13章编译预处理和动态存储分配 1.以下叙述中正确的是()。 A.在C语言中,预处理命令行都以“#”开头 B.预处理命令行必须位于C源程序的起始位置 C.#include
【解析】通常,预处理命令位于源文件的开头,也可以写在函数与函数之间。答案选择A选项。 3.以下关于宏的叙述中正确的是()。 A.宏名必须用大写字母表示 B.宏定义必须位于源程序中所有语句之间 C.宏替换没有数据类型限制 D.宏调用比函数调用耗费时间 【答案】C 【解析】A项错误,在C语言中,宏名可以是任何合法的C语言标识符,只不过通常习惯用大写字母;B项错误,宏可以根据需要出现在程序的任何一行的开始部位;D项错误,宏定义是“编译预处理”命令,它们的替换过程在编译时期就已经完成了,因此不会占有程序运行的时间。答案选择C选项。 4.以下关于宏的叙述错误的是()。 A.宏替换不具有计算功能 B.宏是一种预处理指令 C.宏名必须用大写字母构成 D.宏替换不占用运行时间 【答案】C 【解析】宏名习惯采用大写字母,以便与一般变量区别,但是并没有规定一定要用大写字母,答案选择C选项。
一、选择题 1.下列关于对象的描述中,错误的是___________。 A.对象是类的别名 B.对象是类的实例 C.一个类可以定义多个对象 D.对象之间通过消息进行通信 2.在对字符数组进行初始化时,___________是正确的。 A.char s1[]=”abcd”; B.char s2[3]=”xyz”; C.char s3[][3]={‘a’,‘x’,‘y’}; D.char s4[2][3]={”xyz”,”mnp”}; 3.联合成员的地址值和所占的字节数___________。 A.都相同 B.都不同 C.前者相同,后者不同 D.前者不同,后者相同 4.文件包含命令中被包含的文件的扩展名___________。 A.必须为.h B.不能用.h C.必须是.c D.不一定是.h 5.下列while循环的次数是___________。 while(int i=0) i--; A.0 B.1 C.5 D.无限 6.在函数说明中,下列___________项是不必要的。 A.函数的类型 B.函数参数类型和名字 C.函数名字 D.返回值表达式 7.在传值调用中,要求___________。 A.形参和实参类型类型任意,个数相等 B.实参和形参类型都完全一致,个数相等 C.实参和形参对应的类型一致,个数相等 D.实参和形参对应的类型一致,个数相等 8.在一个函数中,要求通过函数来实现一种不太复杂的功能,并且要求加快执行速度,选用_____比较合适。 A.内联函数 B.重载函数 C.递归调用 D.嵌套调用 9.下列有关对函数模板参数的描述,错误的是___________。 A.函数模板是一组函数的样板 B.函数模板是定义重载函数的一种工具 C.模板函数是函数模板的一个实例 D.模板函数在编译时不生成可执行代码 10.下列各种函数中,___________不是类的成员函数。 A.构造函数 B.析构函数 C.友元函数 D.复制构造函数 11.___________不是构造函数的特征。 A.构造函数的函数名与类名相同 B.构造函数可以重载 C.构造函数可以设置默认参数 D.构造函数必须指定类型说明 12.下述静态数据成员的特性中,___________是错误的。 A.说明静态数据成员时前边要加修饰符static B.静态数据成员要在类体外进行初始化 C.引用静态数据成员时,要在静态数据成员名前加<类名>和作用域运算符 D.静态数据成员不是所有对象所共用的 13.关于delete运算符的下列描述中,___________是错误的。 A.它必须用于new返回的指针 B.它也适用于空指针 C.对一个指针可以使用多次该运算符 D.指针名前只用一对方括号符,不管所删除数组的维数 14.派生类的构造函数的成员初始化值表中,不能包含___________。 A.基类的构造函数 B.派生类中子对象的初始化 C.派生类中静态数据成员的初始化 D.派生类中一般数据成员的初始化 15.下列运算符中,在C++语言中不能重载的是_______________。 A. * B. >= C. :: D. / 16.下列关于面向对象语言的基本要素的描述中,正确的是___________。 A.封装性和重载性 B.多态性和继承性 C.继承性和聚合性 D.封装性和继承性 17.在int b[][3]={{1},{3,2},{4,5,6},{0}};中b[2][2]的值是___________。 A.0 B.5 C.6 D.2 18.下列各运算符中,___________运算的结合性是从左到右。 A.三目 B.赋值 C.比较 D.单目 19.预处理命令在程序中都是以___________开关的。 A. * B. # C. : D. / 20.下列for循环的次数为___________。 for(int i(0),x=0;!x&&i<=5;i++);
国家二级C语言机试(编译预处理和指针)模拟试卷7 (总分:56.00,做题时间:90分钟) 一、选择题(总题数:28,分数:56.00) 1.有以下程序:#include<stdio.h>void main() void fun(char*c) {char s[81];{while(*c) gets(s);fun(s);puts(s); {if(*c>='a'&&*c<='z')*c=*c-('a'-'A'); } c++: }} 当执行程序时从键盘上输入Hello Beijing<回车>,则程序的输出结果是 (分数:2.00) A.HELLO BEIJING √ B.Hello Beijing C.hello Beijing D.hELLO Beijing 解析:解析:子函数fun的功能是把小写字母转换成大写字母,所以程序的输出结果为选项A)。 2.有以下程序#include<stdio.h>void f(int*p,int*q) void f(int*p,int*q);{ main() p==p+1;*q=*q+1; { int m=1,n=2,*r=&m; } f(r,&n);printf("%d,%d",m,n); }程序运行后的输出结果是 (分数:2.00) A.2,3 B.1,3 √ C.1,4 D.1,2 解析:解析:本题考查函数的调用与指针。fun()函数的作用是:使指针p指向原来所指变量的下一个变量,使q指针指向的值加1。主函数中,指针r指向m,调用fun()函数的结果是,使r指向地址位于m后面的变量,使位丁n的地址上的变量(就是n)的值加1,因此,结果为1,3。 3.有以下程序 #include<stdio.h> main() void fun(int*a,int*b) { int x=3,y=5,*p=&x,*q=&y;{ int*c;fun(p,q);printf("%d,%d,",*p,*q);c=a;a=b;b=c;} fun(&x,&y);printf("%d,%d\n",*p,*q);}程序运行后的输出结果是 (分数:2.00) A.3,5,5,3 B.3,5,3,5 √ C.5,3,3,5 D.5,3,5,3 解析:解析:本题考查函数的调用与指针。p和q分别为指向x和y的指针,函数fun()的两个形参均为指针型,主要功能为交换两个指针的指向,当调用结束以后,该操作不能返回主函数。而主函数中,fun(p,q)、fun(&x,&y)的实参均为x与y的地址,因此,两者结果相同,并且两者指针指向的值不能变化。 4.有下列程序:void f(int b[]) {int I;for(i=2;i<6;i++)b[i]*=2;} main() {int a[10]={1,2,3,4,5,6,7,8,9,10},i;f(a);for(i=0;i<10,i++)printf("%d,",a[i]);}程序运行后的输出结果是 (分数:2.00) A.1,2,3,4,5,6,7,8,9,10, B.1,2,3,4,10,12,14,16,9,10, C.1,2,6,8,10,12,7,8,9,10,√ D.1,2,6,8,10,12,14,16,9,10, 解析:解析:函数void f(int b[])的功能是对数组b[]中第2个到第5个元素的值逐个扩大2倍。所以在main()函数中,f(a)语句的作用是对数组a[10]中从a[2]到a[5]的各个数字乘以2,因而数组a[10]的元素就变成了{1,2,6,8,10,12,7,8,9,10}。 5.有以下程序 #include<stdio.h> int fun(char s[]) main() {int n==0; {char s[10]={'6','1','*','4','*','9','*','0','*'};while(*s<='9'&&*s>='0') printf("%d\n",fun(s));{n=10*n+*s
1.以下叙述中正确的是()。 A) 在C语言中,预处理命令行都以"#"开头 B) 预处理命令行必须位于C源程序的起始位置 C) #include 编译预处理 1概述: 编译预处理是在源程序正式编译前的处理。预处理名令一般写在程序的最开头,并且以#开头的命令。编译预处理命令不是c语言本身的组成部分,也不属于c语句,不能直接对他们编译。在代码的正式编译之前(编译即指转换成二进制的机器语言),系统先对预处理命令进行处理,然后再由编译程序对处理后的程序进行正常的编译,得到可执行文件。即对一个源程序进行编译时,系统会先引用预处理命令对源程序中的预处理部分进行处理,然后自动进行源程序的编译。 C语言提供3中预处理命令:宏替换文件包含条件编译他们均以#开头,并独占一个书写行,语句结尾不用;作为结束符。 2 宏替换(宏定义) 分为两种: (1)无参数的宏替换 是指用一个指定的标识符(即宏名)来代表程序中的一个字符串。 格式#define 宏名字符串 如#define SIZE 10 SIZE为宏名,此命令执行后,预处理程序对源程序中的所有SIZE的标识符用10替换。 说明: ①宏名一般用大写字符,但不是必须的。 ②字符串可以是常量,表达式,语句或多条语句可以是任何语句如输出语句,赋值语句等等 ③宏定义与变量定义不同,只是做字符的简单替换,不占内存空间,也不赋值 ④结尾不能加;,如果加了;,则;也作为字符串的一部分,一同参与替换。 ⑤宏定义允许嵌套定义,即在宏定义的字符串中可以使用已经定义的宏名。 ⑥宏定义要写在函数之外的,一般写在程序的开头,作用范围是从定义到本文件结束,出来这个文件失去作用了。若要终止其作用,在需要终止前面加#undef 宏名 ⑦若宏名出现在双引号中,则将不会发生宏替换。如printf(“ADD”) ADD是宏,这里不会进行宏替换了 ⑧替换文本不替换用户标识符中的成分宏名ADD不会替换标识符ADDIP中的ADD (2)有参数的宏替换 宏定义中的参数为形式参数,在宏调用中的参数为实际参数。 格式:#define 宏名(形参)字符串 各参数间用,隔开。替换时,不仅要将宏展开,还要将形参替换为实参,但是仅仅是替换而不会去运算得出一个值,这点千万注意。 说明:①注意参数有括号与无括号的区别,这里只是进行直接的替换,不进行其他任何操作。 ②宏替换之后为一个字符串,不是一个值。 ③在带参的宏定义中宏名与(形参)之间不能有空格,否则则被认为是无参宏定义,会将空格后面的字符都当做替换字符串的一部分。如: #define Y (x) x*x K=Y(5); 宏替换为 K=(x) x*x(5) ④这里虽然哟形参与实参但是,与函数调用时不同,这里只是简单的替换,不存在数值传递。形参不占内存,不必进行类型说明。但实参的值是要进行类型说明的。 NOIP复赛复习13预处理与前缀和 一、预处理 所谓预处理,顾名思义,就是事先计算好需要的值或事先处理某些东西,有时候你会发现你做一个题目出现了TLE,原因就是重复的计算会导致效率不高(或者说你的预处理不够“优雅”)。 A、直接把结果预处理 XTUOJ 1052 题意:某一个数字集合定义如下: 1.0属于这个集合; 2.如果x属于这个集合,那么2x+1,3x+1也属于这个集合; 3.集合只包含按增序排列的前100000个元素。 集合按增序排列,根据输入的元素序号,输出对应的元素值。 输入 每行一个整数n(n<100000),表示元素的序号(从0开始记数),如果是-1,则输入结束。 输出 每行输出对应元素的值。 Sample Input 1 2 3 4 5 -1 Sample Output 1 3 4 7 9 分析:很明显,不能也不好直接判断是否存在于这个集合中,只需要把所有存在于这个集合中标记,并且预处理这些元素的序号,之后输出就行了,那么一次预处理便可以知道所有序号对应的元素了。 #include b[0] = 1; for (i = 0; i < MAX; i++) if (b[i] == 1) b[2*i+1] = b[3*i+1] =1; for (i = 0, j = 0; i < 100000; j++) if (b[j] == 1) a[i++] = j; while (cin >> n, n != 1) cout < (1) 下面叙述错误的是()。 A) “#define PRICE 30”命令的作用是定义一个与30等价的符号常量PRICE B) C源程序中加入一些预处理命令是为了改进程序设计环境,提高编程效率 C) “#include <>”命令的作用是在预处理时将文件中的实际内容代替该命令 D) 宏定义也是C语句,必须在行末加分号 (2) 若有定义:#define PI 3,则表达式PI*2*2的值为()。 A) 4 B) 不确定 C) 12 D) 322 (3) 以下程序的运行结果是()。 #define X a+b main( ) { int a=3,b=4,s1; s1=2*X; printf("%d\n",s1); } A) 8 B) 14 C) 10 D) 6 (4) 若有定义#define F 2+3,则表达式F*F的值为()。 A) 13 B) 17 C) 25 D) 11 (5) 下面叙述正确的是()。 A) 宏名必须用大写字母表示 B) 一个源程序只能有一个预编译处理命令行 C) 宏展开不占用运行时间,只占用编译时间 D) 预处理命令也是C语句,必须以分号结束 (6) 下列程序中定义的二维数组a的()。 # define M 3 # define N 4 void main( ) { int a[M][N]; …… } A、第一维和第二维都为4 B、第一维和第二维都为3 C、第一维为4,第二维为3 D、第一维为3,第二维为4 (7) 下列程序的运行结果是()。 # define M 5 # define N M+1 # define NN N*N-M void main( ) { printf(“%d\n”,3*NN); } A、108 B、16 C、21 D、103 (8) 下列叙述正确的是()。 A、宏定义中的宏名必须用大写字母表示 B、为提高程序运行速度可在源程序中加入一些宏定义 C、一个C语言源程序只能有一条预处理命令 D、宏定义不占用程序运行时间,但与程序中的语句一样需要编译 (9) 下列叙述错误的是()。 A、宏定义可出现在源程序中任意合适的位置,且必须在行末加分号 B、预处理命令行都必须以#号开始 C、C语言源程序中加入一些预处理命令是为了改进程序设计环境,提高编程效率 D、# define PER 的作用是用标识符PER代表 (10) 下列程序的运行结果是()。 # define K 5 void main( ) { int a=3,b=4; printf(“%d\n”,K*(a+b)); } A、20 B、15 C、5 D、35 (11) 以下叙述正确的是()。 A) 一个源程序只能由一个编译预处理命令行 B) 编译预处理命令都必须以"#"开头 C) "#define PRICE=30"定义了与30等价的符号常量PRICE 一、单项选择题(总分21) 1. (分值:1.0 分)若有以下定义和语句: int s[4][5],(*p)[5]; p=s; 则指针对s 数组中第三个元素的正确引用形式是()。 A: p[0][3] B: p[1][2] C: p[0][2] D: p[1][3] 序号:92 难度:1 考查点:指针 2. (分值:1.0 分)定义整型变量x,y,z 并赋初始值6 的正确语句是__________。 A: int x=y=z=6; B: int x=6,y=6,z=6; C: x=y=z=6; D: int x,y,z=6; 序号:113 难度:1 考查点:C++基础知识 3. (分值:1.0 分)下列描述中哪个是正确的__________。 A: 私有派生的子类无法访问父类的成员 B: 类A 的私有派生子类的派生类C 无法初始化其祖先类A 对象的属性,因为类A 的成员对类C 是不可访问的 C: 私有派生类不能作为基类派生子类 D: 私有派生类的所有子孙类将无法继续继承该类的成员 序号:126 难度:1 考查点:继承与派生 4. (分值:1.0 分)34 A: 1 B: 2 C: 3 D: 4 序号:140 难度:1 考查点:数组 5. (分值:1.0 分)有以下函数: 以下程序段中不能根据x 值正确计算出y 值的是()。 A: if (x>0) y=1; else if (x==0) y=0; else y= -1; B: y=0;if (x>0) y=1; else if (x<0) y= -1; C: y=0; if (x>=0) if (x>0) y=1; else y= -1; D: if (x>=0) if (x>0) y=1; else y=0; else y= -1; 序号:195 难度:1 考查点:程序控制结构 6. (分值:1.0 分)下面哪一C++ 语言表达式不能正确表示数学关系a<x≤b。选项为 __________。 A: a 第九章编译预处理与带参数的主函数 一、单项选择题 1.C程序中,以#号带头的行是预编译(A)。 A.命令 B.语句 C.函数 D.字符串 2.下列正确的预编译命令是(B)。 A.define PI 3.14159 B.#define p(a,b) strcpy(a,b) C. #include stdio.h D. # define PI3.14159 3.下列命令或语句中,正确的是(C)。 A.#define MYNAME= “ABC” B.#include stdio.h C. for(i=0;i<10;i++); D.struct int stu{int name}; 4.下列命令或语句中,正确的是(A)。 A.#define PI 3.14159 B. include “stdio.h” C.for(i=0,i<10,i++)a++ D.static struct {int i;}b={2}; 5.下列命令或语句中,错误的是(B)。 A. #define PI 3.14159 B.#include编译预处理
NOIP复赛复习13预处理与前缀和
预处理的考试试题
程序设计试卷13
第九章编译预处理与带参数的主函数