收藏 分享(赏)

程序设计基础复习纲要.doc

上传人:dreamzhangning 文档编号:2242189 上传时间:2018-09-07 格式:DOC 页数:21 大小:120KB
下载 相关 举报
程序设计基础复习纲要.doc_第1页
第1页 / 共21页
程序设计基础复习纲要.doc_第2页
第2页 / 共21页
程序设计基础复习纲要.doc_第3页
第3页 / 共21页
程序设计基础复习纲要.doc_第4页
第4页 / 共21页
程序设计基础复习纲要.doc_第5页
第5页 / 共21页
点击查看更多>>
资源描述

1、Programming : Principles and Practice Using C+第 1 页 共 21 页程序设计基础复习纲要Chapter 12 Hello, World1. 了解 软件开发的 3 个阶段:分析、设计与实现;实现又细分为编码、调试和测试。其中关键概念是反馈。 (1.6 p22)2. 记忆 C+之父是 Bjarne Stroustrup3. 识记 C+注释代码:块注释 /* comments */ 行注释 / comments4. 识记 cin 和 cout 都是标准库中预定义的对象,不是 C+的关键字。5. 理解 C+源代码通常由头文件(*.h)和源文件(*.cpp

2、)构成。#include 指令用于包含头文件,出于简化,作者提供了头文件 std_lib_facilities.h 用于本课程的学习。6. 理解 C+源文件是供程序员阅读的,它不能直接执行。C+编译器负责将C+源文件转换为二进制目标文件,然后连接器再将目标文件与库的目标代码连接生成可执行的二进制文件(p29) 。也即,从 C+源文件到可执行文件须经过两个阶段:编译和连接。于是程序中的错误按发生的阶段可分为编译时错误、连接时错误、运行时错误以及逻辑错误。7. 了解 可移植性 (0.2.3) ,例如:绝大多数 C+源代码是可移植的、目标文件及可执行程序不可移植。本课程强调编写可移植的程序。编程题1

3、. 经典例程 Hello, World(ex2-2)Chapter 3 对象、类型和值1. 理解、重点、难点 基本概念(3.8 p44):类型的概念是 C+和大多数编程语言的核心。在 C+中,几乎一切都有类型(变量、常量、表达式的运算分量,表达式的值,函数的参数,函数的返回值,等等) 。类型定义了一组可能的值和一组操作(作用其对象上) ;对象是一块内存区域,存放指定类型的值;值是一组二进制位,按给定类型来解释其含义;变量是命名了Programming : Principles and Practice Using C+第 2 页 共 21 页的对象;声明 1是命名一个对象的语句;定义 2是为一

4、个对象分配分配内存的声明。变量的声明与定义之间的区别见补充例程declaration_definition.cpp。显然类型、对象和值是相互联系的概念,其关系可用下图示意:3n:int:变量定义语句“int n=3;” 的内存分配映像上图有助于形象地区分左值与右值的概念(4.3) 。通俗地讲,左值指能出现在“=” (赋值或初始化符)左边的表达式;而右值指出现在“=”右边的表达式。例如变量既可以作左值又可以作右值,但两者含义截然不同:左值指上面的“盒子”而右值指“盒子”里的内容。例:赋值语句 n=5;将 5 放入上图的“盒子”中;而 m=n+7;(设变量 m 已用 int m;定义)将变量 n

5、对应“盒子”中的内容 5 取出来去和 7 相加,再把结果 12 放入变量 m 的盒子中。2. 理解、识记 变量的命名规则(3.7):程序中的变量可以取什么名字?几乎所有编程语言对变量的名字都有限制。C+的变量命名规范(其实也是函数名、类型名等用户自定义 标识符 的命名规范)是:C+中的合法的变量名必须是字母或下划线开头的字母、数字或下划线的字符 3序列。建议用户不要使用下划线开头的变量名,因为这是留给编译器或标准库的开发人员用的。例:U.S.A(错) $123(错) tan(对) do(错) _123(对,但不建议) .abc(错) li_ling(对) -abc(错)3. 理解、重点 变量使

