C语言程序设计实验指导 教学课件 ppt 作者 唐新来 王萌第9章预编译和位运算

上传人:w****i 文档编号:94357543 上传时间:2019-08-06 格式:PPT 页数:48 大小:108.50KB
返回 下载 相关 举报
C语言程序设计实验指导 教学课件 ppt 作者 唐新来 王萌第9章预编译和位运算_第1页
第1页 / 共48页
C语言程序设计实验指导 教学课件 ppt 作者 唐新来 王萌第9章预编译和位运算_第2页
第2页 / 共48页
C语言程序设计实验指导 教学课件 ppt 作者 唐新来 王萌第9章预编译和位运算_第3页
第3页 / 共48页
C语言程序设计实验指导 教学课件 ppt 作者 唐新来 王萌第9章预编译和位运算_第4页
第4页 / 共48页
C语言程序设计实验指导 教学课件 ppt 作者 唐新来 王萌第9章预编译和位运算_第5页
第5页 / 共48页
点击查看更多>>
资源描述

《C语言程序设计实验指导 教学课件 ppt 作者 唐新来 王萌第9章预编译和位运算》由会员分享,可在线阅读,更多相关《C语言程序设计实验指导 教学课件 ppt 作者 唐新来 王萌第9章预编译和位运算(48页珍藏版)》请在金锄头文库上搜索。

1、第9章 预编译和位运算,2019年8月6日星期二,在学习和编写C语言源程序的时候,我们通常会遇到和用到一些如 #include,#define等之类的命令,这些以“#”开头的命令我们称之为预编译命令。预编译命令不是C语言本身组成的部分,所以在使用时以“#”开头,以示和C语言区别。 预编译又称为预处理,是指对C语言源程序进行词法扫描和语法分析之前,首先对预编译命令进行处理,然后再进行编译以得到目标代码。,预编译处理是C语言编译系统的一个重要的功能,它主要包含宏定义、文件包含和条件编译。这三个功能分别用宏定义命令,文件包含命令和条件编译命令来实现。在程序中正确适当地使用预编译处理功能可使程序易读、

2、易改、易移植、易调试,也有利于模块化程序设计,从而可以有效地提高程序的开发效率。下面我们就用一些简单易懂的例子来讲解这三种常用的预编译处理功能。本章的例子和源程序均在Visual C+6.0开发环境下运行。,9.1 宏定义 9.2 文件包含 9.3 条件编译 9.4 位运算,9.1 宏定义,宏定义是指用一个指定的标识符来代表一个字符串,这里的标识符叫做“宏名”。预编译时将宏名替换成字符串的过程叫“宏展开”。宏定义又分为不带参数和带参数两种,下面将分别介绍。,9.1.1不带参数宏定义,不带参数宏定义的一般形式为: #define 标识符 字符串 其中,上述形式的标识符也称为“常量标识符”或“符号

3、常量符”。它的功能是在程序的开头使用,将指定的常量表达式进行符号化的替换,使该符号常量有一定的标识意义。 例如: #define F (y*y-8*y) 表示将表达式(y*y-8*y)在程序中由标识符F代替。在编写源程序时,所有的(y*y-8*y)都可由F代替,而对源程序作编译时,将先由预处理程序进行宏代换,即用(y*y-8*y)表达式去置换所有的宏名F,然后再进行编译。,【例9.1】不带参数宏定义举例。 #define F (y*y-8*y) int main( ) int s,y; printf(“input a number: “); scanf(“%d“, 运行结果如下: input

4、a number:3 s=-135,使用不带参数宏定义时我们还应该注意: (1)习惯上宏名用大写字母表示,以便于与变量区别。但也允许用小写字母。 (2) 宏定义不是说明或语句,在行末不必加分号,如加上分号则连分号也一起进行置换。 (3) 宏定义是用宏名来表示一个字符串,在宏展开时又以该字符串取代宏名,这只是一种简单的代换,字符串中可以含任何字符,可以是常数,也可以是表达式,预处理程序对它不作任何检查。如有错误,只能在编译已被宏展开后的源程序时发现。,(4)宏定义必须写在函数之外,其作用域为宏定义命令起到源程序结束。如果要终止其作用域可使用# undef命令。 例如: #define AGE 3

