第18讲 从C到C++ 计算机与通信工程学院.

Slides:



Advertisements
Similar presentations
C++语言程序设计教程 第5章 构造数据类型 第6章 C++程序的结构.
Advertisements

电子成绩单项目实现.
第10章 结构体与链表 本章要点: 结构体类型与结构体变量的定义 结构体变量的引用与初始化 结构体数组 链表处理 共用体类型和枚举类型
第九章 系 统 安 全 性 9.1 结构体 9.2 结构体型数组  9.3 结构体型指针 9.4 内存的动态分配 9.5 共用体
第7章 结构体、联合体和枚举类型 本章导读 本章主要知识点 《 C语言程序设计》 (Visual C++ 6.0环境)
C语言程序设计 第十二章 位运算.
第一章 程序设计入门.
Introduction to the C Programming Language
C语言程序设计 第五章 选择结构程序设计.
高级语言程序设计 主讲人:陈玉华.
第5章 函数与预处理 《 C语言程序设计》 (Visual C++ 6.0环境) 本章导读
C 程序设计实例 1. 问题描述 2. 数据结构 3. 算法分析 4. 参考程序 5. 改进说明.
计算概论 第二十一讲 文件操作 北京大学信息学院.
补充内容 结构体 概述 定义结构体类型和定义结构体变量 结构体变量的引用 结构体变量的初始化 指针与结构体 用typedef定义类型的别名.
If … else 選擇結構 P27.
C 程式設計— 語言簡介 台大資訊工程學系 資訊系統訓練班.
结构体和共用体 2 梁春燕 华电信息管理教研室.
C++语言程序设计 C++语言程序设计 第六章 指针和引用 第十一组 C++语言程序设计.
C++ 程式設計— 語言簡介 台大資訊工程學系 資訊系統訓練班.
STRUCTURE 授課:ANT 日期:2010/5/12.
第七章 函数 目录 有参的加法函数的开发 函数定义的一般形式 函数参数和函数的值 函数的调用
C++语言程序设计 C++语言程序设计 第四章 数组及自定义数据类型 C++语言程序设计.
第九章 结构体和共用体 结构体的定义 结构体的使用 共用体的定义 共用体的使用 主讲:李祥 时间:2015年10月.
计算概论 第十八讲 C语言高级编程 结构与习题课 北京大学信息学院.
C语言程序设计 李祥.
程序设计专题一 结构化程序设计与递归函数 主讲教师: 刘新国.
第5章 堆疊(Stacks) 5-1 堆疊的基礎 5-2 堆疊的表示法 5-3 堆疊的應用 - 運算式的計算與轉換
QQ: 李祥 QQ: 欢迎多种方式的学习交流,祝大家学有所成.
第7章 编译预处理 本章要求: 本章重点: 本章难点: 掌握用#define定义无参数宏和带有参数宏定义和调用方法;
第五章 指针 5.1 指针的概念和定义 5.2 指针运算 5.3 指针和数组 5.4 字符串指针 5.5 指针数组 5.6 指向指针的指针
第四章 C 语言中的输入和输出.
期中考试成绩分布 《程序设计》-2017年秋.
THE C PROGRAMMING LANGUAGE
第13章 结构体的应用 13.1 了解由用户构造的数据类型 13.2 结构体类型说明及结构体变量 13.3 结构体数组
第十章 指针.
第3章 顺序结构程序设计 为了让计算机处理各种数据,首先就应该把源数据输入到计算机中;计算机处理结束后,再将目标数据信息以人能够识别的方式输出。C语言中的输入输出操作,是由C语言编译系统提供的库函数来实现。 3.1 格式化输出——printf()函数 3.2 格式化输入——scanf()函数.
2.1 C语言的数据类型 2.2 常量与变量 2.3 变量赋初值 2.4 各类数值型数据间的混合运算 2.5 C语言的运算符和表达式
第七章 函数及变量存贮类型 7.1 函数基础与C程序结构 7.2 函数的定义和声明 7.3 函数的调用 7.4 函数的嵌套与递归
第4章 顺序程序设计.
授课老师:龚涛 信息科学与技术学院 2016年3月 教材:《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
第6章 预 处 理.
第九章 预处理命令.
C语言程序设计.
第十章 用户自定义数据类型 目录 学生信息管理系统的开发 结构体数据类型的概述 结构体变量的使用 结构体数组
目录 9.1 结构体类型 9.2 共用体类型 9.3 枚举类型 9.4 类型声明符typedef 1.
第十章 结构体与链表 西安工程大学.
C语言概述 第一章.
C程序设计.
Introduction to the C Programming Language
第11章 位运算 为了节省内存空间,在系统软件中常将多个标志状态简单地组合在一起,存储到一个字节(或字)中。C语言是为研制系统软件而设计的,所以她提供了实现将标志状态从标志字节中分离出来的位运算功能。 所谓位运算是指,按二进制位进行的运算。 11.1 数值在计算机中的表示 11.2.
C语言程序设计 教案 崔武子制作
Chap 5 函数 5.1 计算圆柱体积 5.2 使用函数编写程序 5.3 变量与函数.
輸出與輸入(I/O).
第十四章 若干深入问题和C独有的特性 作业: 函数指针 函数作参数 函数副作用 运算 语句 位段 存储类别 编译预处理
本节内容 字符与字符串 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
第6章 预 处 理.
Introduction to the C Programming Language
第三章 基本的輸出與輸入函數 (Basic Output & Input Function)
第四章 C 语言中的输入和输出.
第4章 顺序结构程序设计 为了让计算机处理各种数据,首先就应该把源数据输入到计算机中;计算机处理结束后,再将目标数据信息以人能够识别的方式输出。C语言中的输入输出操作,是由C语言编译系统提供的库函数来实现。 4.1 格式化输出——printf()函数 4.2 格式化输入——scanf()函数.
第3章 最简单的C程序设计 3.1 顺序程序设计举例 3.2 数据的表现形式及其运算 3.3 C语句 3.4 数据的输入输出.
Introduction to the C Programming Language
第二章 数据类型、运算符和表达式 §2.1 数据与数据类型 §2.2 常量、变量和标准函数 §2.3 基本运算符及其表达式 目 录 上一章
C/C++基礎程式設計班 C語言入門、變數、基本處理與輸入輸出 講師:林業峻 CSIE, NTU 3/7, 2015.
Chap 10 函数与程序结构 10.1 圆形体积计算器 10.2 汉诺塔问题 10.3 长度单位转换 10.4 大程序构成.
Introduction to the C Programming Language
安排座位.
C++语言程序设计 C++语言程序设计 第二章 基本数据类型与表达式 第十一组 C++语言程序设计.
Presentation transcript:

第18讲 从C到C++ 计算机与通信工程学院

第18讲 编译预处理和数据类型再命名 本讲主要内容 宏定义 文件包含 条件编译 数据类型再命名 不带参数的宏 带参数的宏 一般形式 文件包含的有关说明 条件编译 ifdef-else-endif形式 ifndef-else-endif形式 if-else-endif形式 数据类型再命名 typedef的一般形式 typedef应用举例

第18讲 编译预处理和数据类型再命名 教学目标 了解编译预处理的概念,了解宏的概念。 了解文件包含的概念,熟练掌握文件包含命令include的用法。 了解条件编译的概念,熟悉常用的条件编译命令及其用法。 了解文件重名的意义,掌握typedef命令的使用方法。

一、宏定义 不带参数的宏 不带参数的宏是用一个标识符代替一个字符串,其一般形式如下: #define 宏名 宏体 其中的“#”表示这是一条预处理命令。 凡是以“#”开头的均为预处理命令。 “define”为宏定义命令。 宏名是一个标识符,宏体可以是一个字符串,也可以是一个数值,也可以是一个表达式等。 例如:#define PI 3.1415926

一、宏定义 #define TWO 2 #define MSG "I love c language." 例17-1 宏定义应用举例。 #define TWO 2 #define MSG "I love c language." #define FMT " number is %d\n" main() {     int number=TWO;     printf(FMT, number);     printf("%s\n",MSG); }

一、宏定义 例17-2 计算圆面积。 #define PI 3.14 main() { float R=16.99; printf("S=PI*R*R=%f\n",PI*R*R); }

一、宏定义 例17-3 计算圆的周长和面积 。 #define R 3.0 #define PI 3.1415926 #deinfe L 2*PI*R /* 使用宏R和PI定义宏L */ #define S PI*R*R /* 使用宏R和PI定义宏S */ main() { printf("L=%f\nS=%f\n",L,S); }

一、宏定义 例17-4输出格式定义为宏。 #define PR printf main() #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[]="This is a string."; 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); }

