当前位置:文档之家› C语言程序设计教案 第九章 编译预处理

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

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

}

例如:由键盘输入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)

再与源程序合并

说明:

⑴宏名一般用大写表示,以便与变量名区分。

⑵使用宏名使程序易读,易修改。

⑶只作简单的置换,不作正确性检查。

⑷宏定义不是C语句,不必在行末加分号。

⑸宏名的作用域一般从自定义命令到本源文件结束。

⑹可以用# undef命令终止宏定义的作用域。

⑺宏定义允许嵌套,允许层层置换。

⑻宏名在源程序中用双引号括起来,则TC中预处理不对其作宏代换。

例:printf(“L=%f”, L); 中双引号内L不替换。

⑼宏定义与定义的变量不同,宏只作字符替换,不分配内存空间。

⑽对“输出格式”进行宏定义,可以减少书写麻烦

例如:

#define P printf

#define D “%d,%d,%d\n”

#define F “%6.2f,%6.2f,%6.2f\n”

main()

{ int a=5,c=8,e=11;

float b=3.8,d=9.7; f=21.08;

P(D,a,c,e);

P(F,b,d,f);

P(F,a+b,c+d,e+f);

}

二、带参数的宏定义

格式:#define 宏名(参数表) 字符串

例:#define s(a,b) a*b

{……

area =s(3,2);

……}

对带参的宏展开后,为area=3*2;

例:#define M(y) y*y+3*y

{……

k=M(5);

……}

对其展开后,为k=5*5+3*5;

说明:

⑴对带参数的宏展开只是将宏名后括号内的实参

字符串代替#define命令行中的形参。

⑵宏定义时,在宏名与带参数的括号之间不应加

空格,否则将空格以后的字符都作为替代字符

串的一部分。

⑶带参宏定义,形参不分配内存单元,因此不必

作类型定义。(与函数的区别之一)

⑷带参宏与函数的区别之二:

例如:

main()

{ int i=1;

while( i<=5 ) printf(“%d\t”,SQ( i++));}

SQ(int y)

{ return(y)*(y); }

其结果为:1 4 9 16 25

如:

#define SQ(y) ((y)*(y))

main()

{ int i =1;

while( i<=5 )

printf(“%d\t”,SQ( i++));

}

运行结果:

2 12 30

例:利用宏定义求两个数中的大数。

#define MAX(a,b) (a>b)?a:b

main()

{int x, y, max;

scanf(“%d%d”, &x, &y);

max =MAX(x, y);

printf(“max=%d\n”, max);

}

带参的宏定义和函数不同:

1、函数调用时,先求实参表达式值,后代入。而带参的宏只是进行简单的字符替换。

2、函数调用是在程序运行时处理的,分配临时的内存单元。而宏展开则是在编译时进行的,不分配内存单元,不进行值的传递,也无“返回值”。

3、对函数中的实参和形参都要定义类型,类型应一致。而宏不存在类型问题,宏名和参数无类型,只是一个符号代表,展开时代入指定的字符即可。

4、调用函数只可得到一个返回值,

而用宏可以设法得到几个结果。

5、使用宏次数多时,宏展开后使源程序增长,

而函数调用不使源程序变长。

6、宏替换不占运行时间,只占编译时间。

而函数调用则占用运行时间( 分配单元、保留现场、值传递、返回)

一般用宏代表简短的表达式比较合适。

也可利用宏定义实现程序的简化。

例9.5:

#define PR 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[]=“CHINA”;

a=1;b=2;c=3;d=4;

PR(D1,a);

PR(D2,a,b);

PR(D3,a,b,c);

PR(D4,a,b,c,d);

PR(S, string);

}

§9.2 “文件包含”处理

“文件包含”处理是指将指定的被包含文件的全部内容插到该控制行的位置处,使其成为源文件的一部分参与编译。因此,被包含的文件应该是源文件。

通常置于源程序文件的首部,故也称为“头文件”。

C编译系统提供的头文件扩展名为“.h”,但设计者可根据实际情况,自行确定包含文件的后缀、名字及其位置。

一般形式,#include “文件名”

或#include <文件名>

文件format.h

#define PR 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”

文件file1.c

#include “format.h”

main()

