当前位置:文档之家› 编译预处理

编译预处理

编译预处理
编译预处理

编译预处理

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)

④这里虽然哟形参与实参但是,与函数调用时不同,这里只是简单的替换,不存在数值传递。形参不占内存,不必进行类型说明。但实参的值是要进行类型说明的。

⑤带参宏与带参函数区别:

带参宏不存在数值传递,不占运行时间,占用编译预处理时间。而函数的调用占运行时间,且时间比宏长。由于宏替换是原样替换,所以宏展开后,源程序会增长,但函数调用则不会。此外,有返回值函数会返回一个数值,无返回值函数进行其他操作。而宏替换只进行替换,不进行计算,赋值等其他任何操作。

⑥仍用#undef 宏名(形参)终止。

3 文件包含

文件包含是指一个源程序文件将另一个指定文件的全部内容包含进来,即将一个文件包含到另一个文件中去,形成一个文件。一般放在C程序的前面。

格式为

#include<文件名>或者#include”文件名”

说明:

①文件名是指在磁盘中的文本文件名字且包含扩展名。扩展名后缀是自己制定的。

②在预编译过程中,预编译程序将用包含的文件中的内容替换此命令行。

③由于文件一般写在开头,也叫头文件

④一个包含命令只能包含指定的一个文件,若有多个文件需要包含时,则要引用多个包含命令。

⑤包含文件可以嵌套,即包含文件中还可以包含其他文件。

⑥包含文件中一般包含一些公用的#define命令行,定义的函数等

⑦在程序开发时,可以把一些宏定义,一些自定义函数分别存入不同的文件中,当需要使用某类宏定义或某函数时,就该函数或宏定义所在的文件包含到程序的开头。

⑧文件包含是很有用的,一个大的程序可以分为多个模块,单独编写成多个文件,再由包含命令合之为一个文件。

C语言预处理命令之条件编译(#ifdef,#else,#endif,#if等)

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 #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++);

C语言13章习题

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、语句可以用分号或句号结尾。(×)

c语言第8章编译预处理及位运算习题答案.doc

编译预处理习题 一.单项选择题 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 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=21 8.有以下程序 # 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); } 程序运行后的输出结果是

第九章 编译预处理

第九章编译预处理 一、单选题 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()

(完整版)C语言8~13章复习题

第八章函数 一、选择题 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 B)#include C)#include D)#include 8、已定义函数如下: int fun(int *p) { return *p;} 则函数的返回值是(C ) A)不确定的值 B)形参p中存放的值 C)形参p所指存储单元的值 D)形参p的地址值 9、以下叙述不正确的是(D ) A)在不同的函数中可以使用同名的变量 B)函数中的形式参数是局部变量 C)在函数内定义的变量只在本函数范围内有效

C语言程序设计教案 第九章 编译预处理

第九章编译预处理 课题:第九章编译预处理 教学目的: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章 预处理命令

第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命令行中指定的字符串从左到右进行臵换。如果字符串中包含宏中的形参,则将程序语句中相应的实参(可以是常量、变量或表达式)代替形参。如果宏定义中的字符串中的字符不是参数字符,则保留。

《二级C语言程序设计》章节题库(编译预处理和动态存储分配)【圣才出品】

第13章编译预处理和动态存储分配 1.以下叙述中正确的是()。 A.在C语言中,预处理命令行都以“#”开头 B.预处理命令行必须位于C源程序的起始位置 C.#include必须放在C程序的开头 D.C语言的预处理不能实现宏定义和条件编译的功能 【答案】A 【解析】“编译预处理”就是在C编译程序对C源程序进行编译前,由编译预处理程序对这些编译预处理命令行进行处理的过程。A项正确,在C语言中,凡是以“#”号开头的行,都称为“编译预处理”命令行。B项错误,预处理命令行可以出现在程序的任何一行的开始部位,其作用一直持续到源文件的末尾;C项错误,#include 可以出现在程序的任意一行的开始部位;D项错误,预处理可以实现宏定义、条件编译和文件包含。答案选择A选项。 2.以下关于编译预处理的叙述中错误的是()。 A.预处理命令行必须位于源程序的开始 B.源程序中凡是以#开始的控制行都是预处理命令行 C.一行上只能有一条有效的预处理命令 D.预处理命令是在程序正式编译之前被处理的 【答案】A