6、用的两条基本原则:先声明,后引用;首次引用(作右值使用)前,已被正确地初始化。4. 理解、重点、难点 类型安全的概念?安全的类型转换?不安全的类型转换?例如:charint 和 intdouble 都是安全的类型转换;而 intchar 及1 此处特指狭义的变量声明,即,不是变量定义的声明。2 此处特指变量定义。3 C/C+中的字符是基于 ASCII 字符集,而不是 UNICODE 或 DBCS 字符集,因此变量名不能含中文字符。Programming : Principles and Practice Using C+第 3 页 共 21 页doubleint 都是不安全的类型转换。5. 理

7、解、重点、难点 区分初始化和赋值:例如:int n=3;为初始化;而 int n; n = 3;则为赋值。编程题1. ex3-22. ex3-43. ex3-84. ex3-10Chapter 4 计算1. 理解、重点、难点 计算的基本概念:Wirth 公式 :算法+数据结构= 程序输入2. 理解、重点、难点 程序员的目标: 将计算表达出来,并且追求正确性、简单性和高效性这三条基本原则。3. 理解、重点、难点 抽象和分治:系统(软件或硬件、甚至建筑、机械等其他行业)设计与实现中的最主要敌人是复杂性。目前,对付复杂性的主要手段是:将大的、复杂的计算任务分解为一系列小的、较易处理的小任务(“大事化

8、小,小事化了” ) 。这一技术主要有两类方法:抽象(abstraction )和分治(divide and conquer it) 。代码数据输出计算Programming : Principles and Practice Using C+第 4 页 共 21 页4. 理解、重点、难点 表达式程序的最基本单元(4.3):1) 区分左值和右值:当一变量作左值时指这个对象本身;而当它作右值时,表示这个对象的值。2) 常量表达式(例:const double pi=3.14159;) 。好的编程风格:避免直接使用魔数(magic constant)而代之以符号常量。这也是 C+引入 const 关

9、键字的原因。3) 运算符:区分=及= 不等式 a v(6);则访问向量v 的有效下标是 v0v5;又如 vector names(4);则有效的向量元素是 names0names3。向量的一些基本操作:v.size();求向量 v的元素个数;v.push_back(x) 在向量 v 尾部添加新的元素x;sort(v.begin(),v.end) 对向量元素进行排序(小大) 。编程题1. 补充例程:百分制五分制转换(用 if 实现或 switch 实现)2. 试一试(p63,p64,p66)3. ex4-24. ex4-35. ex4-44 正交性设计不仅对于软件设计很重要,对于硬件设计也很重要

10、,事实上,系统设计师在设计处理器的指令系统时,也遵循正交性原则,这已经是处理器设计的一条普遍原则。5 包括函数的引用性声明或函数的定义Programming : Principles and Practice Using C+第 6 页 共 21 页6. ex4-11Chapter 5 错误1. 理解、重点、难点 错误的分类(5.1):按错误出现的时期,可分为编译时错误、连接时错误、运行时错误以及逻辑错误。一般地,越后面发现的错误越难以处理。记住,错误是越早发现越好。2. 了解 本课程的错误处理要求 :1) 对于所有合法输入应输出正确结果。2) 对于所有非法输入应输出错误信息。3) 无须操心硬

11、件故障。4) 无须操心系统软件故障。5) 发现一个错误后,允许程序终止。3. 理解 编写高质量软件的途径 :1) 精心组织软件以使错误最小化;2) 通过调试和测试,消除大部分程序错误;3) 确定余下的错误不重要。4. 了解 错误的来源 :1) 缺少规划2) 不完备的程序3) 意外的参数4) 意外的输入5) 意外的状态6) 逻辑错误5. 了解 编译时错误 :语法错误;类型错误;警告6. 了解 连接时错误 :下列情形将产生连接时错误:当某个调用的函数仅有声明,没有定义时;或定义函数时,参数的个数或类型与声明函数时不一致。7. 考点、重点、难点 运行时错误:经常发生在函数调用上。Programmin