{ int a,b,c,d;

char string[]=“CHINA”;

a=1;b=2;c=3;d=4;

PR(D1,a);

PR(D2,a,b);

PR(D3,a,b,c);

PR(D4,a,b,c,d);

PR(S, string);

}

注:被包含的文件应是源文件,而不应是目标文件。

头文件除了可以包含函数原型和宏定义外,也可以包括结构体类型定义和全局变量定义等。

说明:

1、一个include命令只能指定一个被包含文件,如果要包含n个文件,要用n个include命令。

2、如果文件1包含文件2,而文件2中要用到文件3的内容,则可在文件1中用两个include 命令分别包含文件2和文件3,而且文件3应出现在文件2之前,即在“file1.c”中定义:#include “file3.h”

#include “file2.h”

3、在一个被包含文件中又可以包含另一个被包含文件,即文件包含是可以嵌套的。

4、被包含文件(file2.h)与其所在的文件(file1.c),在预编译后已成为同一个文件。

5、在#include 命令中,文件名可以用双引号或尖括号括起来。

如:#include

或#include “file2.h”

二者的区别:

用尖括号时称为标准方式,系统到存放C库头文件所在的目录中寻找要包含的文件。

用双引号时,系统先在用户当前目录中寻找要包含的文件,若找不到,再按标准方式查找。

#include “c:\tc\include\myfile.h” /*正确*/

#include /*正确*/

#include /*错误*/

用尖括号:带路径:按指定路径去寻找被包含文件,但此时被包含文件不能以“.h”结尾,否则错误。

不带路径:仅从指定标准目录下找。

用引号:带路径:按指定路径去寻找被包含文件,不再从当前目录和指定目录下找。

不带路径:先在当前目录下找,找不到再在系统指定的标准目录下找。

步骤三课堂小结

本课主要讲解了宏定义、“文件包含”处理。对带参数的宏的使用,及与函数的使用的区别。搞清经常使用的头文件。

步骤四布置作业

上机作业:(第九章课后练习)9.4

书面作业:(第九章课后练习)9.7、9.8

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.下面叙述中正确的是()。 A.#define和printf都是C语句 B.#define是C语句,而printf不是 C.printf是C语句,但#define不是 D.#define和printf都不是C语句

编译预处理

第九章编译预处理 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语言预处理命令之条件编译(#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

第九章 编译预处理

第九章编译预处理 一、单选题 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章编译预处理及位运算习题答案.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); } 程序运行后的输出结果是

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语言条件编译及编译预处理阶段