5、0 int main() int a; return 0; #undef AGE void max() 上述程序段表示AGE只在main函数中有效,在函数max中无效。,(5) 宏名在源程序中若用引号括起来,则预处理程序不对其作宏代换。 例如: #define AGE 20 #include int main() printf(“AGE“); printf(“n“); return 0; 运行结果如下: AGE 上面程序定义宏名AGE表示20,但在printf语句中AGE被引号括起来,因此不作宏代换。此时“AGE”是字符串而不是宏名,不作宏替换,(6)宏定义允许嵌套,在宏定义的字符串中可以使用

6、已经定义的宏名。在宏展开时由预处理程序层层代换。 例如: #define M 100 #define N (M+r*r) /*M是已定义的宏名*/ 对语句: printf(“%d“,N); 在宏代换后变为: printf(“%d“,100+r*r);,9.1.2带参数宏定义,带参数宏定义的一般形式为: #define 宏名(参数表) 字符串,【例9.2】带参数宏定义举例。 #include #define SUB(a,b) a*b int main() int c; c=SUB(2,3); printf(“%d”,c); return 0; 运行结果如下: 6,带参数的宏与函数有许多相似之处,

7、但两者有本质区别: (1)函数调用时,先求出实参表达式的值,再把此值传递给形参;二使用带参数的宏时,只是简单的字符替换然后代入形参,而使用带参的宏只是进行简单的字符替换。 例如: #define SQ(x) (x)*(x) 在程序中执行语句: Z=SQ(a+b); 对宏展开得: z=(a+b)*(a+b); 在宏替换时,只是用参数符“a+b”替换形参x,但并不求表达式a+b的值。,(2)函数调用是在程序运行时处理的,为形参分配临时的内存单元。而宏展开则是在编译前进行的,在展开时并不分配内存单元,不进行值的传递处理,也没有返回值的概念。 (3)宏替换不占运行时间,只占编译时间,而函数调用则占运行

8、时间(分配单元,保留现场,值传递,返回)。 (4)使用宏次数多时,宏展开后源程序长,因为每展开一次都使程序增长,而函数调用不会这样。,(5)对函数中的实参和形参都要定义类型,二者的类型要求一致,如不一致,应进行类型转换;而宏不存在类型问题,宏名无类型,它的参数也无类型,只是一个符号代表,展开时代入指定的字符串即可。宏定义时,字符串可以是任何类型的数据。,9.2 文件包含,文件包含是指一个源程序文件可以将另外一个源程序文件的全部内容包含进来,即将另外的一个文件嵌入到本文件之中。其一般格式为: #include “文件名“ 功能:根据“文件名“,把指定文件的全部内容读到当前处理的文件中,作为当前文

9、件的一个组成部分,即用文件的内容替代该#include命令行。,【例9.3】输入三个整数x,y,z,请把这三个数由小到大输出。 分析:我们可以建立max.h和mainfile.c两个文件。 文件max.h的内容为: void a(int x,int y,int z) int z; if(xy) t=x;x=y;y=t; / *交换x,y的值* / if(xz) t=z;z=x;x=t; / *交换x,z的值* / if(yz) t=y;y=z;z=t; / *交换z,y的值* / printf(“small to big: %d %d %dn“,x,y,z); 文件mainfile.c的内容为

10、: #include /* 包含输入输出头文件stdio.h */ #include “ max.h“ /* 包含文件max.h */ int main() int i,j,k; scanf(“%d%d%d“, ,源程序文件mainfile.c中有文件包含命令:#include “max.h“ 处理程序将#include “max.h“文件的全部内容复制并插入到mainfile.c文件中的#include “max.h“命令处,即max.h被包含到mainfile.c中,并将包含max.h后的mainfile.c文件作为一个源程序文件来处理。 上面的程序预编译预处理后,文件mainfile.c