12、g : Principles and Practice Using C+第 7 页 共 21 页1) 主2) 错误处理的两个基本方面 : )(主3) 错误处理的几种方案:I. 主调方和被调方均不检测,也不处理错误。II. 主调方检测并处理错误。III. 被调方检测并处理错误。IV. 被调方检测错误,而主调方处理错误。这就引来新的问题:低层的被调方如何向高层的调用方报告错误?目前主要有三种报告方式 6: 主4) 异常的基本思想及其优点(5.6) 。异常的基本思想是:如果被调函数发现一个自己不能处理的错误,它不是正常返回,而是通过抛出异常来表示检测到错误的发生(同时终止自己的执行 7) 。任何一个

13、其直接或间接的主调函数都可以捕捉到这一异常,并确定应该如何处理这个错误。这体现了机制与策略的分离:底层被调函数具有检测错误的机制,高层主调函数则有决定错误处理策略的权利。异常方式的优点:异常不可忽略。即,一旦低层被调函数(比如库函数)检测到错误导致抛出异常,高层的主调方(直接或间接主调函数)一定要处理,如果直到 main()也不处理该异常,则程序将终止运行。这种做法有效地防止错误无意中继续转播。它允许主调方将处理正常逻辑的代码与处理异常逻辑的代码适当分离,代码更简洁、更清晰,当然可读性也更好。最后,顺便提一句,错误处理(尤其是如何让系统从错误中恢复过来)本质上就是很困难的问题,异常方式也不可能

14、让它变得很容易,异常只是让错误处理更容易一些(相比于其他方式) 。6 其实还有一种以函数变参转回错误标志的方式。例如:将 sqrt()设计为 void sqrt(double x, int7 C+异常处理采用终止语义。至于为什么不采用 唤醒语义?详见 Bjarne 的另一著作C+的设计与演化Programming : Principles and Practice Using C+第 8 页 共 21 页5) 了解常见的几种运行时错误:错误参数;范围错误;输入错误;截断错误。当然还有其它一些错误,比如标准库中提供的域错误、上溢、下溢等。8. 理解逻辑错误:在一些输入下程序的输出结果不正确。逻辑

15、错误通常是算法有问题引起的,此类错误是最难被发现和排除的,因为有些情况下,程序对大多数输入都能输出正确结果。教材5.7 的例子就是个典型的例子。9. 理解调试、前置条件、后置条件、测试。前置条件(简称“前件” )及后置条件(简称“后件” )是一种所谓断言的技术:前置条件是函数的入口处参数必须满足的关系式,后置条件是函数出口处(返回时)必须满足的关系式。给函数增加前件和后件有助于我们避免设计错误和及早发现错误,能有效降低调试和测试的难度 8。10. 理解为了达到本课程的错误处理要求,今后我们错误处理的代码框架类似于 p96 的结构:int main()try /* your code */kee

