admin 管理员组文章数量: 1086019
2024年12月31日发(作者:jsp留言板功能实现)
第一章
1.1.1
程序设计基本特点
1.1 软件的发展
从程序设计到软件工程
计算机(computer)是能以相对于人而言几百万甚至几十亿倍速度进行运
算并作出逻辑判断的设备。
计算机按照一组指令控制下的运行过程(由“算法”规定)来处理数据
(data),这组指令称为计算机程序(computer program)。
编写这组指令的工作称为程序设计(programming)。
大约在二十世纪七十年代,程序设计发展为软件工程。
软件可定义为包括计算机程序、方法、规则、相关的文档资料以及计算机
运行所需数据。
软件工程曾由Boehm下定义为:“运用现代科学技术知识设计并构造计算
机程序和为开发、运行和维护这些程序所必需的相关文件资料”。程序设计和
软件工程两者区别如下:
主要特点 程序设计 软件工程
内容 指令和数据 指令、数据和全套文档
汇编语言和 需求定义、软件功能、文档设计
主要语言
高级语言 和程序设计等语言
软件生命周期各阶段
工作范围 编写程序
(以下将介绍)
需求者 个别用户 市场用户
开发者 编程人员本人 开发组织或开发机构
软件规模 微型、小型 大、中、小型
决定质量因素 个人技术水平 管理水平
数据库、工程化开发方法、标准
开发技术和手段 程序库
和规范、面向对象技术
维护者 编程人员本人 专职维护队伍
容量小、速度慢、 超高速、特大容量、
硬件特征
可靠性差 微型化、网络化
软件开发过程(软件生命周期)分为互相重叠的三个阶段:
(一) 开发与设计(development and design):它又可分为四部分:
1. 分析问题。
2. 研究解决方案。
3. 方案的代码化,也即编写程序,简称编程。
4. 程序的测试和修改。
(二) 编写文档(documentation)。
软件开发过程中涉及众多文档,例如需求说明书、可行性分析、实
施计划、概要设计说明书、用户手册等等。这是软件工程的一个重要环
节,也是软件工程与以前普通程序设计的一个重要区别。
(三) 维护(maintenance)。
这是三个阶段中耗时最长、费用最多的。最典型的例子是“Y2K
(2000年)问题”,曾拖延数十年之久。问题来源是上世纪许多程序只
用两位数表示年份,因而遇到50时就无法辨别它是1950还是2050。不
少公司花费大量精力修改数十年来运行的程序,以使它们能在本世纪中
成功地运行。
我们这门课只是上述各阶段中的一小部分,主要是第一阶段中的编程工作。
1.1.2 程序设计语言的五种形式
程序设计语言在发展过程中可分为五种形式:
1. 机器语言(machine language):
–
以0和1表示
–
手工操作
2. 汇编语言(assembler language):
–
稍微接近人的语言,例如
mov ax,100
add ax,bx等
–
开始使用批处理(batch processing)功能。
3. 高级编程语言(high-level programming language):
–
更接近于人类语言,但使用仍不方便
–
如60年代的ALGOL
4. 面向过程的程序设计语言(procedure-oriented programming language):
有时也称过程式程序设计语言(procedural programming language)或结
构化程序设计(structured programming language)语言。
–
结构化程序设计的产生和发展形成了现代软件工程的基础。
–
编程是面向过程的(procedure-oriented)或面向操作的(action-oriented),
编程单位是函数(function,子程序)。
–
整个程序是一个模块层次(hierarchy of modules),按功能划分为多个基本
模块,各模块之间关系尽可能简单,其功能相对独立,自顶向下进行功能分解。
–
每一模块内既有数据,又有代码,函数代码按一定算法对代码进行操作。
–
如FORTRAN,C语言等
5. 面向对象的程序设计(Object-Oriented Programming, OOP) 语言:
面向过程的程序设计具有以下缺点:
–
功能与数据分离,不易保持功能与数据的相容性。
–
软件修改困难。
–
限制了软件的可重用性,降低了软件开发效率,也难于维护软件。
为解决以上问题,人们进而研究面向对象技术,提出了面向对象的程序设计方
法。详见下节。
目前人们大多混合使用结构化程序设计语言和面向对象的程序设计语言。
1.2 面向对象的程序设计
编程是面向对象的(object-oriented),编程单位是类(class)
1.2.1
编程语言特征
面向对象编程语言直接描述有关域中的对象及其相互关系。它以客观世界中
所存在的事物为依据,较为接近人们的思维方式,具有如下特征:
(1) 客观世界由一系列事物组成,每个事物的特性被抽象出来后分别由一组属
性和一组操作(方法)来描述。这类事物就是面向对象编程语言中的类及其对象。
(2)客观世界的各事物可按其共性分为各类(称为基类,如人、车、鸟等),这
些类是具有相同共性的各事物的集合,它是面向对象语言中相对独立的程序单
位,是这些事物的统一抽象。
(3)不同事物除具有[基类的]共性之外,还具有各自的个性。因此应由具有不同
的属性和操作的特殊类加以描述。这些特殊类(称为派生类)通过继承机制继承
基类的共性(如汽车、拖拉机、坦克都继承“车”的共性),但派生类又各有自
己的个性。
1.2.2 优越性
面向对象的程序设计至少能解决结构化程序设计语言(例如C语言)中以下四
个无法解决的问题:
(A)数据的封装(数据的保护):
在面向过程的编程语言中,编程单位是函数,它们用于实施一定算法,对所有
数据进行操作。这就是Nicholase Wirth(Pascal编程语言的设计者)所提出的著名
公式:
算法 + 数据结构 = 应用程序
这种编程方法无法对全局变量加以控制:有时只要求一个函数独家对全局数据
进行赋值、读写,而不准其它函数对它赋值。这在面向过程的编程语言中无法做到,
因这些全局数据谁都可以读、可以写。因此软件工程规定应该尽少使用全局数据(全
局变量)。
但在面向对象的编程语言中,可以通过数据封装对数据加以保护,只允许被授
权者对数据读取或赋值,从而实现上述要求。
此点详见第三章。
(B)复杂程序中程序代码的可重用性(re-usability):
先看个简单例子。Windows操作系统允许用户在他自己的程序中设计不同窗口,
如同Windows操作系统的窗口一样。但又绝对不允许用户修改Windows的程序,
而且用户也没有能力修改。实际上用户根本不必修改Windows的程序,只需将自己
的程序模块贴上去即可在他自己的程序中设计并实现不同窗口。
复杂程序不但庞大,而且复杂。其复杂性表现在:必须由多个梯队合作完成编
程,因而管理比较困难;不易处理各种系统状态之间的正确切换;设计周期很长;
不易维护。
复杂程序不单要求运行正确,还须容易维护、具有好的可读性和可重用性。
好的可重用性允许在其它程序中再次使用复杂程序中一部分甚至于大部分现有
功能以及大量的通用模块,但又不引进任何错误。这将能节省费用、缩短开发周期
和减少程序的复杂性。
当解决这个问题时,在面向过程的编程语言中只能将其它程序部分地或全部地
复制过来,在加以改写,这极易引进错误。但在面向对象的编程语言中,不必进行
复制,只须通过继承机制即可实现可重用性。
详见第四章。
(C)同一方法(操作)具有多种功能:
以上提到,新程序可以继承并再次使用复杂程序中大量通用模块以及一部分甚
至于大部分现有功能。但仅这一点是远远不够的,它还必须具有为原有函数补充新
功能的能力。面向过程的编程语言并不具备此类能力。
而在面向对象的编程语言中,新程序能够将继承来的方法重新定义,补充旧功
能或增加新功能,同时又绝对不允许修改原有程序(因原有程序十分复杂)。这时
可以通过继承性重用大部分原有程序代码,而同时又允许用户通过多态性对此方法
补充新功能,以便该方法在不同情况下发挥不同功能。这就是多态性。
详见第五章、第六章和第七章。
(D)数据与程序的相容性(consistency) – 类型安全性(type-safety):
这个功能较小,但却有用。
[例1]在面向过程的编程语言C语言中,可能出现输出语句中的类型错误
#include
void main( )
{
int i=3;
double d=4.4;
printf(“%dt%fn”, i, d);
}
运行结果:
3 4.400000 对!
但如写错为:
printf(“%dt% d n”, i, d);
则编译时不出错,但运行结果错,为:
3 -26214,
其原因是不同类型的数据的字长不同(见第二章)。
但在面向对象的编程语言C++中,如使用:
cout<
则得 3 4.4, 不会出错!
此处C++中的对象cout解决了它与数据d的相容性!
此内容包括在第八章中。
1.3 C++语言概述
1.3.1 C++程序结构特点
先看C程序的结构特点:编程单位是函数(function)。C程序中至少有一个
函数,即主函数main( ),可能还有头文件,如 iostream.h。见下例:
[例1]#include
void main( )
{
int i=3;
double d=4.4;
printf(“%dt%fn”, i, d);
}
运行结果:3 4.4
C程序中一般还有其它函数(即子程序)如以下程序中的add( ):
[例2]#include < stdio.h >
int add(int i, int j)
{
int a;
a = i + j;
return a;
}
void main( )
{
int i = 3, j = 4, a;
a = add ( i, j);
printf(“%d”, a);
}
运行结果:7
可以看出,语句(statements)是程序的基本单元。每条语句由操作数和运
算符组成,用分号结束。操作数可以是变量、常量或表达式。运算符用于规定
对操作数进行运算操作的运行方式,分为三类:
1. 一元运算符:作用于一个操作数,又可分为前缀运算符和后缀运算符。
它们使用时分别放置于操作数的前面和后面。
2. 二元运算符:作用于两个操作数,它们使用时放置于两个操作数之间。
3. 三元运算符:作用于三个操作数。C++中仅有一个,即“条件运算符?:”
(见第二章§2.4.1.2)。
以上是C语言的结构特点,而C++语言的结构特点则有所不同。表现为:
C语言的编程单位是函数(function),而C++语言的编程单位是类(class)。
C语言的重点是函数,由一组完成类似任务的操作组成函数,而一批函数又组
成程序。C语言中的数据只用于支持函数所要完成的操作。
但C++程序中既要考虑函数,又要考虑数据,须将它们有机地组织起来,
成为新的编程单位,称为“类”。
C和C++程序的相同处在于:都由若干个文件组成。但其文件组成则不同。
C语言的每个文件由若干个函数组成,各函数是相对独立的程序段,这些函
数中只有一个是主函数(主程序)。
C++语言的每个文件中由若干个类组成,而绝大部分函数都包含在类中。同
样只有一个主函数。
下例中整个C++程序由5个源文件组成,各源文件的长度都不同。它们是:
、、、和。
文件一
文件二
文件三
文件四
文件五
以上各源文件并不一定彼此紧挨着,同时其顺序也常是随意的。
而任何一个源文件中又可包括以下内容:
头文件
全局变量和全局数据
类A
(包括数个函数体、数据或程序块)
class base
类B class derive
void main( ) {„„ „„}
及其它独立函数(外部函数)
整个程序的全部文件的所有独立函数中必定有也只能有一个主函数
main( )。
除头文件一般在源文件的首部外,其他类、独立函数和变量的顺序可以随意
安排。
类C
class grand
1.3.2
C++程序的实现
(一)源程序文件的编辑过程(editing)
形成源文件(source files),文件名称的后缀为cpp,例如。 由用
户编写和修改。
(二)两遍编译过程(two-pass compiling)
大部分编程语言采用单遍编译过程,但C和C++语言却都采用两遍编译过程:
(1)第一遍(first pass):
将源程序文件编译为汇编语言文件,汇编语言文件名称的后缀为 asm,例
如,read_等。一般编程人员不使用这类文件。但它在调试程序
以及深入分析程序时很有用。本课程多处使用此类文件。
调试程序时如果希望阅读汇编语言文件,可以在调试中将VC++的菜单项
“view”下拉,在子菜单“Debug Windows”中选择最后一项“Disassembly”
(热键为Alt+8),即可看到汇编语言文件。
(2)第二遍(second pass):
将汇编语言文件编译为目标文件(object files),目标文件名称的后缀为
obj,例如,read_等。这是编程人员常用的文件。
(三)连接过程(linking)
将所有目标文件连接为可执行文件(executable files),可执行文件名的后缀为
exe,例如,read_等。这是最后供编程人员使用可供运行的文件。
(四)调试过程(debugging)
使用各种调试程序对可执行文件进行调试,找出错误,可能出现三种错误:编
译错、连接错和算法错。
(五)维护过程(maintenance)
在可执行文件投入运行后的半年至一年甚至更长时间内,程序中还会出现各种
错误,需要继续调试,排除错误。
(第一章完)
版权声明:本文标题:第一章程序设计基本特点 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://roclinux.cn/p/1735682157a1682725.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论