11、变为如下形式:,#include /* 由于stdio.h头文件是由C系统提供的,所以此处不再将该文件展开 */ void a(int x,int y,int z) int z; if(xy) t=x;x=y;y=t; /*交换x,y的值*/ if(xz) t=z;z=x;x=t;/*交换x,z的值*/ if(yz) t=y;y=z;z=t;/*交换z,y的值*/ printf(“small to big: %d %d %dn“,x,y,z); int main() int i,j,k; scanf(“%d%d%d“, ,经过预编译预处理后,文件max.h被插入到文件mainfile.c中的#

12、include “max.h“处。常把在文件头部的被包含文件称为“标题文件”或“头文件”,常以”.h”作为文件的扩展名,当然也可以使用其他的扩展名。,使用文件包含时应该注意: (1)在#include命令中,文件名用双引号或尖括号括起来都是合法的。两者的区别是:用尖括号时,系统直接到存放C库函数头文件所在的目录(即include目录)中查找要包含的文件,这称为标准方式;用双引号时,系统先在用户当前工作目录中查找要包含的文件,这称为用户方式,若找不到再按标准方式查找(即再按尖括号的方式查找)。所以,一般来说,如果为调用库函数而用#include命令来包含相关的文件,则用尖括号,以节省查找时间;如

13、果要包含的是用户自己编写的文件(这种文件一般都在当前工作目录中),则用双引号。这里使用的双引号必须为英文双引号。,(2)#include只能指定一个被包含文件,如果要包含n个文件,则要用n个#include命令。 (3)通常,将文件包含命令放在源程序文件开始部分。一个被包含文件中又可以包含另一个被包含文件,即文件包含是可以嵌套的。 (4)文件包含主要在两种情况下使用,一是在程序文件要用到C的库函数时,必须把含有该库函数的头文件包含到本文件中,例如,要实现输入/输出时必须包含头文件” stdio.h”,要使用数学函数时必须包含头文件”math.h”;二是在设计一个大型程序时,可将程序公用的一些数

14、据结构、输出格式定义成头文件,然后在相应的处理程序中,用文件包含命令将相应的头文件包含进来。,9.3 条件编译,一般情况下,源程序中的所有行都参加编译。但有时希望对其中一部分内容只在满足一定条件才进行编译,也就是对一部分内容指定编译的条件,这就是条件编译。预处理程序提供了条件编译的功能。可以按不同的条件去编译不同的程序部分,因而产生不同的目标代码文件,这样非常有利于程序的移植和调试。下面将叙述三种比较常用的条件编译命令。,9.3.1 #ifdef命令,#ifdef命令可以理解为“如果定义过”,常见形式为: #ifdef 标识符 程序段1 #else 程序段2 #endif 作用是:当标识符已经

15、被定义过(一般是用#define命令定义),则对程序段1进行编译,否则编译程序段2。,【例9.4】#ifdef命令举例。 #include #define A 10 int main() #ifdef A /如果定义了A printf(“YES”); #else printf(“NO“); #endif return 0; 运行结果如下: YES,9.3.2 #ifndef命令,#ifndef命令与#ifdef命令的表达的意思恰好相反,可以理解为“如果没有被定义过”,常见形式为: #ifndef 标识符 程序段1 #else 程序段2 #endif 这种形式只是第一行与9.3.1小节的那种形式

16、不同:将“ifdef”改为“ifndef”。它的作用是:若标识符未被定义则编译程序段1,否则编译程序段2。这种形式与与9.3.1小节那种形式的作用相反。,9.3.3 #if指令,#if指令功能是:如果表达式为真,则编译后面的代码,直到出现#else #endif为止;否则就不编译。 #endif用于终止#if预处理指令。这样可以事先给定一定条件,使程序在不同的条件下执行不同的功能。常见形式为: #if 常量表达式 程序段1 #else 程序段2 #endif,【例9.5】 输入一行字母字符,根据需要设置条件编译,使之能将字母全改为大写输出,或全改为小写字母输出。 源程序如下: #include #define FLAG 1 int main() char str20=“Hello“; char c; int i=0; while(c=stri)!=0) i+; #if

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 高等教育 > 大学课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号