16、p_window_open();return 0;catch (exception”表明函数 print_men()不带函数参数也没有返回值。参数传递(实参 形参)的三种方式: 值参、常引用参数、引用参数。理解如何选择恰当的参数传递方式?经验准则:小对象传值;常引用参数传只读的大对象;尽量让函数返回一个值,而不是修改通过引用参数传递进来的对象;迫不得已时使用传引用方式,比如,既要读也要写大对象。当然实际的设计可能更难,有时需要在这些指导原则之间折中,例如:按照原则:ch = cin.get()应该比 cin.get(ch)要更好一些,而事实上后者更通用!难点函数调用的实现机制(8.5.8):函

17、数活动记录栈(stack of activation record) ,简称调用栈(call stack),栈是一种后进先出(LIFO,Last In First Out)的数据结构。基于调用栈的函数实现机制给递归程序的设计带来了极大的便利。参考例程:教材的举例及补充例子 collatz.cpp5理解 求值顺序 (8.6):忠告:不要编写结果依赖于求值顺序的代码,因为那样的代码不具可移植性。例如:vi = +i; v+i = i;6理解、重点、难点 名字空间(8.7):作用是将实体的命名进行逻辑分组,以避免或减少命名冲突的可能性;using 声明及 using 指令:using std:str

18、ing;及 using std:cout;均为典型的 using 声明用法,而 using namespace std;则是典型的 using 指令用法。忠告:慎用 using 指令,尤其是在大型程序中。7理解、难点 其余知识点:(1)算术 if 表达式(也叫 条件表达式) (P161 L1-9):e1?e2:e3 当子表达式 e1 值非零时取子式 e2 的值作为整个表达式的值,否则取子式 e3 的值作为结果。它是 C/C+中唯一的三元运算符,且不可进行运算符重载。 (2)临时对象(temporary object ) (P170 中间):有时,编译器会在可执行代码中偷偷安插一些源代码中并没有

19、的对象,这种对象被Programming : Principles and Practice Using C+第 15 页 共 21 页称作临时对象。之所以这样称呼是因为临时对象的生成是实现相关的东西,即,有没有安插?安插几个?临时对象的实体如何命名?这些问题的答案在很大程序上取决于编译器的实现。第三章里引入变量的概念时,我们强调变量是命名了的对象,其原因就是由于临时对象的存在。 (3)静态局部变量(P177L-9):只在函数首次调用时才初始化,直到程序退出时,它一直存在。因此可以断定它不在调用栈上分配与释放,事实上它位于程序的静态数据区(详见17.4 P348 图示) 。忠告:慎用静态局部变

20、量。合理使用它可以提高程序性能,但应避免滥用,因为含有静态局部变量的函数不具可重入性,即,函数的各次调用之间可能会相互影响,这给程序的调试带来了很大的困难,尤其是当进行多线程程序设计时。编程题1D8-32Ex8-23Ex8-5Chapter 9 类相关的技术细节1理解、重点、难点 用户自定义类型(UDT,user-defined type):与内置类型(built-in type)相对的概念。为何要定义 UDT?本书反复强调的编程的基本理念是代码直接反映思想。可是现实中有用的概念实在太多了(比如:电视、收音机,等等) ,任何语言设计师或编译器开发者都无法预料到程序可能需要的所有类型!现代编程语

21、言通过“机制与策略的分离”来解决此难题。语言只提供少数几种基本类型,并提供组合这些基本类型的机制(这正是 class、struct 等关键字的作用) ,而完全由程序员来决定如何组合的策略。因此高级语言比低级语言更容易使用,因为用低级语言(汇编语言或机器语言)编程时,程序员必须自己去抽象如何把现实中的概念表示为字或字节?看待 UDT 的两种视角: (9.1) ,于是类的成员主主主要由数据成员和成员函数两部分构成。顺便提一下,数据和操作是计算机科学两个最基本的研究对象。比如说:在 CPU 的指令系统中,每条指令都由操Programming : Principles and Practice Usi

22、ng C+第 16 页 共 21 页作码和操作数两部分组成;数据结构研究如何表示数据以使操作的实现更高效;算法研究如何设计并实现高效的操作(算法设计 11)?也研究操作的复杂度甚至某些问题是否存在恰当复杂度的算法(算法分析)?数据库研究在多用户、并发访问情形下,如何保证数据的一致性?等等。(9.3) ,这体现了接口与实现的分离。于是,C+提供主了两种基本的访问控制:public 及 private。此即 OOP 中的封装性。顺便提一下:OOP 三大特征:封装性、继承性、多态性。2理解、重点、难点 不变式 12(invariant) 判断类型的值是否有效的规则(9.4.3) 。当某个类型存在不变

23、式时(比如日期类) ,我们就设法保证此类型的对象实例时刻维护着不变式。这意味着,我们应该:隐藏 UDT 的数据表示(即,将数据表示放入类的私有区) ;提供一个创建有效对象的构造函数,用以保证新生对象被正确地初始化;其他成员函数的设计遵循接受有效值、生成有效值的原则,即:UDT 所有操作的前置条件和后置条件均是:类的内部状态是有效的满足不变式。如果遵循上述 UDT 的设计原则,我们就能保证 UDT 的对象实例时刻维护着不变式。3重点、难点 成员函数的定义可在类的定义中,也可以在类外定义,此时须加类型限定符:。当在类中定义成员函数时,它通常会被处理为 inline 函数。inline 函数的基本思

24、路是:用空间换时间inline 函数的指令序列会在每个调用处被展开,因此它没有普通函数调用时的栈开销(8.5.8) ,缺点是:一旦 inine 函数作了改动,所有的客户端代码也必须重新编译这违背了接口与实现分离的原则。构造函数是特殊的成员函数,负责新生对象的初始化工作。基本特点:同类名、无返回(甚至不能定义为 void 返回类型) 、可重载、自动调用。4理解、重点 枚举类型及枚举常量。最重要的两点是:枚举常量的作用域11 如你所见,算法设计与数据结构的设计之间决不是相互独立的,而是相互联系、相互制约的。12 这里所指的实际上是一种数据不变式。其实,算法也有不变式的概念。详见 Dijkstra,

25、 Hoare, Dahl 合著的结构程序设计 (陈火旺 译) 。其实,第 5 章介绍的断言技术(前置条件及后置条件)就是检验不变式。Programming : Principles and Practice Using C+第 17 页 共 21 页与定义它的枚举类型的作用域相同;枚举类型向 int 类型的隐式类型转换是单向的。5理解、重点、难点 运算符重载。两类基本方法:类成员函数运算符重载以及全局函数运算符重载,后者又可细分为普通函数重载和友元函数重载两种。以复数 Complex 为例: ; ; ),(.baopertba )(.aoperta ; 。)(.aoperta int),(.a

26、operta其他细节:C+只能重载现有的运算符、不能改变运算分量的数目、也不能改变运算符的结合性。注:唯一的三目运算符?:不可重载。因此 C+中运算符重载分为一元运算符和二元运算符两种。6理解、重点、难点 类接口(界面)的设计:一般地,应遵循如下基本原则: 紧凑性(最小化) ; 即类的接口应尽可能地小。因为小的接口易于理解和维护。 完备性:对 UDT 逻辑上合理的操作都可以由这些操作接口的某种组合来完成); 正交性:各操作接口在功能没有重叠,因此不用担心接口之间的干涉效应; 易用性:设计者应站在用户的角度“由外而内“地设计接口, 理由很简单: 接口是 UDT 提供给外界用户使用的,当然要尽可能