C语言条件编译及编译预处理阶段 一、C语言由源代码生成的各阶段如下: C源程序->编译预处理->编译->优化程序->汇编程序->链接程序->可执行文件其中编译预处理阶段,读取c源程序,对其中的伪指令(以#开头的指令)和特殊符号进行处理。或者说是扫描源代码,对其进行初步的转换,产生新的源代码提供给编译器。预处理过程先于编译器对源代码进行处理。 在C 语言中,并没有任何内在的机制来完成如下一些功能:在编译时包含其他源文件、定义宏、根据条件决定编译时是否包含某些代码。要完成这些工作,就需要使用预处理程序。尽管在目前绝大多数编译器都包含了预处理程序,但通常认为它们是独立于编译器的。预处理过程读入源代码,检查包含预处理指令的语句和宏定义,并对源代码进行响应的转换。预处理过程还会删除程序中的注释和多余的空白字符。 二、伪指令(或预处理指令)定义 预处理指令是以#号开头的代码行。#号必须是该行除了任何空白字符外的第一个字符。#后是指令关键字,在关键字和#号之间允许存在任意个数的空白字符。整行语句构成了一条预处理指令,该指令将在编译器进行编译之前对源代码做某些转换。下面是部分预处理指令: 指令用途 # 空指令,无任何效果 #include 包含一个源代码文件 #define定义宏 #undef取消已定义的宏 #if如果给定条件为真,则编译下面代码 #ifdef 如果宏已经定义,则编译下面代码 #ifndef 如果宏没有定义,则编译下面代码 #elif如果前面的#if给定条件不为真,当前条件为真,则编译下面代码, 其实就是elseif的简写 #endif结束一个#if……#else条件编译块 #error停止编译并显示错误信息 三、预处理指令主要包括以下四个方面: 1、宏定义指令 宏定义了一个代表特定内容的标识符。预处理过程会把源代码中出现的宏标识符替换成宏定义时的值。宏最常见的用法是定义代表某个值的全局符号。宏的第二种用法是定义带参数的宏(宏函数),这样的宏可以象函数一样被调用,但它是在调用语句处展开宏,并

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程序中,以#号带头的行是预编译(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;

第九章 预处理

第九章预处理 A部分(本、专科必做) 一、选择题 以下不正确的叙述是(D) A、宏替换不占用运行时间。 B、宏名无类型。 C、宏替换只是字符替换。 D、宏名必须用大写字母表示。 C语言的编译系统对宏命令的处理(D) A、在程序运行时进行的。 B、在程序连接时进行。 C、和C程序中的其它语句同时进行编译的。 D、在对源程序中其它语句正式编译之前进行的。 3、以下程序的输出结果是(C)。 A、15 B、100 C、10 D、150 #define MIN(x,y) (x)<(y)?(x):(y) void main() { int I,j,k; i=10;j=15;k=10*MIN(i,j); printf(“%d\n”,k); } 4、以下叙述中正确的是(D) 用#include包含的文件的后缀必须是“.h”。 若一些源程序中包含某个头文件;当该文件有错时,只需对该头文件进行修改,包含此头文件的所有源程序不必重新进行编译。 宏命令行可以看作是一行C语句。 预处理是在编译之前进行的。 5、以下叙述中正确的是(C) A、源程序中所有的行都参加编译。 B、宏定义常量与const定义常量是一样的。 C、宏定义可以嵌套定义,即在宏定义中的字符串可以引用另一个宏定义的标识符。 D、以上都不正确。 二、填空题 以下程序中for 循环执行的次数是 6 。 #define N 2 #define M N+1 #define NUM (M+1)*M/2 void main() { int i; for(i=1;i<=NUM;i++); printf(“%d\n”,i); } 2、以下程序的输出结果是x=93 。 #define A 3 #define B(a) ((A+1)*a)

C语言预处理命令总结大全

C语言预处理命令总结大全 (2012-02-13 17:18) 标签: C语言预处理分类:C编程 C程序的源代码中可包括各种编译指令,这些指令称为预处理命令。虽然它们实际上不是C语言的一部分,但却扩展了C程序设计的环境。本节将介绍如何应用预处理程序和注释简化程序开发过程,并提高程序的可读性。ANSI标准定义的C 语言预处理程序包括下列命令: #define,#error,#include,#if,#else,#elif,#endif,#ifdef,#ifndef,#undef,#line,#pragma等。非常明显,所有预处理命令均以符号#开头,下面分别加以介绍。 一 #define 命令#define定义了一个标识符及一个串。在源程序中每次遇到该标识符时,均以定义的串代换它。ANSI标准将标识符定义为宏名,将替换过程称为宏替换。命令的一般形式为: #define identifier string 注意: 1该语句没有分号。在标识符和串之间可以有任意个空格,串一旦开始,仅由一新行结束。 2宏名定义后,即可成为其它宏名定义中的一部分。 3 宏替换仅仅是以文本串代替宏标识符,前提是宏标识符必须独立的识别出来,否则不进行替换。例如: #define XYZ this is a tes 使用宏printf("XYZ");//该段不打印"this is a test"而打印"XYZ"。因为预编译器识别出的是"XYZ" 4如果串长于一行,可以在该行末尾用一反斜杠' \'续行。 #defineLONG_STRING"this is a very long\ string that is used as an example" 5 C语言程序普遍使用大写字母定义标识符。 6 用宏代换代替实在的函数的一大好处是宏替换增加了代码的速度,因为不 存在函数调用的开销。但增加速度也有代价:由于重复编码而增加了程序长度。 二 #error 命令#error强迫编译程序停止编译,主要用于程序调试。 #error指令使预处理器发出一条错误消息,该消息包含指令中的文本.这条指令的目的就是在程序崩溃之前能够给出一定的信息。 三 #include

第九章改 预处理命令习题答案

第九章习题答案 一、单项选择题 1.A 2.B 3.C 4.D 5.B 6.C 7.A 8.D 9.D 10.C 11.B 12.C 13.D 14.C 二、填充题 1.编译处理编译预处理 2.非静态存储类型变量和外部函数 3.7 4.printf(“%d\n”,m); 5.fopen(“a.txt”,”rw”); 6.x[i]>=’A’&&x[i]<=’Z’ 7.“ i=%d\n” 8.(1) #define MAX(a,b,c) (2) #define MIN(a,b) (a=’0’&& c<=’9’) (4) #define isupper( c) (c>=’A’&& c<=’Z’) (5) #define islower( c) (c>=’a’ && c<=’z’) 三、程序分析题 1.运行结果: -3 2.运行结果: 7,47 3.运行结果:50 25 4.运行结果:x=9, y=5 5.运行结果:9 9 11 6.输出结果: x|y&z=3 x^y&~z=1 x&y&z=0 !x|x=1 ~x|x=-1

四、程序设计题 1.解: #include #include #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.解: #include #include void main (int argc, char *argv[ ]) { int a, b; if (argc<3) { printf (“Parameter missing!\n”) ; exit(0); } a=atoi (argv[1]) ; b=atoi (argv[2]) ; //在stdlib.h中有库函数atoi, 把字符串转换成整数 printf (“%5d + %5d = %5d\n”, a, b, a+b) ; printf (“%5d - %5d = %5d\n”, a, b, a-b) ; printf (“%5d * %5d = %5d\n”, a, b, a*b) ; printf (“%5d / %5d = %5d\n”, a, b, a/b) ; printf (“%5d %% %5d = %5d\n”, a, b, a%b) ; } 3.解: #include #include void main (int argc, char *argv[]) { int i, sum=0; for (i=1; i #include #include

第12章 C语言的编译预处理

第12章 C 语言的编译预处理 C 语言属于高级语言,用C 语言编写的程序称为源程序,这种用高级语言编写的源程序 计算机是不能直接执行的,必须经过C 语言的编译系统把源程序编译成目标程序(机器指令构成的程序)并连接成可执行程序,计算机才可以执行。因此,用C 语言来处理问题,必须经过程序的编写→编译及连接→运行三个主要过程。然而,为了减少C 源程序编写的工作量,改善程序的组织和管理,帮助程序员编写易读、易改、易于移植、便于调试的程序,C 语言编译系统提供了预编译功能。 所谓的预编译功能是指:编译器在对源程序正式编译前,可以根据预处理指令先做一些 特殊的处理工作,然后将预处理结果与源程序一起进行编译。 C 语言提供的编译预处理功能主要有三种:文件包含、宏定义、条件编译。这三种功能 分别以三条编译预处理命令#include 、#define 、#if 来实现。编译预处理指令不属于C 语言的 语法范畴,因此,为了和C 语句区别开来,预处理指令一律以符号“#”开头,以“回车” 结束,每条预处理指令必须独占一行。 12.1 文件包含预处理 “包含”的英文单词为“include ”,所谓“文件包含”预处理,就是在源文件中通过“#include ”命令指示编译器将另一段源文件包含到本文件中来。 例如,源文件f1.c 中有一句“#include f2.c ”编译预处理命令,如图12-1(a)所示。编译预处理后文件f1.c 的完整结构如图12-1(c)所示。 图12-1 文件包含编译预处理命令 编译时先将f2.c (图12-1(b))的内容复制嵌入到f1.c (图12-1(a))中来,即进行“包含” 预处理,然后对调整好的完整的f1.c (图12-1(c))进行编译,得到相应的目标代码。换句话说,由f1.c 和f2.c 组成程序的目标代码(.obj )和用一个源文件(类似于图c )的目标代码(.obj )完全一样。但是用#include 包含f2.c 的方式编写程序可以使其他的程序重用f2.c 的代码,并且使源文件简洁明了。 “文件包含”指令有两种使用方式: 第一种形式,用尖括号(即小于号<、大于号>)括起被包含源文件的名称: #include <文件名> f1.c ……… ……… ……… ……………… ……………… ……………… ……………… ……………… ……………… #include f2.c ……………… ……………… ……………… ……………… ……………… ……………… f1.c (a) 预编译前 (b) (c) 预编译后

第九章编译预处理

第九章 编译预处理 编译指令(编译预处理指令):C 源程序除了包含程序命令(语句)外,还可以使用各种编译指令(编译预处理指令)。编译指令(编译预处理指令)是给编译器的工作指令。这些编译指令通知编译器在编译工作开始之前对源程序进行某些处理。编译指令都是用“#”引导。 编译预处理:编译前根据编译预处理指令对源程序的一些处理工作。C 语言编译预处理主要包括宏定义、文件包含、条件编译。 编译工作实际分为两个阶段:编译预处理、编译。广义的编译工作还包括连接。 9、1 宏定义 宏定义:用标识符来代表一个字符串(给字符串取个名字)。C 语言用“#define ”进行宏定义。C 编译系统在编译前将这些标识符替换成所定义的字符串。 宏定义分为不带参数的宏定义和带参数宏定义。 9、1、1 不带参数宏定义(简单替换) 1 其中:标识符-宏名。 2、宏调用:在程序中用宏名替代字符串。 3、宏展开:编译预处理时将字符串替换宏名的过程,称为宏展开。

说明: (1)宏名遵循标识符规定,习惯用大写字母表示,以便区别普通的变量。 (2)#define 之间不留空格,宏名两侧空格(至少一个)分隔。 (3)宏定义字符串不要以分号结束,否则分号也作为字符串的一部分参加展开。从这点上 看宏展开实际上是简单的替换。 例如:#define PI 3.14; 展开为s=3.14;*r*r ;(导致编译错误) (4)宏定义用宏名代替一个字符串,并不管它的数据类型是什么,也不管宏展开后的词法 和语法的正确性,只是简单的替换。是否正确,编译时由编译器判断。 例如:#define PI 3.I4 照样进行宏展开(替换),是否正确,由编译器来判断。 (5)#define 宏定义宏名的作用范围从定义命令开始直到本源程序文件结束。可以通过 #undef 终止宏名的作用域。

C语言预处理命令总结大全

C语言预处理命令总结大全 标签: C语言预处理分类:C编程 C程序的源代码中可包括各种编译指令,这些指令称为预处理命令。虽然它们实际上不是C语言的一部分,但却扩展了C程序设计的环境。本节将介绍如何应用预处理程序和注释简化程序开发过程,并提高程序的可读性。ANSI标准定义的C语言预处理程序包括下列命令: #define,#error,#include,#if,#else,#elif,#endif,#ifdef,#ifndef,#undef,#line,#pragma等。非常明显,所有预处理命令均以符号#开头,下面分别加以介绍。 一 #define 命令#define定义了一个标识符及一个串。在源程序中每次遇到该标识符时,均以定义的串代换它。ANSI标准将标识符定义为宏名,将替换过程称为宏替换。命令的一般形式为: #define identifier string 注意: 1该语句没有分号。在标识符和串之间可以有任意个空格,串一旦开始,仅由一新行结束。 2宏名定义后,即可成为其它宏名定义中的一部分。 3 宏替换仅仅是以文本串代替宏标识符,前提是宏标识符必须独立的识别出来,否则不进行替换。例如: #define XYZ this is a tes 使用宏printf("XYZ");//该段不打印"this is a test"而打印"XYZ"。因为预编译器识别出的是"XYZ" 4如果串长于一行,可以在该行末尾用一反斜杠' \'续行。 #defineLONG_STRING"this is a very long\ string that is used as an example" 5 C语言程序普遍使用大写字母定义标识符。 6 用宏代换代替实在的函数的一大好处是宏替换增加了代码的速度,因为不存在函数调用 的开销。但增加速度也有代价:由于重复编码而增加了程序长度。 二 #error 命令#error强迫编译程序停止编译,主要用于程序调试。 #error指令使预处理器发出一条错误消息,该消息包含指令中的文本.这条指令的目的就是在程序崩溃之前能够给出一定的信息。 三 #include 命令#i nclude使编译程序将另一源文件嵌入带有#include的源文件,被读入的源文件必须用双引号或尖括号括起来。例如: #include"stdio.h"或者#include 这两行代码均使用C编译程序读入并编译用于处理磁盘文件库的子程序。

第九章 预处理命令

第九章 预处理命令 一、选择题 1.以下叙述不正确的是 。 A)预处理命令行都必须以#开始 B)在程序中凡是以#开始的语句行都是预处理命令行 C)C程序在执行过程中对预处理命令行进行处理 D)预处理命令行可以出现在C程序中任意一行上 2.以下叙述中正确的是 。 A)在程序的一行上可以出现多个有效的预处理命令行 B)使用带参数的宏时,参数的类型应与宏定义时的一致 C)宏替换不占用运行时间,只占用编译时间 D)C语言的编译预处理就是对源程序进行初步的语法检查 3.以下有关宏替换的叙述不正确的是 。 A)宏替换不占用运行时间B)宏名无类型 C)宏替换只是字符替换D)宏名必须用大写字母表示 4.在“文件包含”预处理命令形式中,当#include后面的文件名用””(双引号)括起时,寻找被包含文件的方式是 。 A)直接按系统设定的标准方式搜索目录 B)先在源程序所在目录中搜索,再按系统设定的标准方式搜索 C)仅仅搜索源程序所在目录 D)仅仅搜索当前目录 5.在“文件包含”预处理命令形式中,当#include后名的文件名用<>(尖括号)括起时,寻找被包含文件的方式是 。 A)直接按系统设定的标准方式搜索目录 B)先在源程序所在目录中搜索,再按系统设定的标准方式搜索 C)仅仅搜索源程序所在目录 D)仅仅搜索当前目录 6.在宏定义#define PI 3.1415926中,用宏名PI代替一个 。 A)单精度数B)双精度数C)常量D)字符串 7.以下程序的运行结果是 。 #include #define ADD(x) x+x void main ( ) { int m=1,n=2,k=3,sum ; sum = ADD(m+n)*k ; printf(“%d\n”,sum) ; A)9 B)10 C)12 D)18 8.以下程序的运行结果是 。 #include #define MIN(x,y) (x)>(y) ? (x) : (y) void main ( ) { int i=10, j=15 , k; k = 10*MIN(i,j); printf(“%d\n”,k);

