计本-C语言(第八章).ppt_第1页
计本-C语言(第八章).ppt_第2页
计本-C语言(第八章).ppt_第3页
计本-C语言(第八章).ppt_第4页
计本-C语言(第八章).ppt_第5页
已阅读5页,还剩63页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第8章 预 处 理 命 令 第8章 预 处 理 命 令 第8章 预 处 理 命 令 8.1 宏定义(了解) 8.2 “文件包含”处理(掌握) 8.3 条件编译(重点/掌握) 第8章 预 处 理 命 令 第8章 预 处 理 命 令 1.功能: 预处理命令”(preprocessor DireCtiveS),改进程序设计环 境,提高编程效率。 2.预处理: 由ANSI C统一规定的,但是它不是C语言本身的组成部分, 不能直接对它们进行编译. 如: # define A 20 /*在预处理时将程序中所有的A都置换为指定的字符串*/。 #include “Stdio.h” /*则在预处理时将StDio.h文件中的实际内容代替该命令*/ 3.区别: 为了与一般C语句相区别,这些命令以符号“#”开头。 第8章 预 处 理 命 令 第8章 预 处 理 命 令 概述 1.功能:预处理命令”(preprocessor DireCtiveS) 8.1 宏定义(了解) 第8章 预 处 理 命 令 ANSI C标准规定可以在C源程序中加入一些“预处理命令 ”(preprocessor DireCtiveS) ,以改进程序设计环境, 提高编程效率。这些预处理命令是由ANSI C统一规定的, 但是它不是C语言本身的组成部分,不能直接对它们进行 编译(因为编译程序不能识别它们)。必须在对程序进行通 常的编译(包括词法和语法分析、代码生成、优化等)之前 ,先对程序中这些特殊的命令进行“预处理”, 即根据 预处理命令对程序作相应的处理(例如,若程序中用 #define命令定义了一个符号常量A,则在预处理时将程序 中所有的A都置换为指定的字符串。若程序中用#inClude 命令包含一个文件“StDio.h”, 第8章 预 处 理 命 令 则在预处理时将StDio.h文件中的实际内容代替该命令)。经 过预处理后程序不再包括预处理命令了,最后再由编译程序 对预处理后的源程序进行通常的编译处理,得到可供执行的 目标代码。现在使用的许多C编译系统都包括了预处理、编 译和连接等部分,在进行编译时一气呵成。因此不少用户误 认为预处理命令是C语言的一部分,甚至以为它们是C语句, 这是不对的。必须正确区别预处理命令和C语句、区别预处 理和编译,才能正确使用预处理命令。C语言与其他高级语 言的一个重要区别是可以使用预处理命令和具有预处理的功 能。 第8章 预 处 理 命 令 C提供的预处理功能主要有以下三种: 1. 宏定义 2. 文件包含 3. 条件编译 分别用宏定义命令、文件包含命令、条件编译命令来实现。 为了与一般C语句相区别,这些命令以符号“#”开头。 第8章 预 处 理 命 令 第8章 预 处 理 命 令 9.1 宏定义 9.1.1 不带参数的宏定义 用一个指定的标识符(即名字)来代表一个字符串,它的一般 形式为#define 标识符字符串。这就是已经介绍过的定义符号常 量。如:#definePI3.1415926它的作用是指定用标识符PI来代替 “3.1415926”这个字符串,在编译预处理时,将程序中在该命 令以后出现的所有的PI都用“3.1415926”代替。这种方法使用 户能以一个简单的名字代替一个长的字符串,因此把这个标识符 (名字)称为“宏名”,在预编译时将宏名替换成字符串的过程称 为“宏展开”。#define是宏定义命令。 第8章 预 处 理 命 令 例9.1 #define PI 3.1415926 main() float l,s,r,v; printf(“input raDiuS“); scanf(“%f“, l=2.0*PI*r; s=PI*r*r; v=3.0/4*PI*r*r*r; printf(“l=%10.4fnS=%10.4fnv=%10.4fn“,l,s,v); 第8章 预 处 理 命 令 运行情况如下: input radius:4 l=25.1328 s=50.2655 v=150.7966 说明: (1) 宏名一般习惯用大写字母表示,以便与变量名相区别。但 这并非规定,也可用小写字母。 (2) 使用宏名代替一个字符串,可以减少程序中重复书写某些 字符串的工作量。例如,如果不定义PI代表3.1415926,则 在程序中要多处出现3.1415926,不仅麻烦,而且容易写错( 或敲错),用宏名代替, 第8章 预 处 理 命 令 简单不易出错,因为记住一个宏名(它的名字往往用容易 理解的单词表示)要比记住一个无规律的字符串容易,而且 在读程序时能立即知道它的含义,当需要改变某一个常量 时,可以只改变#define命令行,一改全改。例如,定义数 组大小,可以用 #define array- size 1000 int arrayarray-size; 先指定array-size代表常量1000,因此数组array大小为1000 ,如果需要改变数组大小,只需改 #define行: #define array-size 500 使用宏定义,可以提高程序的通用性。 第8章 预 处 理 命 令 (3) 宏定义是用宏名代替一个字符串,也就是作简单的置换 ,不作正确性检查。如果写成 #define PI 3.l4l59 即把数字1写成小写字母l,预处理时也照样代入,不管含义 是否正确。也就是说预编译时不作任何语法检查。只有在 编译已被宏展开后的源程序时才会发现错误并报错。 (4) 宏定义不是C语句,不必在行末加分号。如果加了分号 则会连分号一起进行置换。如: #define PI 3.1415926; area=PI*r*r; 第8章 预 处 理 命 令 经过宏展开后,该语句为 area=3.1415926;*r*r; 显然出现语法错误。 (5) #define命令出现在程序中函数的外面,宏名的有效范围 为定义命令之后到本源文件结束。通常,#define命令写在 文件开头,函数之前,作为文件一部分,在此文件范围内 有效。 (6) 可以用#undef命令终止宏定义的作用域。例如: 第8章 预 处 理 命 令 #define g 8.8 main() | G的有效范围 #undef g f1() 由于#undef的作用,使G的作用范围在#undef行处终止,因此 在f1函数中,g不再代表8.8。这样可以灵活控制宏定义的 作用范围。 第8章 预 处 理 命 令 (7) 在进行宏定义时,可以引用已定义的宏名,可以层层置 换。 例9.2 #define R 3.0 #define PI 3.1415926 #define L 2*PI*R #define S PI*R*R main() printf(“L=%fns=%fn“,L,S); 第8章 预 处 理 命 令 运行情况如下: L=18.849556 s=28.274333 经过宏展开后,printf函数中的输出项L被展开为 2*3.1415926*3.0,S展开为 3.1415926*3.0*3.0, printf函数调用语句展开为printf(“L=%fns=%fn“, 2*3.1415926*3.0,3.1415926*3.0*3.0); (8) 对程序中用双括号括起来的字符串内的字符,即使与宏 名相同,也不进行置换。如例9.2中的printf函数内有两 个l字符,一个在双引号内,它不被宏置换,另一个在双 引号外,被宏置换展开。 第8章 预 处 理 命 令 (9) 宏定义是专门用于预处理命令的一个专用名词,它与定 义变量的含义不同,只作字符替换,不分配内存空间。 9.1.2 带参数的宏定义 不是进行简单的字符串替换,还要进行参数替换。其定义的 一般形式为 #define 宏名(参数表) 字符串 字符串中包含在括弧中所指定的参数。如: #define s(a,b) a*b area=s(3,2); 第8章 预 处 理 命 令 定义矩形面积S,a和B是边长。在程序中用了s(3,2),把3 、2分别代替宏定义中的形式 图9.1 第8章 预 处 理 命 令 参数a、b,即用3*2代替s(3,2)。因此赋值语句展开 为area=3*2; 对带参的宏定义是这样展开置换的:在程序中如果 有带实参的宏(如S(3,2),则按#define命令行中 指定的字符串从左到右进行置换。如果串中包含 宏中的形参(如a、b),则将程序语句中相应的实 参(可以是常量、变量或表达式)代替形参,如果 宏定义中的字符串中的字符不是参数字符(如a*b 中的*号),则保留。这样就形成了置换的字符串 ,见图9.1。 第8章 预 处 理 命 令 例9.3 #definePI3.1415926 #define S(r) PI*r*r main() float a,area; a=3.6; area=S(a); printf(“r=%fnarea=%fn“,a,area); 运行结果如下: r=3.600000 area=40.715038 第8章 预 处 理 命 令 赋值语句area=s(a);经宏展开后为 area=3.1415926*a*a; 说明: (1) 对带参数的宏的展开只是将语句中的宏名后面括号内的实 参字符串代替#define命令行中的形参。例9.3中语句中有 S(a),在展开时,找到#define命令行中的S(r),将S(a)中 的实参a代替宏定义中的字符串“PI*r*r”中的形参r,得到 PI*a*a。这是容易理解而且不会发生什么问题的。但是,如 果有以下语句:area=S(a+B);这时把实参a+B代替PI*r*r中 的形参r,成为area=PI*a+B*a+B;请注意在a+B外面没有括弧 ,显然这与程序设计者的原意不符。原意希望得到 第8章 预 处 理 命 令 area=PI*(a+B)*(a+B);为了得到这个结果,应当在定义时 ,在字符串中的形式参数外面加一个括弧。即#define S(r) PI*(r)*(r)在对S(a+B)进行宏展开时,将a+B代替r ,就成了PI*(a+B)*(a+B)这就达到了目的。 (2) 在宏定义时,在宏名与带参数的括弧之间不应加空格, 否则将空格以后的字符都作为替代字符串的一部分。例如 ,如果有 #define s (r)PI*r*r 被认为s是符号常量(不带参的宏名),它代表字符串“(r) PI*r*r”。如果在语句中有area=S (a); 则被展开为 area=(r) PI*r*r (a) 显然不对了。 第8章 预 处 理 命 令 有些读者容易把带参数的宏和函数混淆。的确,它们之间有 一定类似之处,在引用函数时也是在函数名后的括弧内写 实参,也要求实参与形参的数目相等。但是带参的宏定义 与函数是不同的。主要有: (1) 函数调用时,先求出实参表达式的值,然后代入形参。 而使用带参的宏只是进行简单的字符替换。例如上面的 S(a+b),在宏展开时并不求a+B的值,而只将实参字符 “a+b”代替形参r。 (2) 函数调用是在程序运行时处理的,分配临时的内存单元 。而宏展开则是在编译时进行的,在展开时并不分配内存 单元,不进行值的传递处理,也没有“返回值”的概念。 第8章 预 处 理 命 令 (3) 对函数中的实参和形参都要定义类型,二者的类型要求 一致,如不一致,应进行类型转换。而宏不存在类型问题 ,宏名无类型,它的参数也无类型,只是一个符号代表, 展开时代入指定的字符即可。宏定义时,字符串可以是任 何类型的数据。例如: #define CHAR1 CHINA(字符) #define a 3.6 (数值) CHAR1和a不需要定义类型,它们不是变量,在程序中凡遇 CHAR1均以CHINA代之;凡遇a均以3.6代之,显然不需定义类 型。同样,对带参的宏: #define S(r) PI*r*r 第8章 预 处 理 命 令 r也不是变量,如果在语句中有S(3.6),则展开后为 PI*3.6*3.6,语句中并不出现r。当然也不必定义r的类型 。 (4) 调用函数只可得到一个返回值,而用宏可以设法得到几 个结果。 例9.4 #define PI 3.1415926 #define CIRCLE(r,l,s,v)L=2*PI*R;S=PI*R*R; =4.0/3.0*PI*R*R*R main() float r,l,s,v; 第8章 预 处 理 命 令 scanf(“%f“, CIRCLE(r,l,S,v); printf(“r=%6.2f,l=%6.2f, S=%6.2f, v=%6.2fn“,r,l,S,v); 经预编译宏展开后的程序如下: main() float r,l,S,v; scanf(“%f”, l=2*3.1415926r;S=3.14159*r*r;v=4.0/3.0*3.1415926* r*r*r; 第8章 预 处 理 命 令 printf(“r=%6.2f,l=%6.2f,S=%6.2f, v=%6.2fn“,r,l,S,v); 运行情况如下: 3.5 r= 3.50,l= 21.99,S= 38.48,v= 179.59 请注意,实参r的值已知,可以从宏带回3个值(l,S,v)。 其实,只不过是字符代替而已,将字符r代替R,l代替L, S代替S,v代替,而并未在宏展开时求出l、S、v的值。 第8章 预 处 理 命 令 (5) 使用宏次数多时,宏展开后源程序长,因为每展开一次 都使程序增长,而函数调用不使源程序变长。 (6) 宏替换宏替换不占运行时间,只占编译时间。而函数调用函数调用则占 运行时间(分配单元、保留现场、值传递、返回)。 一般用宏来代表简短的表达式比较合适。有些问题,用 宏和函数都可以。如: #define MAX(x,y) (x)(y)?(x)(y) main() int a,b,c,d,t; 第8章 预 处 理 命 令 t=MAX(a+b,c+d); 赋值语句展开后为 t=(a+b)(c+d)?(a+b)(c+d); 注意:MAX不是函数,这里只有一个main函数,在main函数 中就能求出t的值。 这个问题也可用函数来求: int max(int x,int y) return(xy?xy); main() 第8章 预 处 理 命 令 int a,B,C,D,t; t=max(a+B,C+D); max是函数,在main函数中调用max函数才能求出t的值。 请仔细分析以上两种方法。 如果善于利用宏定义,可以实现程序的简化实现程序的简化,如事先将程序 中的“输出格式”定义好,以减少在输出语句中每次都要 写出具体的输出格式的麻烦。 第8章 预 处 理 命 令 例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; 第8章 预 处 理 命 令 PR(D1,a); PR(D2,a,B); PR(D3,a,B,C); PR(D4,a,B,C,D); PR(S,string); 运行时输出以下结果: 1 12 123 1234 CHINA 第8章 预 处 理 命 令 程序中用PR代表printf。以NL代表执行一次“换行”操作。 以D代表输出一个整型数据的格式符。以D1代表输出完1个 整数后换行,D2代表输出2个整数后换行,D3代表输出3个 整数后换行,D4代表输出4个整数后换行。以S代表输出一 个字符串的格式符。可以看到,程序中写输出语句就比较 简单了,只要根据需要选择已定义的输出格式即可,连 printf都可以简写为PR。 可以参照例9.5,写出各种输入输出的格式(例如实型、长整 型、十六进制整数、八进制整数、字符型等),把它们单独 编成一个文件,它相当一个“格式库”,用#inClude命令 把它“包括”到自己所编的程序中,用户就可以根据情况 各取所需了。显然在写大程序时,这样做是很方便的。 第8章 预 处 理 命 令 1.概念: 所谓“文件包含”处理是指一个源文件可以将另外一个源文 件的全部内容包含进来,即将另外的文件包含到本文件之中。 2.实现: 通过#include命令 3. 一般形式: #inClude “文件名”或#inClude 8.2 “文件包含”处理(掌握) 第8章 预 处 理 命 令 上图表示“文件包含”的含意。图9.2(a)为文件file1.C,它 有一个#inClude 命令,然后还有其他内容(以A 表示)。图9.2(B)为另一文件file2.C,文件内容以B表示 。在编译预处理时,要对#inClude命令进行“文件包含” 处理:将file2.C的全部内容复制插入 第8章 预 处 理 命 令 到#inClude 命令处,即file2.C被包含到file1.C 中,得到图9.2(C)所示的结果。在编译中,将“包含”以 后的file1.C(即图9.2(C)所示)作为一个源文件单位进行编 译。 “文件包含”命令是很有用的,它可以节省程序设计人员的 重复劳动。例如,某一单位的人员往往使用一组固定的 符号常量(如G=9.81,pi=3.1415926,e=2.718,C=) ,可以把这些宏定义命令组成一个文件,然后各人都可 以用#inClude命令将这些符号常量包含到自己所写的源 文件中。这样每个人就可以不必重复定义这些符号常量 。相当于工业上的标准零件,拿来就用。 第8章 预 处 理 命 令 例8.6可以将例8.5程序改为: (1) 文件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“ 第8章 预 处 理 命 令 (2) 文件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); 第8章 预 处 理 命 令 注意: 在编译时并不是作为两个文件进行连接的,而是作为一个源 程序编译,得到一个目标(.oBj)文件。因此被包含的文件也应该 是源文件而不应该是目标文件。 这种常用在文件头部的被包含的文件称为“标题文件”或“ 头部文件”,常以“h”为后缀(h为heaD(头)的缩写),如 “format.h”文件。当然不用“.h”为后缀,而用“C”为后缀 或者没有后缀也是可以的,但用“h”作后缀更能表示此文件的 性质。 如果需要修改一些常数,不必修改每个程序,只需修改一个 文件(头部文件)即可。但是应当注意,被包含文件修改后,凡包 含此文件的所有文件都要全部重新编译。 第8章 预 处 理 命 令 头文件除了可以包括函数原型和宏定义外,也可以包括结构体类型 定义(见第10章)和全局变量定义等。 说明: (1) 一个inClude命令只能指定一个被包含文件,如果要包含n个文 件,要用n个inClude命令。 (2) 如果文件1包含文件2,而文件2中要用到文件3的内容,则可在 文件1中用两个inClude命令分别包含文件2和文件3,而且文件3 应出现在文件2之前,即在file1.C中定义: #inClude “file3.h“ #inClude “file2.h“ 第8章 预 处 理 命 令 这样,file1和file2都可以用file3的内容。在file2中不必再用 #inClude 了(以上是假设file2.h在本程序中只被 file1.C包含,而不出现在其他场合)。 (3) 在一个被包含文件中又可以包含另一个被包含文件,即文件包 含是可以嵌套的。例如,上面的问题也可以这样处理,见图9.3 。它的作用与图9.4所示相同。 图9.3 第8章 预 处 理 命 令 图9.4 (4) 在#inClude命令中,文件名可以用双引号或尖括号括起来 ,如可以在file1.C中用 #inClude 或#inClude “file2.h“都是合法的。二者的区别是用尖括弧(即 形式)时,系统到存放C库函数头文件所在的目录 中寻找要包含的文件,这称为标准方式。用双引号(即 “file2.h”形式)时,系统先在用户当前目录中寻找要包含 的文件,若找不到,再按标 第8章 预 处 理 命 令 准方式查找(即再按尖括号的方式查找)。一般说,如果为 调用库函数而用#inClude命令来包含相关的头文件,则用 尖括号,以节省查找时间。如果要包含的是用户自己编写 的文件(这种文件一般都在当前目录中),一般用双引号。 (5) 被包含文件(file2.h)与其所在的文件(即用#inClude命 令的源文件file1.C),在预编译后已成为同一个文件(而 不是两个文件)。因此,如果file2.h中有全局静态变量, 它也在file1.C文件中有效,不必用extern声明。 第8章 预 处 理 命 令 一般情况下,源程序中所有的行都参加编译。但是有时希望 对其中一部分内容只在满足一定条件才进行编译,也就是对一部 分内容指定编译的条件,这就是“条件编译”。有时,希望当满 足某条件时对一组语句进行编译,而当条件不满足时则编译另一 组语句。 条件编译命令有以下几种形式: (1) #if def标识符 程序段1 #else 程序段2 #end if 8.3 条件编译(重点/掌握) 第8章 预 处 理 命 令 它的作用是当所指定的标识符已经被#define命令定义过,则在程 序编译阶段只编译程序段1,否则编译程序段2。其中#else部分 可以没有,即#if def标识符程序段1#endif这里的“程序段”可 以是语句组,也可以是命令行。这种条件编译对于提高C源程序 的通用性是很有好处的。如果一个C源程序在不同计算机系统上 运行,而不同的计算机又有一定的差异(例如,有的机器以16位 (2个字节)来存放一个整数,而有的则以32位存放一个整数),这 样往往需要对源程序作必要的修改,这就降低了程序的通用性。 可以用以下的条件编译来处理: 第8章 预 处 理 命 令 #if def COMPUTER-A #define INTEGER-SIZE 16 #else #define INTEGER-SIZE 32 #end if 即如果COMPUTER-A 在前面已被定义过,则编译下面的命令行: #define INTEGER-SIZE 16 否则,编译下面的命令行: #define INTEGER-SIZE 32 如果在这组条件编译命令之前曾出现以下命令行: #define COMPUTER-A 0 第8章 预 处 理 命 令 或将COMPUTER-A定义为任何字符串,甚至是#define COMPUTER-A则 预编译后程序中的INTEGER-SIZE都用16代替,否则都用32代替。 这样,源程序可以不必作任何修改就可以用于不同类型的计算机系 统。当然以上介绍的只是一种简单的情况,读者可以根据此思路 设计出其他的条件编译。 例如,在调试程序时,常常希望输出一些所需的信息,而在调试完 成后不再输出这些信息。可以在源程序中插入以下的条件编译段 : #if def DEBUG Printf(“x=%D,y=%D,Z=%Dn“,x,y,Z); 第8章 预 处 理 命 令 #end if 如果在它的前面有以下命令行: #define DEBUG 则在程序运行时输出x、y、Z的值,以便调试时分析。调试完成 后只需将这个define命令行删去即可。有人可能觉得不用条 件编译也可达此目的,即在调试时加一批printf语句,调试 后一一将printf语句删去。的确,这是可以的。但是,当调 试时加的printf语句比较多时,修改的工作量是很大的。用 条件编译,则不必一一删改printf语句,只需删除前面的一 条“#define DEBUG”命令即可,这时所有的用DEBUG作标识 符的条件编译段都使其中的printf语句不起作用,即起统一 控制的作用,如同一个“开关”一样。 第8章 预 处 理 命 令 (2) #ifndef标识符 程序段1 #else 程序段2 #end if 只是第一行与第一种形式不同:将“ifdef”改为“ifndef” 。它的作用是若标识符未被定义过则编译程序段1,否则编 译程序段2。这种形式与第一种形式的作用相反。 第8章 预 处 理 命 令 以上两种形式用法差不多,根据需要任选一种,视方便而定 。例如,上面调试时输出信息的条件编译段也可以改为 #ifndef RUN printf(“x=%D,y=%D,Z=%Dn“,x,y,Z); #endif 如果在此之前未对RUN定义,则输出x、y、Z的值。调试完成 后,在运行之前,加以下命令行: #define RUN 则不再输出x、y、Z的值。 第8章 预 处 理 命 令 (3) #if表达式 程序段1 #else 程序段2 #endif 它的作用是当指定的表达式值为真(非零)时就编译程序段1, 否则编译程序段2。可以事先给定一定条件,使程序在不同 的条件下执行不同的功能。 例9.7输入一行字母字符,根据需要设置条件编译,使之能将 字母全改为大写输出,或全改为小写字母输出。 第8章 预 处 理 命 令 #define LETTER 1 main() char str20=“C LanGuaGe“,C; int i; i=0 while (C=str i)!=0) i+; #if LETTER 条件编译 if(C=a #else if(C=A #endif 第8章 预 处 理 命 令 printf(“%C“,C); 运行结果为: CLANGUAGE 现在先定义LETTER为1,这样在对条件编译命令进行预处 理时,由于LETTER为真(非零),则对第一个if语句进行编 译,运行时使小写字母变大写。如果将程序第一行改为 #defineLETTER0则在预处理时,对第二个if语句进行编译 处理,使大写字母变成小写字母(大写字母与相应的小写字 母ASCII代码差32)。此时运行情况为ClanGuaGe 第8章 预 处 理 命 令 有的读者可能会问,不用条件编译命令而直接用if语句也能 达到要求,用条件编译命令有什么好处呢?的确,此问题 完全可以不用条件编译处理,但那样做目标程序长(因为 所有语句都编译),运行时间长(因为在程序运行时对if语 句进行测试)。而采用条件编译,可以减少被编译的语句 ,从而减少目标程序的长度,减少运行时间。当条件编译 段比较多时,目标程序长度可以大大减少。 本章介绍的预编译功能是C语言特有的,有利于程序的可移 植性,增加程序的灵活性。 第8章 预 处 理 命 令 习题 9.1 定义一个带参数的宏,使两个参数的值互换,并写出程序,输入 两个数作为使用宏时的实参。输出已交换后的两个值。 9.2 输入两个整数,求它们相除的余数。用带参的宏来实现,编程 序。 第8章 预 处 理 命 令 9.3 给年份year,定义一个宏,以判别该年份是否闰年。提 示:宏名可定为LEAP-YEAR,形参为y,即定义宏的形式为 # define LEAP-YEAR(y) (读者设计的字符串) 在程序中用以下语句输出结果: if (LEAP-YEAR(year) printf (“%D iS a leap year“,year); else printf (“%D iS not a leap year“,year); 第8章 预 处 理 命 令 9.4 请分析以下一组宏所定义的输出格式: # define NL putchar (n) # define PR (format,value)printf (“value=%formatt“,(value) # define PRINT1(f,x1) PR(f,x1);NL #define PRINT2 (f,x1,x2)PR (f,x1);PRINT1(f,x2) 如果在程序中有以下的宏引用: PR (D,x); PRINT 1(D,x); PRINT 2(D,x1,x2); 写出宏展开后的情况,并写出应输出的结果,设 x=5,x1=3,x2=8。 第8章 预 处 理 命 令 9.5 设计所需的各种各样的输出格式(包括整数、实数、字符串等 ),用一个文件名“

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论