27、符合它们的需求!; 类型安全:这样编译器就能在编译阶段捕获大多数参数误用的错误。 const correct:明确各操作接口是否会改变对象的内部状态。其中前两个设计原则可归纳为“Keep interfaces as small as possible, but no smaller”。这与 Albert Einstein 的名言“Keep it as simple as possible, but no simpler”中的哲学精神是相通的。特别需要指出的是, 有时这些原则也会相互冲突,现实设计中往往取一个恰当的平衡点。比如,本章中的 Date 类,Programming : Principl

28、es and Practice Using C+第 18 页 共 21 页从操作接口“最小化“ 的角度看, add_year()和 add_month()是多余的,因为它们都能化归化为 add_day(n), 但从“易用性“的角度看 ,提供它们是很自然的。并且,提供的操作接口是 add_day(),而不是 set_day(), 这也是遵循“ 易用性“ 的设计结果。 另外顺便提一下,Date 类的操作接口 day()、month() 和year()之间完全符合正交性,而 add_year()、add_month()和 add_day()之间则是大致符合正交性,因为 add_year(),add_

29、month()可能会改变“日子“ ,例如:设当前日期 d 为 2012.3.31,则 d.add_month(1)可能将变为 2012.4.30,而d.add_month(-1)将可能改变为 2012.2.29; 设当前日期 d 为 2008.2.29,则d.add_year(1)将变为 2009.3.17理解、重点、难点 C+类的三大组件:,而 ctor 又可细分为)(asignmetdtor c对 已 存 在 的 旧 对 象 赋 值化 工 作负 责 对 象 消 亡 前 的 清 理 工 作负 责 新 生 对 象 的 初 始 化。三大组件与一般的成员函数相比较,在许多方 ctorpy ctor

30、tdfaul 其 它类 型 转 换普 通面都表现出特殊性。以 ctor 为例,它具有下列特点:无返回值;可重载;ctor 在定义对象时由系统自动调用,用户不能显式调用它,等等。三大组件中,copy ctor 与 assignment 最容易混淆,它们之间最本质的差别是:前者是以另一个对象为样板来生成一个新对象;后者则是用另一个对象对已经存在的旧对象进行赋值。可以认为两者的差异就在于对象的新或旧上。例如:Date d1(1900,1,1), d2;Date dd = d1; / copy ctordd = d2; / assignment8理解、重点、难点 helper function(9.7

31、.5):是一种设计思想,而非编程概念。引入它们是为了保持 UDT 接口的最小化我们可以将 UDT 的一些有用的、但并非基本操作的操作设计为 helper function。这大概也是纯OOP 语言(譬如,Java、C#等编程语言)未必就理想的一个有力佐证!否则类的接口将很容易变得庞大和臃肿。Programming : Principles and Practice Using C+第 19 页 共 21 页9理解、难点 其他:(1)类的静态数据成员(static data member) (见9.7.1):用以描述类的所有对象实例所共享的属性。 (2)闰年的判断(ex9-10) ;(3)常对象

32、(const object):描述只读的对象;(4)对象的常操作(const member function):描述对象的只读操作,即,不会改变对象内部状态的操作。编程题1Ex9-82补充例程:3实现二:补充例程的功能扩展Chapter 10 输入/输出流1理解、重点、难点 输入/输出的基本原理(10.1,尤其是 P207 的图) 。软件分层是对付复杂性的一种有效手段。分层化 13的本质思想是抽象。2理解、重点、难点 C+标准 I/O 流模型:P208 和 P209 的两幅图。引入缓冲主要是为了提高 I/O 的性能。3理解、重点、难点 文件。从 C+程序的角度看,文件是操作系统(operati

33、ng system,简称 OS)提供的一种抽象,它可视为一个从 0 开始编号的字节(见 P209 图 2) 。文件有格式确定其中字节含义的规则。文件格式之于文件的作用犹如类型于对象。C+文件 I/O 的基本模型见 P209 图3。文件访问的基本范式:打开/读/写/关闭。4理解、重点、难点 I/O 流的错误处理(10.6):将各种外因(近乎无限)归结为四种内因流的 4 种状态(P213 表格): good():操作成功 eof():遇到 eof(end of file,文件尾) fail():发生某些意外(也许可以恢复) bad():发生严重的意外(通常不可恢复)这是一种重要的抽象对付复杂性的有

34、效方法。13 在 David Money Harris 和 Sarah L.Harris 所著的数字设计和计算机体系结构一书中,开篇就强调了分层化、模块化、规整化是工程领域(当然包括计算机软、硬件系统)对付复杂性的有效方法论。Programming : Principles and Practice Using C+第 20 页 共 21 页5理解、重点、难点 I/O 错误恢复的基本原理( 10.6) 。10.6 P213 的代码段以 cin 为例展示了错误恢复的大致框架,而 P214 的函数 fill_vector()则展示了一个具体的实现。试自行画出流的状态转换图来理解其技术原理。6实用编程技术 :如何读取一个指定范围内的值?(10.7)7理解、重点、难点 如何为 UDT 定义流的输入/ 输出操作?(10.8 和10.9):理解 operator()的参数及返回值。这是非常精妙的细节,本质上,它们这样处理是为了提取符和插入符ch 与 cin.get(ch)的区别;isspace(c),isalpha(c),isdigit(c) ,isalnum(c),isupper(c) ,islower(c) 为常用的字符分类函数;大小写转换:toupper(c)和 tolower(c)6实用编程技术:自定义非标准分隔符的输入流编程题1Ex11-12Ex11-2

展开阅读全文
相关资源
猜你喜欢
相关搜索

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

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报