一、宏定义 关于宏定义的说明: ⑴ 宏名一般使用大写形式。 ⑵ 使用宏可以提高程序的可读性和可移植性。 ⑶ 宏定义是用宏名来表示一个字符串,在宏替换时又以该字符串取代宏名,这只是一种简单的代换。 ⑷ 宏定义不是C语句,后面不能有分号。如果加入分号,则加入的分号将作为宏体的一部分。 ⑸ 通常把#define命令放在一个文件的开头,使其在本文件全部有效。 ⑹ 宏定义终止命令 #undef结束先前定义的宏名。 ⑺ 程序中用双引号括起来的字符串,即使与宏名相同,也不替换。 ⑻ 宏定义允许嵌套,在宏定义的字符串中可以使用已经定义的宏名。在宏展开时由预处理程序层层替换。 ⑼ 宏定义名仅用于编译预处理,不是程序变量,因此系统不会为它分配内存空间。

一、宏定义 带参数的宏 带参数宏定义的一般形式如下: #define 宏名(参数表) 字符串 其中:⑴ 宏名后的参数表可以是一个参数,也可以是多个参数,当有多个参数时,各参数之间用“,”分割。 ⑵ 用于宏体的字符串部分要包括参数表中的参数。 例如:#define max(x,y) x>y?x:y 宏替换按如下过程进行:对于程序中带实参的宏,按照宏定义中的字符串从左到右进行替换,当遇到宏中的形参时,就用程序语句中的宏实参取代它,对于宏定义字符串(宏体)中的非参数字符,则予以保留。

一、宏定义 例17-5 利用宏定义求三个数的最大数。 #include "stdio.h" #define max(x,y) x>y?x:y main() { int a,b,c,m; scanf("%d%d%d",&a,&b,&c); m=max(a,b); /* 使用宏max,a、b为宏实参 */ printf("max=%d\n",max(m,c));/* m、c为宏实参 */ }

一、宏定义 使用带参数的宏时应注意如下问题: ⑴ 在带参宏定义中,形式参数不分配内存单元,也不存在类型定义问题。而宏调用中的实参有具体的值,要用它们去替换形参,因此必须首先进行类型说明。 ⑵ 如果程序中有使用表达式作为宏实参的情况,那么在进行宏定义时,出现在宏替换字符串中的宏参数应使用括号()进行限定,否则宏替换后有可能产生错误的结果。 ⑶ 带参宏定义中,宏名和形参表之间不能有空格出现,一旦出现了空格,就变成了不带参数的宏定义。

一、宏定义 带参数的宏与函数调用的区别: ⑴ 函数调用时要先计算实参表达式的值,然后传给形参。而带参的宏只是进行简单的符号替换,不存在计算表达式的值的问题。 ⑵ 函数调用在程序运行过程中发生作用,而宏在程序的编译预处理阶段发生作用。 ⑶ 函数调用只能得到一个返回值,使用宏能够得到多个结果。 ⑷ 宏替换不占运行时间,只占编译时间,而函数调用则占用运行时间。 ⑸ 在函数中,形参和实参是两个不同的量,各有自己的作用域,调用时要把实参值赋予形参,进行“值传递”。而在带参宏中,只是符号替换,不存在值传递的问题。

一、宏定义 例17-6 计算圆的周长和面积。 #define PI 3.1415926 #define CIRCLE(R,L,S) L=2*PI*R;S=PI*R*R; main() { float r,l,s; printf("Input r:"); scanf("%f",&r); CIRCLE(r,l,s); /* 源程序中使用带参数的宏 */ printf("L=%f,S=%f\n",l,s); }

二、文件包含 为了在一个源程序中使用另一个源程序的代码,C语言提供了文件包含命令include, 它的一般使用形式如下: 文件包含命令的功能是把指定的文件插入该命令行位置取代该命令行, 从而把指定的文件和当前的源程序文件连成一个源文件。

二、文件包含 例17-7 创建源文件userdef.h并在程序e1707.c中使用它。 如下是userdef.h文件的内容: #define PRINT printf /* 定义符号常量PRINT */ #define INPUT scanf /* 定义符号常量INPUT */ #define PI 3.1415926 /* 定义符号常量PI */ 如下是e1707.c文件的内容: #include "userdef.h" main() {float s,r; PRINT("r="); INPUT("%f",&r); s=PI*r*r; PRINT("AREA=%f\n",s); }

