内容正文:
1.7节:宏定义和文件包含
编程语言基础——C语言
同步精品课堂
高教版(第5版)
掌握国家标准《机械制图》中有关图幅、比例、字体图线等基本规定。
教学目标
一
03
掌握带参数宏定义及其使用方法
了解文件包含的定义和操作步骤
04
掌握不带参数宏定义及其使用方法
02
了解C语言的编译预处理的含义和分类
01
教学重难点
二
03
了解文件包含的使用
了解用户自定义头文件的方法和步骤
04
掌握宏定义在使用过程中需要注意的事项
02
掌握宏定义的使用方法
01
导入新课
三
从 “重复代码” 到 “宏定义与文件包含” 的高效编程
在编程时,遇到大量重复的常量、公式或头文件,你会怎么处理?
例 1:计算圆面积时,反复写3.14159
例 2:多个文件都需要引用stdio.h
编程小困惑?
C 语言提供了宏定义和文件包含两种工具,帮我们解决 “重复代码冗余” 的问题。
宏定义:把重复内容 “批量替换”,让代码更简洁
文件包含:把外部文件 “整合” 到当前代码,避免重复编写
C 语言的 “高效解法”
新知讲授
四
知识点1:宏定义
宏定义和文件包含都属于编译预处理命令,以“#”开头,结尾部分不要加分号(除非有特别需要)。编译预处理命令的作用不是实现程序的功能,而是给C语言编译系统提供信息,通知C编译器在对源程序进行编译之前应该做哪些预处理工作。
C语言提供的预处理功能主要有以下三种:
1.宏定义
2.文件包含
3.条件编译
我们今天一起来学习“宏定义”和“文件包含”。
概述
新知讲授
四
知识点1:宏定义
1、不带参数的宏定义
(1)命令的一般形式:
#define 标识符 字符串
(2)概述:
一般形式中的“标识符”为用户定义标识符,称为“宏名”,宏名一般使用大写字母,在预编译时,将程序中出现的宏名均替换成“字符串”的内容,这一过程称为宏展开。
(3)举例
#define PI 3.1415926
/* 在程序中凡遇到“PI”均用字符串“3.1415926”代替。如“2*PI*r”宏展开为“2*3.1415926*r”。
新知讲授
四
知识点1:宏定义
1、不带参数的宏定义
#include<stdio.h>
#define PI 3.1415926
void main()
{
float l,s,r,v;
printf("input radius:");
scanf("%f",&r);
l=2.0*PI*r;
s=PI*r*r;
v=4.0/3*PI*r*r*r;
printf("l=%10.4f
s=%10.4f
v=%10.4f
",l,s,v);
}
在主函数中,所有的PI均使用字符串3.1415926代替,最后参与运算得出结果后输出至屏幕
新知讲授
四
知识点1:宏定义
宏定义是否能添加分号(;)?
#define是宏定义命令,但它不是C语句,不必在行末加分号,如果加了分号,则会连着分号一起置换。
#include<stdio.h>
#define PI 3.1415926
main()
{
double area,r=1.5;
area=PI*r*r;
printf("%f
",area); }
#include<stdio.h>
#define PI 3.1415926;
main()
{
double area,r=1.5;
area=PI*r*r;
printf("%f
",area); }
错误原因:分号无法计算,产生语法错误。
宏展开为:
area=3.1415926;*r*r
新知讲授
四
知识点1:宏定义
宏定义中“宏名”必须大写?
习惯上,符号常量名用大写表示,当然也可以使用小写,但前后必须一致,否则将出现语法错误。
#include<stdio.h>
#define PI 3.1415926
main()
{
double area,r=1.5;
area=pi*r*r;
printf("%f
",area); }
该程序在编译时会产生错误“[Error] ‘pi’ was not declared in this scope”,意思是:[错误] ‘pi’ 未在此作用域内声明。错误原因是C语言对大小写敏感,PI和pi的意义是不同的,在编写程序时,需要特别注意。
新知讲授
四
知识点1:宏定义
1、不带参数的宏定义
说明:
①宏名一般习惯用大写字母表示,以便与变量名相区别,但这并非规定,也可用小写字母。
②使用宏名代替一个字符串,可以减少程序中重复书写某些字符串的工作量,用宏名代替,简单不易出错,要比记住一个无规律的字符容易。
③当需要改变某一个常量时,可以只改变#define命令行,具有“一改全改”的特点。
④宏定义是用宏名代替一个字符串,只做简单的置换,在预编译时不作正确性检查,只有在编译已被宏展开后的源程序时才会发现语法错误并报错。
⑤宏定义不是C语句,不必在行末添加分号,除非有特殊置换分号的要求。
⑥#define命令定义后,宏名的有效范围为定义命令之后到本源文件结束。
新知讲授
四
知识点1:宏定义
1、不带参数的宏定义
说明:
⑦在进行宏定义时,可以引用已定义的宏名,可以层层置换。
#include<stdio.h>
#define R 3.0
#define PI 3.1415926
#define L 2*PI*R
#define S PI*R*R
void main()
{
printf("L=%f
S=%f
",L,S);
/*printf("L=%f
S=%f
",2*3.1415926*3.0,3.1415926*3.0*3.0);*/
}
经过宏展开后,printf函数中的输出项L被展开为“2*3.1415926*3.0”;S展开为“3.1415926*3.0*3.0”。
新知讲授
四
知识点1:宏定义
1、不带参数的宏定义
说明:
⑧对程序中printf语句内用双撇号括起来的字符串内的字符,即使与宏名相同,也不进行置换。因其是非格式符(第二章节数据输入的内容)
⑨宏定义是专门用于预处理命令的一个专用名词,它与定义变量的含义不同,只作字符替换,不分配内存空间。
#include<stdio.h>
#define R 3.0
#define PI 3.1415926
#define L 2*PI*R
#define S PI*R*R
void main()
{
printf("L=%f
S=%f
",L,S);
}
不参与置换
参与置换
新知讲授
四
知识点1:宏定义
2、带参数的宏定义
(1)命令的一般形式:
#define 宏名(形式参数表) 字符串
(2)概述:
定义中的“字符串”应包含括号中所指定的形式参数。
(3)带参数的宏展开
预编译时,遇到带实参的宏名,则按命令行中指定的字符串从左到右进行转换,原则是:凡遇形参则以实参代替,非形参字符则原样保留,从而形成展开后的内容。
(4)举例:#define AREA(r) PI*(r)(r)
则“AREA(3+2)”宏展开后变成“3.1415926*(3+2)*(3+2)”
宏名与括号之间不要添加空格,否则就成为不带参数的宏定义了。
新知讲授
四
知识点1:宏定义
例1-3:求梯形的面积
说明:梯形的面积为上底加下底乘高除2。设梯形的上底、下底和高分别用a、b和h表示,则梯形的面积等于(a+b)*h/2.0。
#include<stdio.h>
#include<conio.h>
#define S(a,b,h) (a+b)*h/2.0 //带参宏定义
main() //定义主函数
{ //函数体开始
double y; //定义双精度型变量y
y=S(2,3,5); //带参宏的使用
printf(“梯形面积=%f
”,y);//输出
getch(); //按任意键结束
} //main函数结束
新知讲授
四
知识点1:宏定义
例题:通过宏展开可以得到若干个结果。
#include<stdio.h>
#define PI 3.1415926
#define CIRCLE(R,L,S,V) L=2*PI*R;S=PI*R*R;V=4.0/3.0*PI*R*R*R
void main()
{ float r,l,s,v;
scanf("%f",&r);
CIRCLE(r,l,s,v);
printf("r=%6.2f,l=%6.2f,s=%6.2f,v=%6.2f
",r,l,s,v);
}
宏展开:l=2*3.1415926*r;s=3.1415926*r*r;v=4.0/3.0*3.1415926*r*r*r;
新知讲授
四
知识点2、文件包含
文件包含的作用与格式
(1)作用:
将一个源程序文件包含到另一个源程序文件中,它以“#include”开头。
(2)格式:
格式1:#include<文件名>
作用:使用格式1时,C编译系统将在系统指定的路径下搜索尖括号中的文件,一般适用于包含库函数的头文件。
格式2:#include“文件名”
作用:使用格式2时,系统首先会在用户当前的目录中搜索双引号中的文件,如果找不到,再按系统指定的路径下搜索,一般适用于包含用户文件的头文件。
数学函数 math.h 字符串函数 string.h
随机函数 stdlib.h 输入输出函数 stdio.h
字符函数 ctype.h 动态存储分配函数 malloc.h
新知讲授
四
知识点2、文件包含
用户能否根据自身需求创建头文件?
在Visual C++ 2010平台上,用户可以根据自身的需求创建头文件,创建步骤如下:
操作步骤:
(1)在Visual C++ 2010的“解决方案资源管理器”中,右键单击“头文件”,选择“添加”→“新建项”,选择“头文件(.h)”,输入名称“prt”,单击“添加”按钮返回主菜单,并在prt.h中输入内容:#define INT(a) printf(“%d ”,a),具体操作步骤如视频所示:
师生互动
五
互动挑战:宏定义与文件包含 “小侦探”
【规则】
(1)全班分为 2 组,每组派 1 名代表上台答题;
(2)针对题目中的代码片段,判断 “宏定义 / 文件包含” 是否正确,并说明理由;
(3)回答正确得 2 分,错误不扣分,最终得分高的组获 “代码侦探组” 称号。
序号 代码片段 小组判断(正确 / 错误)并说出理由
1 #define PI 3.14159
area = PI * r * r;
2 #define S(a,b,h) a*b*h
s = S(2,3,4);
3 #include "myfunc.c"
4 #define M(a,b) a*b
max = M(5,10);
5 #include <stdio.h>
随堂练习
六
1.以下关于不带参数宏定义的一般形式,正确的是( )
A.#define 宏名 字符串
B. define 宏名 字符串
C. #define 宏名(参数) 字符串
D. define 宏名(参数) 字符串
答案:A
解析:不带参数宏定义的一般形式是#define 宏名 字符串,#define是宏定义的关键字,且不带参数时无括号。
随堂练习
六
2.若有宏定义#define PI 3.14,则表达式2*PI的值为( )
A. 6.14
B. 6.28
C. 3.14
D. 语法错误
答案:B
解析:宏展开时PI会被替换为3.14,因此2*3.14=6.28。
随堂练习
六
3.带参数宏定义的一般形式是( )
A. #define 宏名 字符串
B. #define 宏名(参数表) 字符串
C. define 宏名(参数表) 字符串
D. #define 宏名 参数表 字符串
答案:B
解析:带参数宏定义需要在宏名后加括号包含参数表,形式为#define 宏名(参数表) 字符串。
随堂练习
六
4.若有宏定义#define S(a,b) a*b,则S(2+3,4)的展开结果是( )
A. 2+3*4
B. (2+3)*4
C. 2+34
D. 语法错误
答案:A
解析:带参数宏是简单文本替换,S(2+3,4)会直接替换为2+3*4,需注意宏定义的优先级问题。
随堂练习
六
5.为避免带参数宏的优先级问题,合适的宏定义方式是( )
A. #define S(a,b) a*b
B. #define S(a,b) (a)*(b)
C. #define S a*b
D. #define S(a,b) a*(b)
答案:B
解析:将每个参数和整体都用括号包裹,可避免运算优先级错误,如(a)*(b)能保证a和b先运算。
随堂练习
六
6.若有宏定义#define N 5,#define M N+3,则M*2的结果是( )
A. 16
B. 13
C. 5+3*2
D. 语法错误
答案:C
解析:宏替换为N+3*2即5+3*2,若要得到(5+3)*2,需定义#define M (N+3)。
随堂练习
六
7.以下文件包含的格式中,用于包含系统头文件的是( )
A. #include"stdio.h“
B. #include<stdio.h>
C. #include stdio.h
D. include<stdio.h>
答案:B
解析:#include<文件名>用于包含系统头文件,编译器从系统目录查找;"文件名"用于用户自定义头文件。
随堂练习
六
8.若用户创建了一个自定义头文件myhead.h,正确的包含方式是( )
A. #include<myhead.h>
B. #include"myhead.h“
C. #include myhead.h
D. include"myhead.h"
答案:B
解析:用户自定义头文件用双引号" "包含,编译器先从当前目录查找。
随堂练习
六
9.若有宏定义#define F(x) x*x,则F(2+3)的结果是( )
A. 25
B. 13
C. 2+3*2+3
D. 语法错误
答案:C
解析:宏展开为2+3*2+3,计算得2+6+3=11,若要得到(2+3)*(2+3),需定义#define F(x) (x)*(x)。
随堂练习
六
10.若有宏定义#define ADD(a,b) a+b,则ADD(2,3)*4的结果是( )
A. 20
B. 14
C. 2+3*4
D. 语法错误
答案:B
解析:宏展开为2+3*4=2+12=14,若要得到(2+3)*4,需定义#define ADD(a,b) (a+b)。
课堂小结
七
谢谢
EV录屏5.4.2软件录制
Lavf58.33.100
本视频由湖南一唯信息科技开发的EV录屏软件录制, www.ieway.cn
EV录屏5.4.2软件录制
Lavf58.33.100
本视频由湖南一唯信息科技开发的EV录屏软件录制, www.ieway.cn
EV录屏5.4.2软件录制
Lavf58.33.100
本视频由湖南一唯信息科技开发的EV录屏软件录制, www.ieway.cn
EV录屏5.4.2软件录制
Lavf58.33.100
本视频由湖南一唯信息科技开发的EV录屏软件录制, www.ieway.cn
EV录屏5.4.2软件录制
Lavf58.33.100
本视频由湖南一唯信息科技开发的EV录屏软件录制, www.ieway.cn
EV录屏5.4.2软件录制
Lavf58.33.100
本视频由湖南一唯信息科技开发的EV录屏软件录制, www.ieway.cn
EV录屏5.4.2软件录制
Lavf58.33.100
本视频由湖南一唯信息科技开发的EV录屏软件录制, www.ieway.cn
$