C语言编程常见问题解答之编译预处理

C语言编程常见问题解答之编译预处理 本章集中讨论与预处理程序有关的问题。在编译程序对程序进行通常的编译之前,要先运行预处理程序。可能你以前没有见过这个程序,因为它通常在幕后运行,程序员是看不见它的,然而,这个程序非常有用。 预处理程序将根据源代码中的预处理指令来修改你的程序。预处理指令(如#define)为预处理程序提供特定的指令,告诉它应该如何修改你的源代码。预处理程序读入所有包含的文件和待编译的源代码,经过处理生成源代码的预处理版本。在该版本中,宏和常量标识符已用相应的代码和值代替。如果源代码中包含条件预处理指令(如#if),预处理程序将先判断条件,然后相应地修改源代码。 预处理程序有许多非常有用的功能,例如宏定义,条件编译,在源代码中插入预定义的环境变量,打开或关闭某个编译选项,等等。对专业程序员来说,深入了解预处理程序的各种特征,是创建快速和高效的程序的关键之一。 在阅读本章时,请记住本章采用的一些技术(以及所提到的一些常见陷阱),以便更好地利用预处理程序的各种功能。 5.1 什么是宏(macro)?怎样使用宏? 宏是一种预处理指令,它提供了一种机制,可以用来替换源代码中的字符串,宏是用“#define"语句定义的,下面是一个宏定义的例子: #define VERSION—STAMP "1.02" 上例中所定义的这种形式的宏通常被称为标识符。在上例中,标识符VERSION_STAMP 即代表字符串"1.02"——在编译预处理时,源代码中的每个VERSION_STAMP标识符都将被字符串“1.02”替换掉。 以下是另一个宏定义的例子: #define CUBE(x) ((x)*(x)*(x)) 上例中定义了一个名为CUBE的宏,它有一个参数x。CUBE宏有自己的宏体,即((x)*(x)*(x))——在编译预处理时,源代码中的每个CUBE(x)宏都将被((x)*(x)*(x))替换掉。 使用宏有以下几点好处;

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