二、文件包含 对文件包含命令还要说明以下几点: ⑴ 包含命令中的文件名可以用双引号括起来,也可以用尖括号括起来,以下写法都是允许的: #include "stdio.h"  #include <math.h>  但是这两种形式是有区别的: 使用双引号则表示首先在当前的源文件目录中查找,若未找到才到包含目录中去查找;使用尖括号表示在包含文件目录中去查找, 而不在源文件目录去查找。 ⑵  一个include命令只能指定一个被包含文件, 若有多个文件要包含,则需用多个include命令。 ⑶ 文件包含允许嵌套,即在一个被包含的文件中又可以包含另一个文件。

三、条件编译 ifdef-else-endif形式 一般形式如下: #ifdef 标识符 程序段1 #else 程序段2 #endif 程序段1  #else  程序段2  #endif  该形式的条件编译的过程:如果“标识符”已被“ #define”命令定义过,则对“程序段1”进行编译;否则对“程序段2”进行编译。如果没有“程序段2”,上述格式中的“#else”即不再使用,条件编译成为如下形式:  程序段 

三、条件编译 例17-8 条件编译举例1。 #define NUM ok struct stu { int num; char *name; 例17-8 条件编译举例1。 #define NUM ok struct stu { int num; char *name; char sex; float score; }*ps; main() {ps=(struct stu*)malloc(sizeof(struct stu)); ps->num=102; ps->name="Zhang ping"; ps->sex='M'; ps->score=62.5; #ifdef NUM printf("Number=%d\nScore=%f\n",ps->num,ps->score); #else printf("Name=%s\nSex=%c\n",ps->name,ps->sex); #endif free(ps); }

三、条件编译 ifndef-else-endif形式 一般形式如下: #ifndef 标识符 程序段1 #else 程序段2 #endif 程序段1  #else  程序段2  #endif  它与第一种形式的区别是将“ifdef”改为了“ifndef”。它的功能是,如果标识符未被#define命令定义过则对程序段1进行编译, 否则对程序段2进行编译。这与第一种形式的功能正相反。 

三、条件编译 if-else-endif形式 一般形式如下: #if 常量表达式 程序段1 #else 程序段2 #endif 程序段1  #else  程序段2  #endif  它的功能是,如常量表达式的值为真(非0),则对程序段1 进行编译,否则对程序段2进行编译。因此可以使程序在不同条件下,完成不同的功能。  

三、条件编译 例17-9 条件编译举例2。 #define R 1 main() {float x,s; 例17-9 条件编译举例2。 #define R 1 main() {float x,s; printf ("input a number: "); scanf("%f",&x); #if R s=3.14159*x*x; printf("Area of round is: %f\n",s); #else s=x*x; printf("Area of square is: %f\n",s); #endif }

四、数据类型再命名 所谓数据类型再命名就是为已经存在的数据类型再定义一个另外的名字,目的是为了增强程序的可读性,使用的命令是typedef,它以C语句的形式出现在程序中。 typedef 的一般形式如下: typedef 已定义的类型名 新类型名; 例如: typedef int INTEGER; typedef float REAL;

四、数据类型再命名 例17-10 用typedef命令改写例13-3简单的密码加密程序。 #include "stdio.h" struct table {char input; char output; }; typedef struct table TABLE; main( ) {char ch; int length, i; TABLE translate[]={'a','f','b','g','w','d','f', '9','y','*','x','s','m','3','h','k','p','f','u','?' }; length=sizeof(translate)/sizeof(struct table); while((ch=getchar())!= '\n') { for(i=0;translate[i].input!=ch&&i<length;i++) ; if (i<length) putchar(translate[i].output); else putchar (ch); }

编译预处理和数据类型再命名-小结 1. 使用预处理功能便于程序的修改、阅读、移植和调试,也便于实现模块化程序设计。 1. 使用预处理功能便于程序的修改、阅读、移植和调试,也便于实现模块化程序设计。 2. 宏定义是用一个标识符来表示一个字符串,这个字符串可以是常量、变量或表达式。在宏调用中将用该字符串代换宏名。 3. 宏定义可以带有参数,宏调用时是以实参代换形参,而不是“值传送”。 4. 为了避免宏替换时发生错误,宏定义中的字符串应加括号,字符串中出现的形式参数两边也应加括号。 5. 文件包含是预处理的一个重要功能,它可用来把多个源文件连接成一个源文件进行编译,结果将生成一个目标文件。 6. 条件编译允许只编译源程序中满足条件的程序段,使生成的目标程序较短,从而减少了内存的开销并提高了程序的效率。 7. 数据类型再命名是为已经存在的数据类型再定义一个另外的名字,目的是为了增强程序的可读性,使用的命令是typedef。