【解析】通常,预处理命令位于源文件的开头,也可以写在函数与函数之间。答案选择A选项。 3.以下关于宏的叙述中正确的是()。 A.宏名必须用大写字母表示 B.宏定义必须位于源程序中所有语句之间 C.宏替换没有数据类型限制 D.宏调用比函数调用耗费时间 【答案】C 【解析】A项错误,在C语言中,宏名可以是任何合法的C语言标识符,只不过通常习惯用大写字母;B项错误,宏可以根据需要出现在程序的任何一行的开始部位;D项错误,宏定义是“编译预处理”命令,它们的替换过程在编译时期就已经完成了,因此不会占有程序运行的时间。答案选择C选项。 4.以下关于宏的叙述错误的是()。 A.宏替换不具有计算功能 B.宏是一种预处理指令 C.宏名必须用大写字母构成 D.宏替换不占用运行时间 【答案】C 【解析】宏名习惯采用大写字母,以便与一般变量区别,但是并没有规定一定要用大写字母,答案选择C选项。

2012-2013学年第二学期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

国家二级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

C二级 第9章 编译预处理和动态存储分配

1.以下叙述中正确的是()。 A) 在C语言中,预处理命令行都以"#"开头 B) 预处理命令行必须位于C源程序的起始位置 C) #include 必须放在C程序的开头 D) C语言的预处理不能实现宏定义和条件编译的功能 参考答案:A 【解析】预处理命令是以"#"号开头的命令,它们不是C语言的可执行命令,这些命令应该在函数之外书写,一般在源文件的最前面书写,但不是必须在起始位置书写,所以B),C)错误。C)语言的预处理能够实现宏定义和条件编译等功能,所以D)错误。 2.以下关于宏的叙述中正确的是()。 A) 宏替换没有数据类型限制B) 宏定义必须位于源程序中所有语句之前 C) 宏名必须用大写字母表示D) 宏调用比函数调用耗费时间 参考答案:A 【解析】宏定义写在函数的花括号外边,作用域为其后的程序,通常在文件的最开头,所以B)选项中宏定义必须位于源程序中所有语句之前是错误的。宏名一般用大写,但不是必须用大写,所以C)选项错误。宏展开不占运行时间,只占编译时间,函数调用占运行时间(分配内存、保留现场、值传递、返回值),所以D)选项错误。 3.有以下程序: #include #define PT 3.5 ; #define S(x) PT*x*x ; main() {int a=1,b=2;printf("%4.1f\n" ,S(a+b));} 程序运行后的输出结果是()。 A) 7.5 B) 31.5 C) 程序有错无输出结果D) 14.0 参考答案:C 【解析】宏定义不是C语句,末尾不需要有分号。所以语句printf("%4.1f\n" ,S(a+b));展开后为 printf("%4.1f\n" ,3.5;*a+b*a+b;);所以程序会出现语法错误。 4.若程序中有宏定义行: #define N 100 则以下叙述中正确的是 A) 宏定义行中定义了标识符N的值为整数100 B) 在编译程序对C源程序进行预处理时用100替换标识符N C) 上述宏定义行实现将100赋给标示符N D) 在运行时用100替换标识符N 参考答案:B 【解析】本题考查预编译相关知识,宏定义在编译程序时做了一个简单的替换,所以选项B正确。 5.有以下程序 #include #define N 3 void fun( int a[][N], int b[] ) { int i, j; for( i=0; i

编译预处理

编译预处理 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预处理与前缀和

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 #define MAX 2000001 using name space std; int a[100010], b[3*MAX]; int main() { int n, i, j;

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

程序设计试卷13

一、单项选择题(总分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=x)&&!(x>b) D: 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 C.if(2); D.for(; ;) if(1) break; 6.定义带参数的宏计算两式乘积(如x2+3x-5与x-6),下列定义中哪个是正确的(C)。 A.#define muit(u,v)u*v B.#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-5 B.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=AREA D.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.42 C.48 D.54 11.设有以下宏定义,int x,m=5, n=1时,执行语句IFABC(m+n,m,x);后,x的值为(B)。 #define IFABC(a,b,c) c=a>b?a:b A.5 B.6 C.11 D.出错 12.以下程序中的for循环执行的次数是(C)。 #include “stdio.h” #define N 2 #define M N+1 # define NUM (M+1)*M/2 void main( ) { int i,n=0;

相关主题
文本预览
相关文档 最新文档