C语言程序设计教案 第九章 编译预处理
- 格式:doc
- 大小:46.50 KB
- 文档页数:6
第9章编译预处理本章要求:1、熟悉宏定义与宏扩展。
a宏与函数的区别。
2、熟悉文件包含命令#include的作用及其预处理方法。
3、熟悉条件编译的使用。
概述编译预处理:在源程序文件中,加入“编译预处理命令”,使编译程序在对源程序进行通常的编译(包括词法分析、语法分析、代码生成、代码优化)之前,先对这些命令进行预处理,然后将预处理的结果和源程序一起再进行通常的编译处理,以得到目标代码(OBJ文件)。
C提供的编译预处理命令:宏命令(Macro)、文件包含命令(include)、条件编译命令这些命令均以#开头,以区别于语句。
9.1 宏定义(Macro)一、不带参数的宏一般形式: #define 标识符字符串如: #define PI 3.1415926作用:用标识符(称为“宏名”)PI代替字符串“3.1415926”。
在预编译时,将源程序中出现的宏名PI替换为字符串“3.1415926”,这一替换过程称为“宏展开”。
#define:宏定义命令#undef:终止宏定义命令[例9.1]#define PI 3.1415926main(){ float l,s,r,v;printf("input radius:");scanf("%f",&r); /* 输入圆的半径*/l = 2.0*PI*r; /* 圆周长*/s = PI*r*r; /* 圆面积*/v = 4.0/3.0*PI*r*r*r; /* 球体积*/printf("l=%10.4f\ns=%10.4f\nv=%10.4f\n",l,s,v);}关于宏定义的说明:1、一般宏名用大写字母表示。
(变量名一般用小写字母)。
2、使用宏可以提高程序的可读性和可移植性。
如上述程序中,多处需要使用π值,用宏名既便于修改又意义明确。
3、宏定义是用宏名代替字符串,宏扩展时仅作简单替换,不检查语法。
语法检查在编译时进行。
第九章编译预处理课题:第九章编译预处理教学目的:1、了解预处理的概念及特点2、掌握有参宏与无参宏的定义及使用,领会文件包含的使用及效果教学重点:教学难点:掌握宏的使用,文件包含有参宏与无参宏的使用步骤一复习引导ANSI C标准规定可以在C源程序中加入一些“预处理命令”,以改进程序设计环境,提高编程效率。
这些预处理命令是由ANSI C统一规定的,但它不是C语言本身的组成部分,不能直接对它们进行编译。
必须在对程序进行通常的编译之前,先对程序中这些特殊的命令进行“预处理”,即根据预处理命令对程序作相应的处理。
经过预处理后程序不再包括预处理命令了,最后再由编译程序对预处理后的源程序进行通常的编译处理,得到可供执行的目标代码。
步骤二讲授新课C语言与其他高级语言的一个重要区别是可以使用预处理命令和具有预处理的功能。
C 提供的预处理功能主要有以下三种:宏定义、文件包含、条件编译。
分别用宏定义命令、文件包含命令、条件编译命令来实现。
为了与一般C语句相区别,这些命令以符号“ #” 开头。
§9.1宏定义宏:代表一个字符串的标识符。
宏名:被定义为“宏”的标识符。
宏代换(展开):在编译预处理时,对程序中所有出现的“宏名”,用宏定义中的字符串去代换的过程。
一、不带参数的宏定义一般形式:#define 标识符字符串#define PI 3.1415926main(){ 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语言程序设计》教案(清华谭浩强)第一章:C语言概述1.1 课程介绍介绍C语言的历史和发展解释C语言的特点和应用范围强调学习C语言的重要性和目的1.2 C语言的基本概念解释编程语言和编译器的概念介绍C语言的基本数据类型和变量讲解C语言的语法结构和程序结构1.3 C语言的编译过程解释编译器的角色和功能介绍编译过程中的预处理、编译、汇编和步骤强调编译过程中产生的文件和它们的作用第二章:基本数据类型和运算符2.1 基本数据类型介绍整型、浮点型、字符型和布尔型的概念和用法解释不同数据类型的存储方式和大小强调数据类型的选择和使用场景2.2 变量和常量解释变量的概念和作用介绍变量的声明和初始化方法讲解常量的概念和用法2.3 运算符介绍算术运算符、关系运算符和逻辑运算符的概念和用法解释赋值运算符和条件运算符的作用强调不同运算符的优先级和使用规则第三章:控制语句3.1 条件语句介绍if语句的语法和用法讲解switch语句的概念和用法强调条件语句的选择和嵌套使用3.2 循环语句介绍for循环、while循环和do-while循环的概念和用法解释循环控制语句如break和continue的作用强调循环条件的设置和循环次数的控制3.3 跳转语句介绍goto语句的概念和用法讲解label标签的作用和跳转规则强调跳转语句的使用场景和可能导致的问题第四章:函数和指针4.1 函数的基本概念介绍函数的定义和声明讲解函数的参数传递和返回值强调函数的命名规则和命名规范4.2 指针的概念和用法解释指针的概念和作用介绍指针的声明和初始化方法讲解指针的赋值和指针运算4.3 指针和数组介绍数组的概念和用法解释指针和数组的关系强调指针在数组操作中的应用第五章:结构体和文件操作5.1 结构体的概念和用法介绍结构体的定义和声明讲解结构体的成员访问和内存布局强调结构体在数据组织中的应用5.2 文件操作的基本概念解释文件的概念和文件操作的重要性介绍文件打开、读写、关闭等操作的方法强调文件操作中的错误处理和文件指针的管理第六章:动态内存分配6.1 动态内存分配的概念介绍动态内存分配的原因和必要性解释malloc、calloc和realloc函数的作用和用法强调动态内存分配的注意事项和错误处理6.2 链表的概念和用法介绍链表的定义和结构讲解链表的创建、插入、删除和遍历操作强调链表的优势和应用场景6.3 动态内存分配的应用实例通过实例演示动态内存分配在实际编程中的应用讲解内存泄漏和内存溢出的概念强调编写高效和安全的程序的重要性第七章:字符串处理7.1 字符串的基本概念介绍字符串的定义和表示方法解释字符串的长度和字符串的结束标志强调字符串与数组的区别和联系7.2 字符串的常用函数介绍字符串的输入输出函数如printf和scanf 讲解字符串的拷贝、连接、比较等操作函数强调字符串处理函数的使用和注意事项7.3 字符串处理的应用实例通过实例演示字符串处理在实际编程中的应用讲解字符串排序、查找和替换等操作强调字符串处理在文本分析和数据处理中的应用第八章:标准库函数8.1 标准输入输出库函数介绍标准输入输出库stdio.h中的常用函数讲解文件读写、数据转换等函数的用法和功能强调标准库函数的使用场景和注意事项8.2 字符串处理库函数介绍字符串处理库string.h中的常用函数讲解字符串比较、查找和替换等函数的用法和功能强调字符串处理库函数的使用和与其他库函数的配合8.3 数学计算库函数介绍数学计算库math.h中的常用函数讲解数学运算、三角函数和指数函数等函数的用法和功能强调数学计算库函数在数学计算和科学计算中的应用第九章:并发编程和同步机制9.1 并发编程的基本概念介绍并发编程的定义和目的解释进程和线程的概念和关系强调并发编程的优势和挑战9.2 并发编程的同步机制介绍互斥锁、条件变量和信号量等同步机制的原理和用法讲解同步机制在多线程编程中的应用和注意事项强调同步机制在避免竞态条件和数据一致性中的重要性9.3 并发编程的应用实例通过实例演示并发编程在实际应用中的优势和挑战讲解多线程的创建、同步和通信等操作强调并发编程在多任务处理和性能优化中的应用第十章:C语言编程实践10.1 编程实践的重要性强调编程实践在学习和掌握C语言中的重要性解释编程实践对于提高编程能力和解决问题的作用强调编程实践中的代码质量和编程规范10.2 编程实践的项目和案例介绍常见的编程实践项目和案例讲解实际编程中的问题解决方法和技巧强调编程实践中的调试和测试的重要性10.3 编程实践的资源和工具介绍编程实践中的常用工具和环境讲解集成开发环境(IDE)的使用和代码管理强调编程实践中的团队合作和代码分享的重要性重点和难点解析重点环节1:C语言的基本概念和特点需要重点关注C语言的历史和发展,以及其特点和应用范围。
《C语言程序设计》课程教学大纲课程中文名称:C语言程序设计课程英文名称:The C Programming Language课程编号:TS17003课程性质:通识教育课学时:总学时72、理论课学时48、实验课学时24学分:4开课学期:第3学期适用对象:电子科学、应用化学、机械电子、车辆工程、电信工程、地理信息系统等本科专业先修课程:高等数学、大学计算机基础课程简介:《C语言程序设计》是工学、理学类专业的一门重要基础课,通过讲授使学生掌握C语言的基本语法、语句、程序控制结构以及结构化程序设计的基本思想和方法,使学生认识计算机程序设计算法、养成良好的程序设计风格及认识程序设计实践在本课程学习中的重要性,培养学生熟练使用C语言分析和解决实际问题的能力,为学生进一步学习其他专业课程和今后从事软件开发工作打下坚实的基础。
一、教学目标及任务计算机程序设计是当代大学生必备的基本技能,C语言是一种功能完备、使用方便的程序设计语言,学生程序设计能力的培养和提高,也是其计算机应用水平的体现。
《C语言程序设计》是我校理工类非计算机专业学生的通识课,也是全国计算机专业等级考试二级C语言程序设计的重要内容。
本课程的任务是让学生掌握C语言基本知识及程序设计的基本方法,学会运用C语言作为工具,通过程序设计以解决和处理现实世界中尤其是与本专业有关的大量实际问题,着重于学生程序设计能力的培养。
二、学时分配三、教学内容及教学要求第一章 C语言程序设计概述(2学时)教学要求:1.了解C语言发展史、特点、基本词法;2.掌握C语言程序设计的基本结构;3.掌握C程序的上机步骤。
教学重点与难点:重点:C语言程序的基本结构。
难点:计算机程序设计算法。
教学内容:第一节 C语言的历史与特点1.C语言的由来;2.C语言的特点。
第二节 C语言概述1.C语言基本词法;2.计算机常用算法及其表示;3.C语言上机步骤。
本章习题要点:C语言的发展和特点;简单的C程序设计;计算机算法、程序设计语言和程序设计方法。
《C语言程序设计教程》全册教案完整版教学设计第一章:C语言概述1.1 教学目标让学生了解C语言的历史和发展背景让学生掌握C语言的特点和优势让学生了解C语言的应用领域1.2 教学内容C语言的历史和发展背景C语言的特点和优势C语言的应用领域1.3 教学方法讲解法:讲解C语言的历史和发展背景,讲解C语言的特点和优势讨论法:引导学生讨论C语言的应用领域1.4 教学评价课后作业:让学生编写简单的C语言程序,了解C语言的基本语法第二章:C语言基础语法2.1 教学目标让学生掌握C语言的基本语法,包括数据类型、运算符、表达式等让学生了解C语言的控制语句,包括条件语句、循环语句等2.2 教学内容数据类型、变量和常量运算符和表达式控制语句:条件语句、循环语句2.3 教学方法讲解法:讲解数据类型、变量和常量的定义和使用,讲解运算符和表达式的使用,讲解条件语句和循环语句的语法和功能编程实践:让学生编写C语言程序,运用所学的控制语句2.4 教学评价课后作业:让学生编写C语言程序,运用所学的数据类型、运算符和控制语句第三章:函数与编译预处理3.1 教学目标让学生掌握C语言的函数概念和定义方法让学生了解C语言的编译预处理指令3.2 教学内容函数的定义和声明编译预处理指令:include、define、宏定义和宏调用3.3 教学方法讲解法:讲解函数的定义和声明的语法和功能,讲解编译预处理指令的使用方法编程实践:让学生编写C语言程序,运用所学的函数和编译预处理指令3.4 教学评价课后作业:让学生编写C语言程序,运用所学的函数和编译预处理指令第四章:数组和字符串4.1 教学目标让学生掌握C语言的数组和字符串的概念和使用方法4.2 教学内容一维数组的定义和使用字符串的定义和使用4.3 教学方法讲解法:讲解一维数组的定义和使用的语法和功能,讲解字符串的定义和使用的语法和功能编程实践:让学生编写C语言程序,运用所学的数组和字符串4.4 教学评价课后作业:让学生编写C语言程序,运用所学的数组和字符串第五章:指针5.1 教学目标让学生掌握C语言的指针的概念和使用方法5.2 教学内容指针的概念和声明指针的赋值和使用指针与数组指针与函数5.3 教学方法讲解法:讲解指针的概念和声明的语法和功能,讲解指针的赋值和使用的语法和功能,讲解指针与数组和指针与函数的关系编程实践:让学生编写C语言程序,运用所学的指针知识5.4 教学评价课后作业:让学生编写C语言程序,运用所学的指针知识第六章:结构体、联合体和枚举6.1 教学目标让学生掌握C语言中的结构体、联合体和枚举的概念和使用方法。
第九章编译预处理课题:第九章编译预处理教学目的:1、了解预处理的概念及特点2、掌握有参宏与无参宏的定义及使用,领会文件包含的使用及效果教学重点:教学难点:掌握宏的使用,文件包含有参宏与无参宏的使用步骤一复习引导ANSI C标准规定可以在C源程序中加入一些“预处理命令”,以改进程序设计环境,提高编程效率。
这些预处理命令是由ANSI C统一规定的,但它不是C语言本身的组成部分,不能直接对它们进行编译。
必须在对程序进行通常的编译之前,先对程序中这些特殊的命令进行“预处理”,即根据预处理命令对程序作相应的处理。
经过预处理后程序不再包括预处理命令了,最后再由编译程序对预处理后的源程序进行通常的编译处理,得到可供执行的目标代码。
步骤二讲授新课C语言与其他高级语言的一个重要区别是可以使用预处理命令和具有预处理的功能。
C 提供的预处理功能主要有以下三种:宏定义、文件包含、条件编译。
分别用宏定义命令、文件包含命令、条件编译命令来实现。
为了与一般C语句相区别,这些命令以符号“ #” 开头。
§9.1宏定义宏:代表一个字符串的标识符。
宏名:被定义为“宏”的标识符。
宏代换(展开):在编译预处理时,对程序中所有出现的“宏名”,用宏定义中的字符串去代换的过程。
一、不带参数的宏定义一般形式:#define 标识符字符串#define PI 3.1415926main(){ 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:bmain(){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 <file2.h>或#include “file2.h”二者的区别:用尖括号时称为标准方式,系统到存放C库头文件所在的目录中寻找要包含的文件。
用双引号时,系统先在用户当前目录中寻找要包含的文件,若找不到,再按标准方式查找。
#include “c:\tc\include\myfile.h” /*正确*/#include <c:\test\file.c> /*正确*/#include <c:\tc\include\stdio.h> /*错误*/用尖括号:带路径:按指定路径去寻找被包含文件,但此时被包含文件不能以“.h”结尾,否则错误。
不带路径:仅从指定标准目录下找。
用引号:带路径:按指定路径去寻找被包含文件,不再从当前目录和指定目录下找。
不带路径:先在当前目录下找,找不到再在系统指定的标准目录下找。
步骤三课堂小结本课主要讲解了宏定义、“文件包含”处理。
对带参数的宏的使用,及与函数的使用的区别。
搞清经常使用的头文件。
步骤四布置作业上机作业:(第九章课后练习)9.4书面作业:(第九章课后练习)9.7、9.8。