Transcript
Page 1: 计算机与程序设计基础 - Baiduimages.china-pub.com/ebook55001-60000/57390/ch01.pdf第1 章 计算机与程序设计基础 3 程序原理的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制

第 1 章

计算机与程序设计基础

【学习目标】 1)理解计算机中信息的表示方法。 2)理解计算机的基本组成及各基本部件的功能。 3)理解软件的分类及常用软件的功能。 4)理解计算机的基本工作原理(存储程序原理)。 5)理解存储器的基本结构、存储单元、地址及按地址访问数据与指令的概念。 6)理解计算机主要技术指标的含义。 7)了解操作系统的发展、分类及操作系统的主要功能。 8)理解文件、目录与路径的概念。 9)理解计算机中存储信息的方法。 10)理解计算机采用的二进制编码及信息单位。 11)了解计算机的数字系统、计数法及进制的概念。 12)掌握十进制、二进制、八进制、十六进制数据之间的转换。 13)理解正负数、实数的浮点表示及值域和精度的概念。 14)理解计算机中非数值信息的表示方法(ASCII 码、汉字编码、Unicode 码及多媒体信

息编码)。 15)理解算法的概念、掌握算法的描述。 16)理解结构化程序设计思想、掌握结构化程序设计方法和规则。

1.1 引言

计算机技术是人类在 20 世纪最重要的发明之一。自 1946 年第一台计算机问世以来,计算机的应用已日益深入到我们社会的生产、生活、国防、科技、教学、商务、文化、娱乐等方方面面。大到宇宙飞船的发射、电子商务、电子政务的运行,小到电子邮件的收发、使用手机通话、通过网络聊天和玩电子游戏机,无不需要计算机技术的支持。随着技术的发展,计算机技术将会在人类活动的几乎所有领域得到应用,深刻而持久地改变我们的社会和生活。

计算机技术之所以具有如此大的影响力,一个重要的原因是,一台计算机由硬件系统和

Page 2: 计算机与程序设计基础 - Baiduimages.china-pub.com/ebook55001-60000/57390/ch01.pdf第1 章 计算机与程序设计基础 3 程序原理的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制

2 计算机程序设计(C 语言版)

软件系统两大部分构成。计算机的硬件,包括它的核心功能部件和外围设备,只是提供了一个具有广泛通用性的计算平台。计算机系统功能的多样化和复杂化,主要取决于它的软件系统。可以粗略地认为,硬件决定计算机系统的性能,而软件决定计算机系统的功能。硬件性能的提高在很大程度上取决于电子技术的进展,而软件功能的发展取决人们的需求,以及软件工作者的想象力和程序设计能力。硬件是基础,软件是计算机的灵魂,没有软件的计算机什么都不能做,只有安装了软件的计算机,才能进行信息处理,成为一台真正意义的计算机。

最初的计算机主要用于科学计算。现在,计算机作为一种现代化的处理信息的工具,其用途早已超出了数值计算的范围,可以用于文字、图形/图像、动画和声音等多媒体数据的处理。这些数据的外在表现形式差别很大,但在计算机内部,则用统一的二进制数表示,并有特定的计算机程序将其解释成不同的文字、图形/图像、动画和声音等。计算机所能完成的工作以及怎样完成工作都是由人指定的,即计算机所做的任何工作都是在由人编写的程序的控制下进行的。

根据计算机的工作特点,可以把计算机描述成是一种能存储程序和数据、并能自动、精确、高速执行程序的现代化智能电子设备,是一种能对各种数字化信息进行处理的工具。

学习计算机程序设计,不仅要了解计算机是什么,计算机能够做什么、如何做,而且还要知道这个学科领域解决问题的基本方法与特点,即学习这个学科领域解决问题的基本思维方法。因此本章介绍的内容主要有:计算机系统组成及基本工作原理、二进制编码、计数法、进制概念、各种数制转换,同时简要介绍算法和结构化程序设计的基本概念,为读者提供计算机程序设计的一般性准则,以便于本课程的学习。

1.2 计算机系统的基本组成与工作原理

1.2.1 计算机系统的组成

一个完整的计算机系统(Computer System)由硬件(Hardware)系统和软件(Software)系统两大部件组成。

硬件系统是指组成计算机的具体的物理设备。1946 年,美籍匈牙利数学家冯·诺依曼在参加第一台计算机的研制中,提出了三个重要的设计思想:

1)采用二进制编码形式表示数据和程序;

2)要执行的程序和被处理的数据预先放入计算机中,计算机能够自动地从内存中取出指令执行;

3)计算机由运算器、控制器、存储器、输入设备、输出设备五大基本部件组成(如图 1-1所示)。

冯·诺依曼的思想奠定了计算机科学发展的理论基础,并被应用于实际设计中,为计算机的发展立下了不朽的功勋。按照冯·诺依曼思想设计的计算机被称为冯·诺依曼结构计算机。60多年来,计算机的性能、速度、应用领域等都发生了翻天覆地的变化,但计算机的基本结构没有变。“存储程序原理”至今仍然是计算机的基本工作原理。存储

中央处理器 CPU

主机

(内)存储器

(外)存储器

输入设备 输出设备

说明: 表示控制流 表示数据流 图 1-1 计算机的基本结构

Page 3: 计算机与程序设计基础 - Baiduimages.china-pub.com/ebook55001-60000/57390/ch01.pdf第1 章 计算机与程序设计基础 3 程序原理的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制

3 第 1 章 计算机与程序设计基础

程序原理的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制下一步一步地进行处理,直到得出结果。自从计算机诞生的那一天起,这一原理就决定了人们使用计算机的主要方式——编写程序和运行程序。

冯·诺依曼计算机各大部件的名称和功能如下: 1)运算器。算术逻辑部件,又称 ALU(Arithmetic Logic Unit),负责完成所有算术运算、

逻辑运算任务。

2)控制器(Control Unit)。如同人的大脑,负责指挥计算机各部件按照指令指定的功能进行各种操作,使计算机能够按照程序的安排,自动完成规定的任务。

3)存储器(Memory Unit)。计算机的重要部件之一,是计算机能够实现“存储程序”功能的硬件基础。程序和数据以及运算的中间结果和最终结果均以二进制形式存储在其中。计算机的存储系统分为内部存储器(简称内存或主存)和外部存储器(简称外存或辅存)。内存中存放将要执行的指令和运算数据,存取速度快,但容量较小。外存容量大、成本低、存取速度慢,用于存放需要长期保存的程序和数据。当存放在外存中的程序和数据需要处理时,必须先将它们读到内存中,才能进行处理。

4)输入设备(Input Device)。用来接受用户输入的原始数据和程序,并将它们变为计算机能够识别的代码形式存放到存储器中。

5)输出设备(Output Device)。用于将存储器中经计算机处理得到的运算结果转变为人们所能接受的形式,输出到相应的介质上,供使用者观看、分析和保存。

五大部件构成了计算机的硬件部分。在微型计算机中运算器和控制器是集成在一个半导体芯片中的,通常把运算器和控制器统称为 CPU。CPU是中央处理器(Central Processing Unit)的英文缩写。人们常把 CPU和主存储器(内存)合称为主机。

计算机软件系统包括了计算机运行所需的各种程序及其有关的文档资料。计算机系统是在硬件(裸机)的基础上,通过一层层软件的运行,向用户呈现出友好的使用界面和强大的功能。根据程序的不同用途,通常把软件分为系统软件和应用软件两大类。

系统软件(System Software)是计算机设计制造者提供的管理计算机全部软硬件资源的软件。包括操作系统、语言处理程序、数据库管理系统、网络管理程序、工具与服务程序等。这些系统程序中,操作系统是最核心的软件,其他所有程序都要在它的支持下工作。

应用软件(Application Software)是专门为某一应用目的而编制的通用或专用程序,例如现在广泛使用的办公软件 Microsoft Office,还有财务、销售、管理、教学、产品设计等在各行各业运用的一些专用软件。应用软件必须在系统软件的支持下才能工作。

需要指出的是,计算机的硬件系统和软件系统之间是相辅相成、缺一不可的。没有任何软件的计算机称为裸机,裸机本身是不能完成任何功能的,只有配备一定的软件,才能发挥其功用。图 1-2概括了计算机的组成,图 1-3反映了用户和软件、硬件之间的关系。

运算器

控制器

中央处理器 (CPU)

存储器

输入设备

输出设备

系统软件

应用软件

计算机系统

软件

硬件

主存(内存)

辅存(外存) 外设

主机

应裸 机

作 系

用 户 用 程

序 其

系 统

图 1-2 计算机系统的组成 图 1-3 用户和软件、硬件之间的关系

Page 4: 计算机与程序设计基础 - Baiduimages.china-pub.com/ebook55001-60000/57390/ch01.pdf第1 章 计算机与程序设计基础 3 程序原理的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制

4 计算机程序设计(C 语言版)

1.2.2 计算机的基本工作原理

从图 1-1可见,计算机中有两股信息流在流动,一股是数据流,它包括参加运算的原始数据、运算过程中的中间结果和最终结果,还包括程序中的指令;另一股是控制流,是由控制器发往各部件的命令。在计算机内部,这些信息都用以“0”和“1”组合而成的二进制代码来表示,因为计算机能理解、识别的只能是二进制信息。我们把程序和数据同时存储在存储器中,在发出命令以后,计算机就能够自动完成运算,就是因为在存储器中存储了程序。计算机是在程序的控制之下自动完成相应操作的,这就是所谓的“存储程序原理”,又称冯·诺依曼原理。为深刻理解这一原理,下面介绍一下指令和程序的概念。

1)指令(instruction)。指令由一串二进制代码组成,是计算机完成一个基本操作的命令,如:传送、加法、移位、停机等都是一个基本操作。指令应能由控制器中的指令译码器所识别,因此,不同类型的计算机由于硬件的差异,指令代码也不同。一条指令实际上包括两种信息即操作码和操作数。操作码用来表示该指令所要完成的操作(如加、减、乘、除、数据传送等),其长度取决于指令系统中的指令条数。操作数用来描述该指令的操作对象,它或者直接给出操作数,或者指出操作数的存储器地址或寄存器地址(即寄存器名)。指令的一般格式如图 1-4所示。

2)指令系统(Instruction Set)。某一台计算机所能识别的所有基本指令的集合称为指令系统。指令系统的丰富与否,决定了计算机对数据的运算和处理能力的强弱。

3)程序(program)。程序就是为完成预定任务用计算机语言编写的一组指令序列。计算机按照程序规定的流程依次执行指令,最终完成程序所描述的任务。 用户在写好程序后,要通过输入设备输入到存储器中。计算机执行程序依规定的顺序执

行一条条指令,每一条指令的执行分为两个阶段:一是从主存储器将指令码取到 CPU中;二是 CPU对取入的指令进行分析译码,判断该指令要做什么,然后向各部件发出完成该操作的控制信号,使各部件产生相应的动作,这样就完成了一条指令的执行过程,如图 1-5所示。

4)程序设计语言(programming language)。又称编程语言。用户通常用某种编程语言编写程序,输入计算机,然后由翻译软件将其转换成计算机能够理解的语言(指令),在计算机上运行。程序设计语言分为低级语言(low-level language)和高级

语言(high-level language)。低级语言又称为面向机器的语言,如机器语言(machine language)、汇编语言(assembly language)。高级语言有面向过程的语言(procedure-oriented language)和面向对象的语言(object-oriented language),下面是一些常用的高级语言。

Fortran 语言 1954年推出,适用于科学和工程计算。 BASIC 语言 初学者语言,1964年推出;1991年微软推出可视化的、基于对象的 Visual Basic开发环境,发展到现在的 VB.NET开发环境。VB.NET是完全面向对象的、功能也更强大。 Pascal 语言 结构化程序设计语言,1968 年推出,适用于教学、科学计算、数据处理和系统软件等开发,目前已被 C语言取代。 C/C++语言 1972年推出 C语言,1983年语言的设计者加入面向对象概念,改名为 C++。C/C++语言简练、功能强、适用面广。 Java 语言 一种新型的跨平台的面向对象程序设计语言,1995年推出,适用于网络应用。 程序设计语言的发展经历了五代——机器语言、汇编语言、高级语言、非过程化语言和

操作码 操作数 图 1-4 指令格式

取指令 分析指令 执行指令

图 1-5 程序的执行过程

Page 5: 计算机与程序设计基础 - Baiduimages.china-pub.com/ebook55001-60000/57390/ch01.pdf第1 章 计算机与程序设计基础 3 程序原理的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制

5 第 1 章 计算机与程序设计基础

智能语言。

1.3 微型计算机的系统结构

本节介绍微型计算机系统,主要介绍:硬件方面的 CPU、内存、接口和总线等概念;软件方面介绍几种常用的操作系统、操作系统功能、文件、文件夹(目录)、逻辑盘、路径的概念。 微型计算机可以分成微处理器(Micro Processor)、微型计算机(Microcomputer)、微型计

算机系统(Microcomputer System)三个层次,如图 1-6所示。微型计算机包含了许多种系列、档次、型号的计算机,如 IBM PC、联想开天等。这些计算机的共同特点是体积小,适合放在办公桌上使用,而且每个时刻只能一人使用,因此又称为个人计算机。

1.3.1 微型计算机的主要性能指标

(1)字长 字长是衡量计算机处理能力的重要指标,它是

指计算机的 CPU 一次能直接处理的二进制数的位数,字长越大,计算机的处理能力越强。例如,8086、286 的字长是 16 位,386、486、586(奔腾)都是32位。而现在已有了 64位甚至多核的微处理器。 (2)速度 衡量计算机速度常用的有两种指标: 运算速度:用每秒钟能执行多少条指令来表示。国际上通用的指标是每秒百万条指令MIPS(Million Instructions Per Second),通常用于较大的计算机系统。 主频:指 CPU主时钟的工作频率(一秒钟内发生的同步脉冲数),主频越高,说明 CPU的速度越快,微型计算机都用主频这个指标。主频的单位为兆赫兹(MHz),早期的微机 CPU主频才几兆赫兹,而现在已达到 3GHz以上。例如,“酷睿 2/2.4G”,“酷睿 2”表示 CPU的型号(酷睿双核 CPU),“2.4G”就表示主频是 2.4GHz。

(3)内存容量 通常用字节(Byte)作基本单位。目前,微型计算机的内存容量已达到数 G字节。 (4)存取周期 微机内主存完成一次读/写操作所需的时间称为存储器的存取时间,连续两次读/写所需的

最短时间称为存储器的存取周期。存取周期越短,则存取速度越快。存取周期的大小影响着计算机的运算速度。 (5)外部设备的配置和软件的配备 要求显示器、键盘、打印机、磁盘和光盘驱动器等外部设备基本配置齐全,安装合理、达

到测试标准。对操作系统、汉字处理能力、数据库管理系统以及网络功能等必须作全面衡量。 此外,还有性能价格比、可靠性、可用性、可维护性等指标。

1.3.2 微型计算机的硬件组成

微型计算机的硬件由主机和外部设备组成,图 1-7是 IBM PC系列机的典型结构。 1.主板 主板(Main Board)是固定在计算机主机箱箱体上的一块电路板(如图 1-8所示)。主板

上装有大量的有源电子元件。其中主要组件有 CMOS、基本输入输出系统(BIOS)、高速缓冲存储器(Cache)、内存插槽、CPU 插槽、键盘接口、硬盘驱动器接口、总线扩展插槽(提供

微型计算机系统 微处理器

微型计算机

运算器 控制器 寄存器组

内存储器 总线

输入输出接口

外部设备 软件

图 1-6 微型计算机系统的组成

Page 6: 计算机与程序设计基础 - Baiduimages.china-pub.com/ebook55001-60000/57390/ch01.pdf第1 章 计算机与程序设计基础 3 程序原理的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制

6 计算机程序设计(C 语言版)

ISA、PCI 等扩展插槽)、串行接口(COM1、COM2)、并行接口(打印机接口 LPT1)、通用串行总线 USB接口等,因此,主板是计算机各种部件相互连接的纽带和桥梁。

主板 硬盘适配器软盘适配器

软盘驱动器 硬盘驱动器 光盘驱动器 主机箱

RAM/ROM

微处理器

并行接口 串行接口

显示器 打印机鼠标,调

制解调器音响,话筒

显示卡 声卡

总线(ISA、EISA、VESA、PCI…)

外部设备

图 1-7 PC的典型结构

2.中央处理器 中央处理器(Central Processing Unit)简称 CPU(见图 1-9),是计算机的核心,包括运

算器、控制器等。计算机的运转是在 CPU的控制下实现的,所有的算术运算和逻辑运算都是由它完成的。因此,CPU是决定计算机速度、处理能力和产品档次的关键部件。

I/O 接口

CPU插座

电源插座

内存插槽

软盘接口

IDE 硬盘接口

PCI 总线扩 展槽

芯片组(南桥)

AGP扩展槽

芯片组(北桥) 图 1-8 主板 图 1-9 CPU

3.存储器 存储器(storage/memory)分为主存储器(内部存储器)和辅

助存储器(外部存储器),通常称为内存和外存。计算机的存储器层次结构如图 1-10所示。CPU只能与内存之间直接进行信息交换,用户编写的程序以文件的形式存储在外存上,程序运行时,装载入内存,再一条一条装入 CPU的控制器执行。数据则送入运算器,运算的结果再送入内存,然后在屏幕上显示、打印机上打印,或以数据文件的形式输出到外存保存起来。

CACHE

主存(内存)

辅存(外存)

CPU

图 1-10 存储器层次结构

Page 7: 计算机与程序设计基础 - Baiduimages.china-pub.com/ebook55001-60000/57390/ch01.pdf第1 章 计算机与程序设计基础 3 程序原理的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制

7 第 1 章 计算机与程序设计基础

(1)主存储器 主存储器(Main memory)简称主存,因为是在主机的内部,所以通常又称为内(部)存

(储器)。是计算机硬件的一个重要部件,其作用是存放指令和数据,并能由中央处理器直接随机存取。现代计算机为了提高性能,又能兼顾合理的造价,采用多级存储体系。即由存储容量小、存取速度高的高速缓冲存储器(Cache)与存储容量大、存取速度次之的主存储器相结合。

计算机在执行程序前必须将程序和数据装入内存中,这种装入信息的操作称为“写入”;所执行的指令及处理的数据,也必须从内存取出,这种取出信息的操作称为“读出”。存储器读出信息后,原内容保持不变;向存储器写入信息,则原内容被新内容所代替。

由于内存是由半导体器件构成的,没有机械装置,所以内存的读写速度远远高于外存,但容量也相对较小,主要用来存放计算机正在使用的程序和数据。

从功能来看,内存一般分为 ROM和 RAM两类。 ROM(Read Only Memory,只读存储器)。ROM的特点是只能从中读出信息,而不能向其中写入信息,在关机和断电后,ROM 中的内容仍能保存,不会丢失。ROM 的写入,需要用专门的编程器完成。一般 ROM中存储的是由厂家存入的系统引导程序、自检程序、输入输出驱动程序等。 RAM(Random Access Memory,随机存储器)。RAM的特点是其中存放的内容可随机读写,但 RAM中的信息具有易失性,关机或断电后信息会丢失。计算机在运行时,系统程序、用户程序以及所用数据都存放在 RAM中。

一般用户直接使用的是 RAM,通常我们所说的内存大小也指的是 RAM。下面根据存储器的结构示意图(见图 1-11)介绍一些与存储器有关的概念。

从图 1-11中可见,存储器由若干个单元组成,每个单元有一个唯一的编号,称为地址。信息的最小单位是二进制的位(bit),每 8 个二进制位定义为一个字节(Byte),存储器以字节为单位来进行编址。CPU 访问内存时,一次最多能读写几个字节取决于字长是多少,字长一般是 8的 2n倍(与数据总线的根数有关),字长反映了计算机处理数据的能力与效率。例如:字长为 16位的 CPU,它的数据总线是 16条,一次最多可读写某地址开始连续 2个字节的 16位数;字长为 32 位的 CPU,则数据总线是 32条,一次最多可读写某地址开始连续 4 个字节的 32 位数。存储单元的数量称为存储容量,微机中以 B、KB、MB、GB、TB 作为计量存储器容量的单位,1B表示一个字节,1KB=1024B(210B)、1MB=1024KB(220B),1GB=1024MB(230B)、1TB=1024GB(240B)。

RAM

存储单元内容

0 1 0 0 0 0 0 1

0 1 0 0 0 0 1 0

0 1 0 1 1 0 1 0

字节(Byte)

存储单元地址

0000H 0

0001H 1

0064H 100

FFFFH 65535

读/写命令(来自控制总线)

﹒ ﹒

十进制地址值十六进制地址值

地址信息 (来自地址总线)

设地址总线为 16 条

数据信息 (来自数据总线)

图 1-11 存储器结构示意图

Page 8: 计算机与程序设计基础 - Baiduimages.china-pub.com/ebook55001-60000/57390/ch01.pdf第1 章 计算机与程序设计基础 3 程序原理的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制

8 计算机程序设计(C 语言版)

内存容量是反映计算机性能的一个很重要的指标,目前常用的微机内存容量有 512MB、1GB、2GB等,也有高达 4GB的。 (2)辅助存储器 辅助存储器(auxiliary memory)简称辅存,因为安装在主机的外部,所以通常称为外(部)

存(储器)。它主要用来存放主存储器难以容纳、又是程序执行所需要的大量文件信息。它的特点是存储容量很大,存储成本低,但存取速度较慢。它不能直接与中央处理器交换信息,CPU只能通过输入输出通道访问外存的信息。

目前常用的外存有硬盘、U盘、光盘、固态硬盘(SSD)和磁带等(见图 1-12)。硬盘、U 盘、固态硬盘上的信息都是可以读写的,并可长期保存,断电也不会消失。硬盘容量大,已达若干 TB。而 U盘使用、携带方便,常用于拷贝保存文件。外存是一种特殊的设备,如果站在存储器的角度看,它是外存,但如果站在外设的角度看,它是一种特殊的输入输出设备,既可以输入,也可以输出。

U盘 光盘 硬盘 固态硬盘 磁带

图 1-12 常用外部存储器

4.输入/输出接口与输入/输出设备 输入/输出(Input/Output)简称 I/O,I/O接口是微处理器与 I/O设备之间交换信息的连接

电路,外设必须通过接口连接到系统总线上再与 CPU相连。I/O接口的作用,主要是协调 CPU与外设间的速度、信息格式、信息类型等差异,使之能正确完成 CPU与 I/O设备间的信息交换。因此 I/O接口又常称为适配器,适配器一般做成插板形式,故也称为适配卡或接口卡。

早期,每一台 I/O设备都需要有与之匹配的接口卡(见图 1-13),接口卡插在主板的扩展槽上。随着技术的发展,主板上的芯片组集成了接口卡的功能。现在,除了特殊要求,一般不再需要插接口卡了,I/O设备可以直接连在主机箱的前面板和后面板上相应的 I/O接口插座上(见图 1-14)。

鼠标

键盘

串行口

并行口音频输入 音频输出 话筒输入

VGA USB(2) USB(2)

网络接口

图 1-13 接口卡 图 1-14 微机的 I/O接口

输入/输出设备(简称 I/O设备)是指那些用于输入或输出的具体设备,I/O设备通过 I/O接口、总线与 CPU之间建立联系。微型机常用的 I/O设备有键盘、鼠标、显示器、打印机。对于多媒体计算机,还常有语音输入机、扫描仪、绘图机、录像机、VCD机、音响等设备。

5.系统总线 总线(Bus)就是计算机部件与部件之间进行信息传输的一组公共信号线及相关的控制逻

辑电路。它是一组能为计算机多个部件服务的公共信息传输通路,能分时地发送或接收各部件的信息,如图 1-15所示。

系统总线(System Bus)又称内总线或板级总线。因为该总线是用来连接微机各功能部件

Page 9: 计算机与程序设计基础 - Baiduimages.china-pub.com/ebook55001-60000/57390/ch01.pdf第1 章 计算机与程序设计基础 3 程序原理的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制

9 第 1 章 计算机与程序设计基础

而构成一个完整微机系统的,所以称之为系统总线。系统总线在微型计算机中的地位,如同人的神经中枢系统,采用总线结构是微型机组成结构最显著的特点之一。 在系统总线上通常传输三种信号:数据、地

址和控制信号,相应的总线也分为数据总线(Data Bus)、地址总线(Address Bus)和控制总线(Control Bus)三类。系统总线常被比作“高速公路”,总线上的数据流则视为公路上的“车辆”,显然,交通是否畅通直接依赖于总线,因此总线技术是微机系统结构的一个重要方面。PC机上使用过的总线有 ISA总线、EISA总线、PCI总线等。现在 PC机上普遍使用的是 PCI总线。

主板上的总线扩展槽(见图 1-8)是系统总线的延伸,用来接插各种外部设备的接口卡,是主机与各种接口卡之间传送数据的通道。 (1)PCI扩展槽 外围设备互联扩展槽(Peripheral Component Interconnect)简称 PCI扩展槽,是基于 PCI

局部总线的扩展插槽,其颜色一般为乳白色,它是目前个人电脑中使用最为广泛的接口,几乎所有的主板产品上都带有这种插槽。PCI总线是一种高性能局部总线,是为了满足外设间以及外设与主机间高速数据传输而提出来的。在数字图形/图像和语音处理,以及高速实时数据采集与处理等对数据传输率要求较高的应用中,采用 PCI 总线来进行数据传输,能在高时钟频率下保持高性能,适合为显卡、声卡、网卡、Modem 等设备提供连接接口,PCI 总线系统要求有一个 PCI控制卡,它必须安装在一个 PCI插槽内。 (2)AGP扩展槽 加速图形端口扩展槽(Accelerated Graphics Port,AGP)用于连接显示设备的接口,是为

了提高视频带宽而设计的一种接口规范,可以显示高质量的三维动态图形和图像。

1.3.3 微型计算机的软件系统

没有任何软件的计算机称为裸机,裸机是不能完成任何工作的,可以说软件是计算机工作的“灵魂”。软件系统是由系统软件和应用软件两大类组成的。

1.微型机的系统软件 系统软件是由生产厂家或公司在出售计算机时提供给用户的。微机上常用的系统软件主

要有: (1)操作系统 操作系统(Operating System,OS)是一个功能强大的、能对计算机的软硬件资源进行管

理的软件。操作系统是系统软件的核心,其他所有程序都要在它的支持下工作。操作系统一般应具备处理器管理、存储器管理、文件管理、设备管理、作业管理等五大功能,当然对于用途不同的操作系统,不一定要具备全部功能。

操作系统可分为批处理操作系统、分时操作系统、实时操作系统、分布式操作系统、网络操作系统、嵌入式操作系统、个人计算机操作系统等类型。

下面简要介绍几种微型计算机上常用的操作系统及其功能和一些相关基本知识。 磁盘操作系统(Disk Operating System,DOS)是典型的单用户、单任务操作系统,它对

计算机的发展、普及、应用以及计算机文化的形成都有不可估量的推动作用。其特点是字符界面、行式命令、需要记忆基本操作命令。

主存储器 I/O接口

I/O

设备

地址总线AB

数据总线DB

控制总线CB

I/O总线

控制

CPU

图 1-15 微型计算机的总线结构

Page 10: 计算机与程序设计基础 - Baiduimages.china-pub.com/ebook55001-60000/57390/ch01.pdf第1 章 计算机与程序设计基础 3 程序原理的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制

10 计算机程序设计(C 语言版)

Windows操作系统是微软公司开发的具有图形用户界面(GUI)的多任务操作系统。所谓多任务是指在操作系统环境下可以同时运行多个应用程序,如可以一边在 Word软件中编辑稿件,一边让计算机播放音乐,这时两个程序都已被调入内存储器中并处于工作状态。

Windows是在微软的 DOS操作系统上发展起来的。由最初的 Windows 1.0版、Windows 3.x、Windows 9x、Windows NT,Windows 2000,到现在普遍使用的 Windows XP和 Windows 7等。Windows 7操作系统于 2009 年 10 月正式发布,支持 32 位及 64 位双核以上等级的处理器。与以往的版本相比,Windows 7具有更友好、更快速、更简单、更安全等特点。

UNIX系统是世界上应用最广泛的操作系统之一,它具有多用户、多任务、多进程的特性。随着计算机技术,特别是硬件的迅猛发展,该系统得到不断的发展和完善。UNIX系统广泛用于小型机以及工作站上,并已成为工作站以及 32 位高档机的标准操作系统。在国外,UNIX系统占据着计算机操作系统的主导地位。实际上,UNIX系统是对 UNIX各种版本的总称。目前用于 PC机的类 UNIX系统有 SCOUnix、Xenix和 Linux等。因为 Linux系统是免费的,所以应用也较普遍。

UNIX系统是 C语言的宿主系统,即最初的 C语言只是为描述和实现 UNIX 操作系统提供一种工作语言而设计的,后来随着 UNIX的普及而被引起注意,又因其本身的高效、灵活、功能丰富、表达力强、移植性好等优点受到广泛的重视并普及应用。C 语言已是目前世界上最流行、最实用的计算机高级程序设计语言之一。 (2)语言处理程序 语言处理程序(language processor)一般由汇编程序、编译程序、解释程序和相应的操作

程序等组成,它是用来把用户用其他编程语言编写的源程序(source program)翻译成计算机能够识别的由机器语言构成的目标程序(object program)的系统程序,如 MASM汇编程序、Turbo C 3.0、Visual C++ 6.0 、SQL、Foxpro、ASP等。

处理器只认识机器语言,机器语言以外的计算机编程语言都要靠语言处理程序把它们翻译成机器语言才能在计算机中运行。翻译的方法有两种,一种叫编译,一种叫解释。

编译(compiled)方式,是把针对某种计算机编程语言的编译程序事先安装在计算机上,当用户把用该种编程语言编写的源程序输入计算机后,调用编译程序便可把源程序全部翻译成用计算机机器语言表示的与之等价的目标程序,然后计算机再执行该目标程序。编译就好像笔译,把“外文”(非机器语言程序)全部翻译成“中文”(生成一个完全由机器语言组成的新程序,称为“执行文件”)。以后每次计算机就直接运行这个“执行文件”,不需要再翻译了,就好像翻译将外文书翻译成中文,我们只要看翻译好的中文书就行了。C 语言就是编译执行的,使用的语言处理程序有 Turbo C 3.0、Visual C++ 6.0等。编译过程如图 1-16所示。

解释(interpreted)方式,是指源程序输入计算机后,事先装好的针对该计算机语言的解释程序对源程序逐句翻译,翻译一句,执行一句。解释就好像口语翻译,把源程序(用非机器语言编写的程序)的一句话(语句),翻译成计算机唯一识别的机器语言(指令),让计算机执行。接着翻译下一句,再让计算机执行,直到程序执行完毕。当重新执行这个程序时,仍然是翻译一句,执行一句。BASIC语言就是以解释方式为主,解释过程如图 1-17所示。

编译 连接 目标程序

编译程序

源程序 执行程序 执行

连接程序

解释

机器指令 执行 源程序

解释程序

图 1-16 编译过程 图 1-17 解释过程

(3)数据库管理程序 这是指对数据库中的数据进行维护和管理的系统程序。如 Foxpro、SQL Server、Oracle、

Page 11: 计算机与程序设计基础 - Baiduimages.china-pub.com/ebook55001-60000/57390/ch01.pdf第1 章 计算机与程序设计基础 3 程序原理的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制

11 第 1 章 计算机与程序设计基础

Access等都是微型机上应用比较广泛的关系型数据库管理系统。 (4)常用服务性程序

这包括编辑程序、调试程序、装配与连接程序、系统的维护与测试程序等。

2.关于文件、文件夹(目录)、逻辑盘、路径的概念 (1)文件 文件是计算机中一个很重要的概念,它是操作系统用来存储和管理外存上信息的基本单位。 计算机中的所有信息都是存放在文件中的。文件是存放在外存上的一组相关信息的集合,

它可以是源程序、可执行程序、文章、信函或报表等,文件通常存放在硬盘、U 盘或光盘等介质上,通过文件名进行管理。

所有程序和数据都是以文件的形式存储在磁盘上,每个文件必须有一个正确的名字,因为对一个文件的所有操作(建立、读、写、删除、显示等)都是通过文件名进行的。文件的名称由文件名和扩展名(后缀)组成,文件名和扩展名之间用一个半角“.”隔开。扩展名通常由 1~4个合法字符组成,文件的扩展名一般用来表明文件的类型。

文件名的一般格式:文件名.扩展名 如 DOS的文件名由 1~8个字符组成,扩展名由 1~4个字符组成。Windows允许文件命

名时,最多可长达 255 个字符。用长文件命名可以更好地将文件从名字上区分,便于调用,文件名和扩展名中的字符可以是:26个英文字母、10个阿拉伯数字以及_、∧、$、~、!、#、%、&、−等特殊字符。但不能含有空格、逗号、反斜杠或圆点等符号。汉字也可用作文件名,不过汉字所占字符位不同。原来使用的汉字编码占两个字符位,新的标准有所变化,使用时务必注意。

在对文件进行保存时,一定要注意给出文件名(否则使用系统或软件默认的文件名),选择文件的保存位置(否则在当前位置保存)。一般应用程序创建的文件会有相应的后缀(如Word 文档有 doc 后缀,VC++ 6.0 源程序有 cpp 后缀),不需要特别指定,除非你有特别的要求需要选择或输入文件后缀(如 VC++ 6.0环境下运行 C源程序,就应该将源程序的文件后缀指定为.c)。

这里有一个通配符的使用概念。有时想对几个文件做相同的操作,如一次复制一组文件或列出一组文件名等。通配符“?”和“*”可以帮助你达到这个目的。 “?”通配符可以代表一位任意字符。例如,prg???.c表示当前目录下的所有文件名以 prg

开头、后面紧跟三个任意字符,且扩展名为 c的文件。 “*”通配符代表所在位置及其之后的任意个数的字符串,即可代表任意一组字符,最多

时可代表整个文件名或扩展名。例如*.c表示所有的扩展名为 c的文件,*.*则表示当前目录下的所有文件。 (2)文件夹 文件夹也叫目录,是文件的集合体,文件夹中可包含多个文件,也可包含多个子文件夹。 DOS、Windows、UNIX系统对磁盘文件的管理采用目录及树型结构。如上所述,系统处

理磁盘上的信息是以文件为单位的。磁盘上的文件成千上万,为了便于管理及提高搜索文件的速度,系统都采用多级目录结构进行文件管理,通常把系统软件、各种应用软件、用户程序和数据文件等磁盘文件分类存放于不同的目录下。

磁盘在进行格式化的时候,会自动建立一个根目录,之后我们可以根据需要在根目录下建立若干不同级别的子目录,磁盘上的目录结构好像一棵倒置的“树”,根目录就是“树根”,各层子目录是“树枝”,文件就是“树叶”,因此常称其为树型目录结构。图 1-18是 UNIX文件系统从根目录开始的层次结构。

在树型目录结构中,只有一个根目录,处于最顶层,用“\”表示。文件以集中的方式存

Page 12: 计算机与程序设计基础 - Baiduimages.china-pub.com/ebook55001-60000/57390/ch01.pdf第1 章 计算机与程序设计基础 3 程序原理的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制

12 计算机程序设计(C 语言版)

放在目录中,目录中可包含多个文件,也可包含多个子目录。目录本身也是一个文件,注册在上一层的目录之中。相对于某个目录,我们把它的上一级目录称为它的父目录,把它的下一级目录称为它的子目录。父子目录是相对而言的。每一个子目录只有一个父目录,但可以有多个子目录。例如图 1-18 中,子目录 pb09203 是子目录 p9203001 的父目录,又是子目录user 的子目录。根目录没有父目录。需要注意的是,在同一个目录下,不允许有相同的子目录名或文件名。在不同目录下可以使用相同名字的文件,在处理时也不会发生混乱。

root(\)

bin lib etc home toolb

pb09203 pb09205

p9203001 p9203002 P9203288 P9205001 t1.do …

…… filel. subdir 五级子目录

四级子目录

三级子目录

二级子目录

一级子目录 ……

…… …

user

a.ou

图 1-18 UNIX的层次结构

(3)逻辑盘 在这里我们还要了解“当前盘”和“当前目录”的概念。

在 DOS系统启动成功后,自动显示包含系统盘符的提示,如 C:\>,此时对磁盘的操作默认是对 C盘操作,这时 C盘就是“当前盘”。又如在 UNIX系统,通常每个用户都有一个称为起始目录(home directory)的用户目录。登录时,用户首先进入这个目录,并从这个目录开始工作。起始目录也称登录目录,也是用户登录成功进入系统后的“当前目录”,“当前目录”所在磁盘,即为“当前盘”。

当前目录可以用它的名字或“.”代表。当前目录的父目录可用它的名字或“..”代表。 当一个盘建立了目录结构,操作时就需要指明要找的文件在哪个目录下,系统对每个磁

盘都记忆一个目录。操作一个文件时,如果没有指明目录,则自动到系统记忆的这个目录中去找,该目录被称为“当前目录”。

当前盘和当前目录都是可以通过相应的系统命令改变的。 如 UNIX用户 p9203002登录成功进入主目录 p9203002后,可在系统提示符“$”后键入:

cd subdir↙ 进入子目录 subdir,这时 subdir即变为当前目录。 每个目录都有一个目录名,命名规则与文件名相同。 注意:由于 UNIX 是大小写敏感的,如果文件名的字母相同,但有大小写之分,则代表

各自不同的文件或目录。例如 myfile.c 和 Myfile.c 的含义不同,它们是互不相同的两个文件。 (4)路径 所谓路径是指从根目录或当前目录到指定的目录或文件所要经过的路线的描述。依次所

经过的各个目录之间要用反斜杠“\”隔开。 当我们要对一个文件操作时,必须先确定它处在什么位置上,如果不在当前目录下,则

Page 13: 计算机与程序设计基础 - Baiduimages.china-pub.com/ebook55001-60000/57390/ch01.pdf第1 章 计算机与程序设计基础 3 程序原理的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制

13 第 1 章 计算机与程序设计基础

必须指出找到它需经过的路径。 对路径的描述有两种,绝对路径和相对路径。从根目录开始的路径,称为绝对路径;从

当前目录开始的路径,称为相对路径。假设在图 1-18所示的目录结构中,当前目录是子目录pb09203,要操作的文件是 file1.c,如何描述文件 file1.c的路径呢?

绝对路径:\home\user\pb09203\p9203002\file1.c。 相对路径:p9203002\file1.c,也可通过“.”(当前目录)或“..”(当前目录的父目录)表示成:.\p9203002\file1.c或 ..\pb09203\p9203002\file1.c。

如果我们要操作的文件不在当前盘,则还必须确定它所在的盘符,所以一个完整的文件标识应由三部分组成:[盘符][路径]<文件名[.扩展名]>。

计算机的外存一般都是硬盘。为了便于数据管理,硬盘又分成几个逻辑盘,用盘符(例如 C、D等)来标识。

在 Windows系统中要指定文件的完整路径,应先输入逻辑盘符号(例如 C、D或其他),后面紧跟一个冒号“:”和反斜杠“\”,然后输入所有文件夹名,上下文件夹中间用反斜杠分隔,最后输入文件名(如许多 Windows系统文件存储在一个路径为 C:\ Windows的文件夹中)。在 Windows系统中,可以通过“资源管理器”或“我的电脑”对文件进行管理。

1.4 计算机中信息的表示及存储形式

1.4.1 计算机采用二进制编码

在冯·诺依曼结构计算机中,所有的信息(包括数据和指令)都是采用二进制编码进行

存储与处理,即便是图形/图像、声音等这样的信息,也必须转换成二进制编码信息形式,才能存入计算机中。这是由计算机中所使用的逻辑器件所决定的,这种逻辑器件是具有两种状

态的电路(触发器)。在计算机内部,信息的表示依赖于机器硬件电路的状态,信息采用什么

表示形式,影响到计算机的结构与性能。采用二进制编码的好处是:

1)易于物理实现。因为具有稳定的物理器件很多,如门电路的导通和截止、电压的高低等,而它们恰好对应表示“1”和“0”两个符号。假如采用十进制,需要制造具有十种稳定状态的物理电路,那是十分困难的。

2)二进制运算简单。数学推导证明,对 R进制进行算术运算求和或求积,其运算规则为R(R+1)/2种,如采用十进制,就需要 55种求和或求积的运算规则,而二进制仅各需要三种。所以采用二进制简化了运算器等物理器件的设计,易于物理实现。

3)机器可靠性高。由于电压的高低、电流的有无等都是“质”的变化,两种状态分明。所以基于二进制编码的传递抗干扰能力强,鉴别信息的可靠性高。

4)通用性强。二进制编码不仅成功地运用于数值信息编码,而且适用于各种非数值信息的数值化编码。特别是仅有的两个符号 0 和 1 正好与逻辑命题的两个值“假”与“真”相对应,从而为计算机实现逻辑运算和逻辑判断提供了方便。

计算机存储器中存储的都是由“0”和“1”组成的信息,但它们分别代表各自不同的含义,有的表示机器指令,有的表示二进制数据,有的表示英文字母,有的则表示汉字,还有

的可能表示图形与声音等。存储在计算机中的信息采用了各自不同的编码方案。 虽然计算机内部均采用二进制数来表示各种信息,但计算机与外部交往仍采用人们熟悉

和便于阅读的形式,如十进制数据、文字显示以及图形描述等,其间的转换,则由计算机系

统的硬件和软件来实现。

Page 14: 计算机与程序设计基础 - Baiduimages.china-pub.com/ebook55001-60000/57390/ch01.pdf第1 章 计算机与程序设计基础 3 程序原理的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制

14 计算机程序设计(C 语言版)

1.4.2 计算机中的信息单位

在计算机内部,各种信息都是以二进制形式存储,信息的单位通常采用“位”,“字节”,“字长”几种量纲。

1)位(bit):位是度量数据的最小单位,表示一位二进制数字。 2)字节(Byte):一个字节由八位二进制数字组成(1B=8bit)。字节是信息组织和存储的

基本单位,也是计算机体系结构的基本单位。计算机的存储器(包括内存和外存)通常都是以字节作为容量的单位。常用的单位有:

K/千字节 1KB=210=1024B M/兆字节 1MB=220=1024KB=1 048 576B G/吉字节 1GB=230=1024MB=1 073 741 824B T/太字节 1TB=240=1024GB=1 099 511 627 776B 3)字长:字长是计算机硬件设计的一个指标,它代表了机器的精度。字长是指 CPU 在

一次操作中能处理的最大数据单位,它体现了一条指令所能处理数据的能力。例如一个 CPU的字长为 32 位,则每执行一条指令可以处理 32 位二进制数据。如果要处理更多位的数据,则需要几条指令才能完成。显然,字长越长,CPU可同时处理的数据位就越多,功能就越强,但 CPU的结构也就越复杂。CPU的字长与寄存器长度及数据总线的位数都有关系。早期的微处理器有 8位机、16位机和 32位机,而目前已达 64位。

计算机的字长一般视运算精度的要求,都设为字节的 2n倍,如 4个字节(32位)、8个字节(64位)等。

1.4.3 计算机中的数字系统

因为计算机只能识别和处理二进制信息,所以计算机内部处理的数据都是二进制的,但在用高级语言编写程序时,为适应人们的使用习惯,通常使用十进制形式的数,在输入数据或输出运行结果时,也多采用十进制形式,有时也需要用到八进制或十六进制形式进行输入输出。因此我们要了解这些表示形式及他们之间的关系,以及数据如何在计算机内部存储,这是学习 C语言程序设计必备的基础知识。

人们日常生活中最熟悉的是十进制数,而数值信息在计算机内的表示方法就是采用二进制,在计算机应用过程中必然会涉及二进制、八进制、十六进制系统。无论哪种数制,其共同之处都是进位计数制。

1.数的位置计数法及进制的概念 一般来说,如果数制只采用 R个基本符号,则称其为基 R数制,R称为数制的“基数”,

而数制中每一位固定位置对应的单位称为“权”。 进位计数制的编码规则遵循“逢 R 进位”的规则,各位的权是以 R 为底的幂,1 个数可

按权展开成为多项式。例如,1个十进制数 N=1979.126 可按权展开为:

3 2 1 0 1 2 3

11 10 9 10 7 10 9 10 1 10 2 10 6 10

mi

ii n

N a X−

− − −

= −

= × + × + × + × + × + × + × = ∑

没有小数时, 0

1

ii

i nN a X

= −

= ∑

式中 n——整数部分的位数; m——小数部分的位数;

Page 15: 计算机与程序设计基础 - Baiduimages.china-pub.com/ebook55001-60000/57390/ch01.pdf第1 章 计算机与程序设计基础 3 程序原理的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制

15 第 1 章 计算机与程序设计基础

X——进制数(基数); ai——系数(0~X−1中任意一个数)。 103、102、101、100、10−1、10−2、10−3,⋯⋯分别称为十进制的位权。由上例可见:每一

位数的数值=数码×权,这就是所谓的位置计数法,上式称为按权展开式。 由此可见,只要取不同的基数,即可得到不同进制数 N用位置计数法表示的按权展开式,

从而得到它所代表的十进制数值。例如:

任意二进制数0

1

ii

i nN a X

= −

= ∑ ,基数是 2, ia 代表 0~1,各位的位权是 2i。

任意八进制数0

1

ii

i nN a X

= −

= ∑ ,基数是 8, ia 代表 0~7,各位的位权是 8i。

任意十六进制数0

1

ii

i nN a X

= −

= ∑ ,基数是 16, ia 代表 0~

9、A、B、C、D、E、F,各位的位权是 16i。

显然,由于基数不同,同样一个数代表的值是不同的,原因在于位权不同,例如:

(11011)10=1×104+1×103+0×102+1×101+1×100=(11011)10 (11011)2=1×24+1×23+0×22+1×21+1×20=(27)10 (11011)8=1×84+1×83+0×82+1×81+1×80=(4617)10 (11011)16=1×164+1×163+0×162+1×161+1×160=(69649)10 不同进制的数,常用如上的脚标来区别,也可以加一

个后缀字母来区别,如用 B(Binary)标识二进制,用 H(Hexadecimal)标识十六进制,用 O(Octal)标识八进制,但为了避免字母与数字 0之间的混淆,常用 Q代替 O,用D(Decimal)或空标识十进制。例如 78999D,1100111B,33440Q,7FFH,分别表示十、二、八、十六进制数。

2.各种数制之间的转换 一个数可以用十进制、二进制、八进制、十六进制等

各种形式来表示(见表 1-1),虽然表示的形式不同,但它们是等值的,我们需要熟悉它们之间的转换方法。 (1)R进制转换为十进制 方法:按权展开求和。基数为 R 的数字,只要将各位数字与它的权相乘,其积相加,和

数就是十进制数。 【例 1.1】分别将(1101101.101)2、(3506.24)8、(8FC7.2A)16转换为十进制数。

(1101101.101)2 = 1×26+1×25+0×24+1×23+1×22+0×21+1×20+1×2−1+0×2−2+1×2−3 = 64+32+8+4+1+0.5+0.125 = (109.625)10

(3506.24)8 = 3×83+5×82+0×81+6×80+2×8−1+4×8−2 = 1536+320+6+0.25+0.0625 = (1862.3125)10

(8FC7.2A)16 = 8×163+15×162+12×161+7×160+2×16−1+10×16−2

= 32768+3840+192+7+0.125+0.0390625 = (36807.1640625)10

表 1-1 各进制数对照表

十进制 二进制 八进制 十六进制

0 0000 000 0

1 0001 001 1

2 0010 002 2

3 0011 003 3

4 0100 004 4

5 0101 005 5

6 0110 006 6

7 0111 007 7

8 1000 010 8

9 1001 011 9

10 1010 012 A

11 1011 013 B

12 1100 014 C

13 1101 015 D

14 1110 016 E

15 1111 017 F

Page 16: 计算机与程序设计基础 - Baiduimages.china-pub.com/ebook55001-60000/57390/ch01.pdf第1 章 计算机与程序设计基础 3 程序原理的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制

16 计算机程序设计(C 语言版)

(2)将十进制数转换为 R(R=2,8,16)进制数 方法:整数部分采用除基数取余法;小数部分采用乘基数取整法。

【例 1.2】将(57)10分别转换为二进制、八进制、十六进制数。

因此,(57)10 = (111001)2 = (71)8 = (39)16 注意:最先得到的余数是整数的最低位。

【例 1.3】将(57.3125)10转换为二进制(分别用除 2 取余法和乘 2 取整法对整数部分和小数部分进行转换,然后拼接起来即可)。 由例 1.2已知(57)10 = (111001)2,下面对(0.3125)10进行转换。

因此,(57)10 = (111001.0101)2 (3)二进制与八进制或十六进制之间的转换

3位二进制数可以组合成 23=8种状态,刚好能表示八进制数 0~7;十六进制数可以组合成 24=16种状态,刚好能表示十六进制数 0~F。因此二进制数转换为八进制或十六进制数时,只要把二进制数按 3 位或 4 位分组,然后写出其对应的八或十六进制数即可。它们之间转换比较容易,每三位二进制数相当于一位八进制数,每四位二进制数相当于一位十六进制数。

在转换时,位组划分是以小数点为中心向左右两边延伸,中间的 0 不能省略,整数位和小数位不够时应作补 0处理。

【例 1.4】1)将二进制数 1011010.1转换为八进制数。

2 8001 011 010. 100 1011010.1 132.41 3 2 4

=

2)将二进制数 1011010.1转换为十六进制数。

2 80101 1010. 1000 1011010.1 5A.8

5 A 8=

3)将十六进制数 F7.28转换为二进制数。

16 2F 7 . 2 8

F7.28 11110111.001011111 0111 . 0010 1000

=

4)将八进制数 25.63转换为二进制数。

8 22 5 . 6 3

25.63 10101.110011010 101 . 110 011

=

3.计算机中数的表示 计算机中的数据可以分为数值数据和非数值数据两大类。数值数据通常用于表示数量的

2 57 余数

2 28 ⋯⋯ 1 低位

2 14 ⋯⋯ 0

2 7 ⋯⋯ 0

2 3 ⋯⋯ 1

2 1 ⋯⋯ 1

0 ⋯⋯ 1 高位

8 57 余数

8 7 ⋯⋯ 1 低位

0 ⋯⋯ 7 高位

16 57 余数

16 3 ⋯⋯ 9 低位

0 ⋯⋯ 3 高位

取整数部分

0.3125 × 2 = 0 .625 a-1 = 0 高位

0.625 × 2 = 1 .25 a-2 = 1

0.25 × 2 = 0 .5 a-3 = 0

0.5 × 2 = 1 .0 a-4 = 1 低位

Page 17: 计算机与程序设计基础 - Baiduimages.china-pub.com/ebook55001-60000/57390/ch01.pdf第1 章 计算机与程序设计基础 3 程序原理的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制

17 第 1 章 计算机与程序设计基础

多少,分为无符号数和有符号数。 在计算机中,每一个数据的长度(类型)是一定的,例如 8位、16位、32位、64位等。

如果所有的位都作为数据位来用,这就是无符号数。无符号数多用于表示字符、地址以及逻辑值等。

如果将最高位作为数据的符号位来用,就是有符号数。有符号数分为定点数和浮点数。 定点数:将小数点的位置隐含固定在数值的最低位之后,就是定点整数,也称纯整数;

将小数点的位置隐含固定在符号位之后,数值最高位之前,就是定点小数,也称纯小数。如图 1-19所示。

S

31 30 0

数值

纯整数 小数点

S

31 30 0

数值

纯小数 小数点 图 1-19 定点数格式

数有正负之分,在计算机中如何表示正负号呢?通常,对于 n 位二进制数,将其最高位作为符号位,用“0”表示正,“1”表示负。也就是说把符号数值化,这样的数称为“机器数”,而把机器数对应的原来有正负号的数称为“真值”。

例如:设 n=8,用一个字节存储一个整数。 A=1010101(真值) B=−1010101(真值)

0 1 0 1 0 1 0 1 (机器数) 1 1 0 1 0 1 0 1 (机器数)

数值信息在计算机内采用符号数字化处理后,计算机便可以识别和处理了。 机器数有三种表示形式——原码、反码和补码。 在计算机内部存储的带符号数通常都是以补码形式存储,用补码形式进行运算的。什么

是一个数的补码?为什么要用补码?这要从数的原码、反码开始讲。下面以整型数为例,且假定字长为 8位。 (1)原码 整数 X的原码是指:其符号位为 0表示正,为 1表示负;其数值部分就是 X的绝对值的

二进制数。X的原码通常用[X]原来表示。例如: [+100]原 = 01100100B [+1]原 = 00000001B [−100]原 = 11100100B [−1]原 = 10000001B 注意:在原码中,零有两种表示形式,即“0”的表示不具有唯一性。 例如: [+0]原 = 00000000B [−0]原 = 10000000B 原码表示法简单易懂,与真值(带符号数本身)转换方便,只要把符号还原即可。用原

码做乘除法比较简单,取符号位单独做加运算,便得到结果的符号,即同号为正,异号为负。但当用原码进行加减运算时,运算规则复杂。例如加法运算:若两数同号,则两数相加,结果取共同的符号;若两数异号,则必须比较两个数哪个绝对值大,才能决定谁减谁,结果采用大数的符号,所以原码不便于运算。 (2)反码

X 的反码是指,对于正数,反码与原码相同;对于负数,符号位不变,其数值位 X 的绝对值按位取反(1变 0,0变 1)。X的反码通常用[X]反来表示。例如:

[+100]反 = 01100100B [+1]反 = 00000001B [−100]反 = 10011011B [−1]反 = 11111110B

Page 18: 计算机与程序设计基础 - Baiduimages.china-pub.com/ebook55001-60000/57390/ch01.pdf第1 章 计算机与程序设计基础 3 程序原理的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制

18 计算机程序设计(C 语言版)

注意:在反码中,零也有两种表示形式,即“0”的表示不具有唯一性。 例如: [+0]反 = 00000000B [−0]反 = 11111111B 反码的运算也不方便,通常用来作为求补码的中间过渡。 (3)补码

为了更好理解补码,这里先介绍模数的概念。模数从物理意义上讲,是某种计量器的容量。例如,我们日常生活中的钟表,模数就是 12。钟表计时的方式是达到 12就从零开始(扔掉一个 12),这在数学上是一种“取模(或取余)运算(mod)”。“%”是 C 语言中求除法余数的算术运算符。例如:

14%12=2

如果现在的准确时间是 6 点整,而你的手表指向 8 点,怎样把表拨准呢?我们自然会想到可以有两种方法:把表往后拨 2小时,或把表往前拨 10小时,效果是一样的,即

8–2=6 (8+10)mod 12=6

在模数系统中,

8–2=8+10 (mod 12)

上式之所以成立,是因为 2 与 10 对模数 12 是互补的(2+10=12)。因此,我们可以认可这样一个结论:在模数系统中,一个数减去另一个数,或者说一个数加上一个负数,等于第一个数加上第二个数的补数:

8+(−2)=8+10 (mod 12)

我们称 10为−2在模 12下的“补码”。负数采用补码表示后,可以使减法统一为加法运算。 在计算机中,机器表示数据的字长是固定的。对于 n位数来说,模数的大小是:n位数全

为 1,且最末位再加 1。实际上模数的值已经超过了机器所能表示的数的范围,因此模数在机器中是表示不出来的。若运算结果大于模数,则模数自动丢掉,也就等于实现了取模运算。

如果有 n位整数(包括一位符号位),则它的模数为 2n;如果有 n位小数,小数点前一位为符号位,则它的模数为 2。

由以上讨论可知,对于一个二进制负数,可用其模数与其真值做加法(模减去该数的绝对值)求得其补码。例如:

X = −0110B [X]补 = 24 +(−0110)2= 1010B X = −0.1011B [X]补 = 2 +(−0.1011)2= 1.0101B

由于机器中不存在数的真值形式,用上述公式求补码在机器中不易实现,但从上式可推导出一个简便方法。

对于正数,补码与原码相同;对于一个负数,符号位不变,其数值位 X 的绝对值按位取反后在最低位加 1,即[X]补=[X]反+1。X的补码通常用[X]补来表示。例如:

[+100]补 = 01100100B [+1]补 = 00000001B [−100]补 = 10011100B [−1]补 = 11111111B

注意:在补码中,零有唯一的编码,[+0]补 = [−0]补 = 00000000。 补码运算简单方便,符号位可以作为数据的一位参与运算,不必单独处理,且最后结果

的符号位仍然有效;二进制的减法可用其补码的加法来实现,简化了硬件电路。 【例 1.5】计算−2+3=?应得+1,可将−2的补码和+3的补码相加,就可得结果+1的补码。

Page 19: 计算机与程序设计基础 - Baiduimages.china-pub.com/ebook55001-60000/57390/ch01.pdf第1 章 计算机与程序设计基础 3 程序原理的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制

19 第 1 章 计算机与程序设计基础

【例 1.6】计算 10−67=?应得−57。 应当指出,补码运算结果仍然是补码,若要求得真值必须求其原码。 根据补码求原码,只要对补码再求补码即可,所以有:[[X+Y]补]补 = [X+Y]原。 因为[结果]补 = 11000111B,所以[结果]原 = [[结果]补]补 = 10111001B = −57。 如果符号位为 0,则结果为正,补码即为原码。 以上我们了解到机器数的补码,可以使减法转换为其补码的加法运算,因此在微机中通

常均采用补码存储,补码运算。表 1-2是机器数的整数形式的编码对照表。 由于乘法可以用加法实现,除法可以用减法实现,使用补码,减法又可以转换为加法,

所以计算机中只要有加法器,就可以做加、减、乘、除运算了。现在,为了提高运算速度,计算机中增加了专门的乘法器和除法器。

表 1-2 原码、反码对照表

十进制数 二进制真值 [X]原 [X]反

+127 +1111111 01111111 01111111

+126 +1111110 01111110 01111110

⋯⋯ ⋯⋯ ⋯⋯ ⋯⋯

+2 +0000010 00000010 00000010

+1 +0000001 00000001 00000001

+0 +0000000 00000000 00000000

−0 −0000000 10000000 11111111

−1 −0000001 10000001 11111110

−2 −0000010 10000010 11111101

⋯⋯ ⋯⋯ ⋯⋯ ⋯⋯

−126 −1111110 11111110 10000001

−127 −1111111 11111111 10000000

−128 −10000000

4.计算机中实数的浮点表示 实型数也叫浮点数,例如 123.45、0.12345×103就是实型数。当计算机中需要处理实型数

据时,就出现了如何表示小数点的问题。系统并不是用一位二进制数表示小数点,而是采用浮点数形式,并隐含设定小数点位置。

任何一个实数 X都可以用浮点形式表示(即科学表示法),如果采用二进制则表示如下: E2X M ±= ± ×

其中,M称为数 X的尾数。M采用二进制纯小数形式(0.xxxxxx),它代表了 X的全部有效数字,其位数反映了数据的精度。

[−2]补 = 11111110B 11111110

[+3]补 = 00000011B + 00000011

自动丢失→ 1 00000001

符号位

[+10]补 = 00001010B 00001010

[−67]补 = 10111101B + 10111101

11000111

符号位

Page 20: 计算机与程序设计基础 - Baiduimages.china-pub.com/ebook55001-60000/57390/ch01.pdf第1 章 计算机与程序设计基础 3 程序原理的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制

20 计算机程序设计(C 语言版)

E称为数 X的阶码,表示 2的几次方。E通常采用二进制整数形式,它决定了数的范围。 M 和 E 都可以是正数或负数,即阶码和尾数都是带符号的数,可以采用不同的码制表示

法,例如尾数可用原码或补码表示,阶码用补码表示。 浮点数的具体格式随机器不同而有区别。一个浮点数的存储格式示例如图 1-20 所示

(32 位):

尾数小数点位置

31 30 24 23 22 0

尾 数阶符 阶 码 数符

… … … … … … … … … … …

图 1-20 浮点数的存储格式

例如,当阶码、尾数分别用补码和原码表示时,−0.11011×211、0.11011×2−11在机器内的表示形式分别为:

1 30 ⋯ ⋯ 24 23 22 ⋯ ⋯ ⋯ ⋯ ⋯ ⋯ ⋯ ⋯ ⋯ 0

30 0 0 0 0 0 1 1 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 表示 −0.11011×211

31 30 ⋯ ⋯ 24 23 22 ⋯ ⋯ ⋯ ⋯ ⋯ ⋯ ⋯ ⋯ ⋯ 0

1 1 1 1 1 1 0 1 0 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 表示 0.11011×2−11

注意:这里的±E 采用了二进制整数表示形式,在实际应用中,阶码和尾数常用补码表示,

以便于应用。 为了不损失有效数字,系统常对浮点数进行规格化处理,即保证尾数的最高位是 1,这可

以通过对阶码的调整实现。 目前,计算机的实型数多采用美国电气与电子工程师协会(IEEE)制定的 IEEE 754标准,

每个实型数分为三个字段:数符号位、阶码(指数)和尾数(如图 1-21所示)。4字节的实数称为单精度实数,8字节的实数称为双精度实数。 尾数表示方法:用原码表示,进行规格

化,使其值大于等于 1而小于 2,最高位为 1,是默认(隐藏)位。

指数表示方法:以移码形式存储。对于单精度实数,偏移量为 127(7FH);对于双精度实数,偏移量为 1023(3FFH)。存储浮点数阶码部分之前,偏移量要先加到阶码上。

例如参见表 1-3,单精度实数表示举例。

表 1-3 单精度实数表示举例

十进制 二进制 规格化 符号 移码阶 尾 数

+12 1100 1.1×23 0 10000010 1000000 00000000 00000000

−12 1100 −1.1×23 1 10000010 1000000 00000000 00000000

100 1100100 1.1001×26 0 10000101 1001000 00000000 00000000

−1.75 1.11 −1.11×20 1 01111111 1100000 00000000 00000000

说明:+12,二进制表示为 1100,规格化结果是 1.1×23。第一个 1 是默认位,不存储在

23 位尾数部分内。移码后的阶表示为 127+3=130(即 82H)。 此外,数 0.0存储全为 0;无限大数的阶码部分存储全为 1,尾数部分全为 0。 浮点数运算与整数运算相比就复杂多了。例如浮点数的加法运算,首先要保证参加运算

S 指数 尾数

单精度

31 30 … 23 22 … 0

S 指数 尾数

双精度

63 62 … 52 51 … 0

图 1-21 实型数格式

Page 21: 计算机与程序设计基础 - Baiduimages.china-pub.com/ebook55001-60000/57390/ch01.pdf第1 章 计算机与程序设计基础 3 程序原理的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制

21 第 1 章 计算机与程序设计基础

的数是规格化数,然后再“对阶”,即通过移动尾数使两个数的阶码相同,之后尾数才能相加,最后还要对运算结果再进行规格化处理。为了加快浮点数的运算,在计算机硬件结构中就专门设计了浮点数运算部件。

5.数的表示范围 机器中数的表示范围与数据位数及表示方法有关。一个 m位整数(包括一位符号位),如

果采用原码或反码表示法,能表示的最大数为 2m−1−1,最小数为− (2m−1−1);若用补码表示,能表示的最大数值为 2m−1−1,最小数为−2m−1。

由于补码中的“0”的表示是唯一的,故[X]补 = 100⋯0对应的真值 X = −2m−1,从而使补码的表示范围与原码有一点差异。即补码 100⋯0的形式是一个特殊情况,权为 2m−1位的 1既代表符号又代表数值。

例如,设 m=8,则原码表示范围为−127~+127,反码的表示范围也是−127~+127,补码的表示范围是−128 ~ +127。

一个 n 位定点小数,小数点左边一位表示数的符号,采用原码或反码表示时,表示范围为− (1−2−n) ~(1−2−n);采用补码表示时,表示范围为−1~(1−2−n)。

至于浮点数的表示范围,则由阶码位数和尾数位数决定。若阶码用 r 位整数(补码)表示,尾数用 n位定点小数(原码)表示,则浮点数范围是:

1 1(2 1) (2 1)(1 2 ) 2 1 (1 2 ) 2r rn n− −− − − −− − × − + − ×~

为了扩大数的表示范围,应该增加阶码的位数,每加一位,数的表示范围就扩大一倍。而要增加精度,就需要增加尾数的位数,在定长机器中,阶码位数和尾数位数的比例要适当。但为了同时满足对数的范围和精度的要求,往往采用双倍字长甚至更多个字长来表示一个浮点数。

6.计算机中非数值数据 在计算机中的非数值数据包括西文字符(字母、数字、各种符号)和汉字字符以及声音、

图像等信息。它们不表示数量的多少,但和数值型数据一样,也需要用二进制数进行编码才能存储在计算机中并进行处理。下面着重介绍中、西文的编码方案。 (1)西文字符编码(ASCII码)

ASCII(American Standard Code for Information Interchange)码是“美国信息交换标准代码”的简称,是由美国国家标准学会(American National Standard Institute,ANSI)制定的,是目前国际上最为流行的字符信息编码方案。

ASCII码有标准 ASCII码和扩展 ASCII码两种。标准 ASCII码也叫基础 ASCII码,使用7 位二进制数来表示,共包含 128 种字符。其中有 33 种控制码,十进制码值为 0~31 和 127(即 NUL~US 和 DEL)称为非图形字符(又称为控制字符),主要用于打印或显示时的格式控制、对外部设备的操作控制、进行信息分隔、在数据通信时进行传输控制等用途。其中控制字符的表示及其含义详见附录 B(ASCII码表)。

除了 33个控制码之外,其余 95个字符称为图形字符,为可打印字符或可显示字符,包括大小写字母共 52个,0~9的数字共 10个和其他标点符号、运算符等其他 33个符号。其中 0~9、A~Z、a~z 都是顺序排列的,且小写比大写字母码值大 32,码值 32 对应的是表中第一个可显示符——空格,数字 0的码值为 48,大写字母 A的码值为 65,小写字母 a的码值为 97。

一个字符的 ASCII 码通常占一个字节,用七位二进制数编码组成,所以 ASCII 码最多可表示 128个不同的符号。

大写字母 A与小写字母 a的机内表示分别是:

“A”:01000001 “a”:01100001

Page 22: 计算机与程序设计基础 - Baiduimages.china-pub.com/ebook55001-60000/57390/ch01.pdf第1 章 计算机与程序设计基础 3 程序原理的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制

22 计算机程序设计(C 语言版)

扩展 ASCII(Extended ASCII)码是将标准ASCII码由 7位扩充为 8 位,由 0 到 255(共256 个)编码组成。EASCII 码比 ASCII 码扩充出来的符号包括表格符号、计算符号、希腊字母和特殊的拉丁符号等。后 128 个编码称为扩展 ASCII码,目前许多基于x86的系统都支持扩展 ASCII 码。 (2)汉字编码 汉字是象形文字,每个汉字都有自己的形状,所以,每个汉字在计算机中也只能采用二

进制化信息编码。 汉字的数量大,常用的汉字就有几千个之多,显然用一个字节(八位编码)是不够的。

目前的汉字编码方案大都采用两个字节,例如“国家标准信息交换用汉字编码字符集”的基本集(GB 2312—80标准)中收入了 6763个汉字,其中一级汉字(最常用)3755个,二级汉字 3008个,另外还包括 682个西文字符、图符。

为了便于使用,GB 2312—80 的国家标准将其中的汉字和其他符号按照一定的规则排列成为一个大的表格,在这个表格中,每一行称为一个“区”,每一列称为一个“位”,整个表格共有 94 区,每区有 94 位,并将“区”和“位”用 4 位十进制数字进行编号:前 2 位为区号,从 01到 94;后 2位为位号,从 01到 94,这种表示方式也称为区位码。

十进制的区位码方便人的使用,但计算机内部使用的是二进制,另外,为了与 ASCII 码兼容,避开其前 32个控制字符,先将十进制区码和位码分别转换为 1个字节的二进制(十六进制表示)数,再将这个数的第一个字节和第二个字节分别加上 20H(32),就得到国标码也称交换码,国标码的每个字节实际上只用了 7位,最高位是 0。每个国标码或区位码都对应着一个唯一的汉字或符号。

例如,汉字“大”的区位码是 2083,写成 16进制就是 1453H,加上 2020H,汉字大的国标码是 3473H (0011010001110011)2,在计算机内形式如下:

0 0 1 1 0 1 0 0 0 1 1 1 0 0 1 1

第一字节 第二字节

在计算机内部,汉字编码和西文编码是共存的,都是文字信息,它们同属一类。系统很难辨别连续的 2个字节代表的是 2个 ASCII字符还是 1个汉字。为了与 ASCII码相区别,采用的方法之一是对二字节的国标码,将两个字节的最高位都置成“1”,而 ASCII 码所用字节最高位保持“0”,然后由软件根据字节最高位来作出判断。这种变形的国标码是一种汉字在计算机内部存储、处理的代码,故又称机内码。因此,“大”的机内码是:(1011010011110011)2= (B4F3)16。

机内码所具有的主要作用是用于统一不同系统所使用的不同汉字输入码,各种五花八门的汉字输入法进入系统后,一律转换为机内码,使不同系统的汉字信息可以相互转换。 汉字输入方法很多,如区位、拼音、五笔字型等。不同输入法有自己的编码方案,不同

输入法采用的汉字编码统称为输入码。输入码进入机器后必须转换为机内码。

显示或者打印汉字时还要用到汉字字形编码,汉字字形码是一种用点阵表示汉字字形的编码。它把汉字按字形排列成点阵,常用的点阵有 16×16、24×24、32×32或更高。一个16×16 点阵的汉字要占用 32 个字节,一个 24×24 点阵的汉字要占用 72个字节⋯⋯。可见汉字字形点阵的信息量很大,占用的存储空间也非常大。汉字字库中存储了每个汉字的点阵代码,当输出时检索字库,输出字形点阵得到字形,如图 1-22所示。计算机处理汉字过程如图 1-23所示。

图 1-22 字形点阵

Page 23: 计算机与程序设计基础 - Baiduimages.china-pub.com/ebook55001-60000/57390/ch01.pdf第1 章 计算机与程序设计基础 3 程序原理的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制

23 第 1 章 计算机与程序设计基础

输入汉字 输入码

汉字机内码

汉字字形码

国标码 汉字库

输出

图 1-23 汉字处理过程

(3)Unicode码 由于 ASCII码只有二进制的 8位,所以最多只能表示 256个字符。Unicode码(统一码、

万国码、单一码)是国际组织于 20 世纪 90 年代初制定的可以容纳世界上所有文字和符号的字符编码方案,已经成为信息编码的一个国际标准。它是以两个字节表示一个字符,允许世界上几乎所有书面语言都能用单一的编码表示,其中也包括中文。相比而言,8 位的 ASCII码就只能表示英文字母和部分符号。在 Unicode 码的 65536 个可能的编码中,有 39000 个已经做了规定,其中 21000个编码用于表示中国汉字。Unicode码编码中尚未定义的编码留待以后使用。

Microsoft Office 就是基于 Unicode 文字编码标准。这样,无论文档以何种语言撰写,只要操作系统支持该语言的特殊字符,Office程序都能正确识别和显示文档信息。

在接收来自其他计算机的电子邮件时,有时会出现“乱码”现象(文字无法识别),这也是由于外来邮件所采用的编码与用户观察邮件时使用的默认编码不一致所造成的。此时只要在邮件软件的菜单中选择合适的编码,邮件文字就会正确地显示出来。 (4)多媒体信息编码 媒体(medium)有两种含义:一是指存储信息的实体,如磁盘、光盘、磁带、半导体存

储器等;二是指传递信息的载体,如文本、图形、图像、动画、视频、声音等。计算机中的“媒体”通常指的是后者。

将多种媒体结合在一起,形成一个有机的整体,能实现一定的功能,就称之为多媒体

(Multimedia)。 多媒体技术就是利用计算机技术把多种媒体综合一体化,使之建立逻辑联系,并能进行

加工处理的技术。多媒体信息经过数字化处理后,以某种二进制编码形式存储在计算机中。例如,一个图形可以用图形原语(如圆、矩形、直线)和它们的属性(如圆心坐标、半径、颜色等编码)来描述;而一个图像(静态)可以用一个像素点的矩阵来描述,其中每一个像素点都用定长的二进制数表示颜色。多媒体信息的编码方法与媒体本身的特性有关,也比较复杂。

1.5 计算机程序与算法

1.5.1 算法的概念

计算机的使用改变了人类的生活方式及工作方式,并将人类的创造性思维推向一个更高的阶段。思维活动可以利用语言来形式化,而语言层次可以离开意识层次相对独立地活动。计算机语言作为人和计算机之间进行意识交流的工具,人通过计算机语言将意识活动交给计算机进行独立的加工,产生进一步的思维活动,所以可以认为计算机是人类思维的工具。计算机思维是一种物化的思维,是人脑思维的进一步延伸。

在计算机语言层次,人与计算机的意识活动的交流是通过程序这个环节来完成的。1976年著名的计算机科学家 N.Wirth出版了一本题名为《Algorithms + Data = Programs》的著作,提出了程序是算法和数据结构的结合的观点,也就是说程序设计主要包括两方面的内容:行

Page 24: 计算机与程序设计基础 - Baiduimages.china-pub.com/ebook55001-60000/57390/ch01.pdf第1 章 计算机与程序设计基础 3 程序原理的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制

24 计算机程序设计(C 语言版)

为特性的设计和结构特性的设计。行为特性的设计是指完整地描述问题求解的全过程,并精确定义每个解题步骤,这一过程即是算法的设计;而结构特性的设计是指在问题求解的过程中,计算机所处理的数据之间的联系,及这些联系的表示方法。

因此,为了有效地进行程序设计,应当至少具有两个方面的知识,即,掌握一门高级语言的语法规则,掌握解题的方法和步骤。计算机语言只是一种工具。光学习语言的规则还不够,最重要的学会针对各种类型的问题,拟订出有效的解题方法和步骤——算法。有了正确的算法,可以利用任何一种计算机高级语言编写程序,使计算机进行工作。

如前所述,程序就是为完成预定任务用某种计算机语言编写的一组指令序列。计算机按照程序规定的流程依次执行指令,最终完成程序所描述的任务。通常,一个计算机程序主要描述两部分内容:一是描述问题的每个对象及它们之间的关系;二是描述对这些对象做处理的处理规则。其中关于对象及它们之间的关系是数据结构的内容,而处理规则则是求解的算法。针对问题所涉及的对象和要完成的处理,设计合理的数据结构常可以有效地简化算法,数据结构和算法是程序最主要的两个方面。

单从程序设计角度来看,可将编程理解为以下公式:

编程=算法+数据结构+程序设计语言

即首先根据程序需要得到的数据、能输入的数据来设计数据结构,再设计相应的算法来实现程序要达到的功能,最后才是使用某一门程序设计语言来进行编码。其中数据结构和算法是独立于程序设计语言的,程序设计语言只是完成最后的编码工具。

数据结构是算法实现的基础,算法总是要依赖于某种数据结构来实现。 1.数据结构 计算机的处理对象是描述客观事物的数据,由于客观事物的多样性,会有不同形式的数

据,如整数、实数、复数和字符、以及所有计算机能够接收和处理的各种各样符号集合。在计算机中,形式不同的数据采用数据类型来标识。变量的数据类型说明变量可能取的值的集合,以及可能施加于变量的操作的集合。例如,程序对表示班级人数的变量,它们只能是大于或等于零的整数,对它们能施行加减操作,不能施行乘除操作,但这些变量能与整数一起施行乘除操作等。所以数据类型不仅定义了一组形式相同的数据集,也定义了对这组数据可施行的一组操作集。

数据结构(Data Structure)是指数据对象及其相互关系和构造方法,程序中的数据结构描述了程序中的数据间的组织形式和结构关系。

2.算法 算法(Algorithm)就是问题的求解方法,一个算法由一系列求解步骤组成,算法的描述

由经明确说明的一组简单指令和规则组成,计算机按照规则执行其中的指令能在有限的步骤内解决一个问题或者完成一个函数的计算。正确的算法要求组成算法的规则和步骤的意义应是唯一确定的,是没有二义性的;由这些规则指定的操作是有序的,必须按算法指定的操作顺序执行,并能在执行有限步骤后给出问题的结果。

数据结构与算法有着密切的关系,只有明确了问题的算法,才能较好地设计数据结构;要选择好的算法,又常常依赖于合理的数据结构。数据结构是构造算法的基础,算法总是要依赖于某种数据结构来实现。

说到学习编程序设计,人们更多地是想到学习这些程序设计语言。其实,程序设计语言只是一个很初级的工具。熟练地掌握这些语言中的一门,就好像学会了写字。在现实生活中,会写字的人不见得能写出好文章,同样道理,学会了一门(或多门)程序设计语言的使用并不一定就能编写出好程序来。

Page 25: 计算机与程序设计基础 - Baiduimages.china-pub.com/ebook55001-60000/57390/ch01.pdf第1 章 计算机与程序设计基础 3 程序原理的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制

25 第 1 章 计算机与程序设计基础

程序设计真正核心的部分是算法的设计。通过对算法的学习,可提高读者的逻辑思维能力,训练有条理地思考与表达能力,最终提高利用计算机解决问题的能力。

解决任何实际问题,都不可避免地涉及算法问题,都需要通过一定的算法,得到一个最优或较优的方案。具体到计算机程序设计,算法的设计就显得更重要了。在这里,我们将重点讨论算法这个组成程序的基石。

粗略地说,算法是解决问题的具体步骤。解决任何一个问题都有一定的步骤,例如你要看电影,就要先买票,然后按时到电影院,进场,找座位,坐下,看电影,退场,等等。又如你要考大学,首先要填报名单,交报名费,拿到准考证,按时参加考试,得到录取通知书,到指定学校报到注册等。这些都是按一系列的规则顺序执行的步骤,缺一不可,顺序错了也不行。当然这些例子是一些人们习以为常的原始算法,算法的描述采用了自然语言的方法。

一个非常著名的古老算法是用于求两个整数的最大公约数的欧几里得算法。这个算法最早出现在大约公元前 350 年至公元前 300 年由欧几里得写成的《Elements》(几何原本)一书中。算法的发明人是欧几里得,因此,人们将该算法称之为欧几里得算法,也称辗转相除法。书中阐述了求两个数的最大公因子的过程:

给定两个正整数 m和 n,求它们的最大公因子,即同时能够整除 m和 n的最大正整数。 步骤 1.以 n除 m,并令 r为所得余数(显然 n>r≥0); 步骤 2.若 r=0,算法结束,n即为 m和 n的最大公因子; 步骤 3.置 m←n,n←r,返回步骤 1。 在描述欧几里得算法的时候,我们采用了一种比自然语言更抽象一些的方法,或者称半

自然语言的方法。同时欧几里得算法的描述与看电影和报考大学的算法相比,具有完全的确定性。在欧几里得算法的描述中引入了一些变量,如 m、n、r,引入了关系运算符=,≥,还引入了记号←表示将该符号右边的变量的值送到左边的变量中去,所以←也称为赋值号。

在算法的描述乃至程序的设计中,变量是个很重要的概念。所谓变量(va)是指一块在计算机内存中分配的存储空间,或者说,每个变量占用了内存中一个确定的存储区。赋值是指将赋值号右边的变量中存储的值送到左边的变量所代表的存储单元中去。

还需要注意的是,在算法中不仅各步骤间的顺序是重要的,在每步内的动作次序同样也是重要的。例如在欧几里得算法的步骤 3中。“置 m←n,n←r”绝不能写成“置 n←r,m←n”,因为原始步骤的结果是在 m、n 和 r中最后都存储了一个值 r,即都变成了步骤 1除法运算的余数。

由于算法是对实际运算的抽象表述,同时算法描述的往往是比看电影复杂得多的运算,所以一个算法每一步的含义(或者说是作用)往往不是一目了然的。学习一个算法的最好方法莫过于将该算法所允许的实例代入到算法中,按算法的步骤去执行算法,这种由人来执行算法的方法称为“人工模拟”,人工模拟也是开发和检验算法的一种重要步骤,通过人工模拟能了解算法每一步的实际含义。算法中一般都包含了“如果⋯则”的步骤,规定对不同的实例以不同的途径处理,所以为深刻弄懂一个算法,一般还需要设计多个实例来反复体会算法中各种不同处理途径的作用。对欧几里得算法,第一个实例是:

m=12和 n=4, 步骤 1.m/n=12/4=3,得到 r=0; 步骤 2.由于余数 r=0,算法结束,4即为 12和 4的最大公因子。 由于这个实例没有“走”到步骤 3,所以由这一个实例不能全面了解欧几里得算法,第二

个实例是: m=48和 n=14, 步骤 1.m/n=48/14=3,得到 r=6;

Page 26: 计算机与程序设计基础 - Baiduimages.china-pub.com/ebook55001-60000/57390/ch01.pdf第1 章 计算机与程序设计基础 3 程序原理的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制

26 计算机程序设计(C 语言版)

步骤 2.余数 r不为零,进入下一步; 步骤 3.置 m←n,n←r,即 m=14、n=6,返回步骤 1。 步骤 1.m/n=14/6=2,得到 r=2; 步骤 2.余数 r不为零,进入下一步; 步骤 3.置 m←n,n←r,即 m=6、n=2,返回步骤 1。 步骤 1.m/n=6/2=3,得到 r=0, 步骤 2.由于余数 r=0,算法结束,n的现值 2为 48和 14的最大公因子。 对欧几里得算法的跟踪应当可以告一段落了,但再深入地想一想,欧几里得算法的上述

表述是否尚有可改进之处呢?下一个实例是: m=14和 n=48, 步骤 1.m/n=14/48=0,得到 r=14; 步骤 2.由于余数 r=14,进入步骤 3; 步骤 3.置 m←n,n←r,即 m=48、n=14,返回步骤 1。 我们可以发现,当 m小于 n时,经过步骤 1、步骤 2和步骤 3后,仅将 m和 n互换了一

次。所以,可以为欧几里得算法增加算法步骤 0: 步骤 0.如果 m<n,则 m←→n(即交换)。 这样尽管欧几里得算法由三步变为四步,但对 m<n的实例,实际减少了算法执行的时间。

而按 m和 n之间大小关系的出现概率考虑,m<n及 m>n出现的概率可能各为一半。 欧几里得算法的结果是正整数 m和 n的最大公约数。 至此可以给算法一个更精确的定义:一个算法是一个有穷规则的集合,其中的规则规定

了解决一个问题的运算序列。 作为一个算法必须具备以下五个特性: 1)有穷性:一个算法必须总是在执行有限的步骤之后结束,且每一步都可在有限时间内

完成。 欧几里得算法满足这个条件。因为在步骤 1以后,r的值肯定小于 n ,所以如果 r不等于

零,则在经过步骤 3将 r的赋给 n以后,重新进行步骤 1时 n的值已经减小,所以循环过程中r 的值是一个递减序列,而正整数的递减序列必然最后要终止。所以对任何给定的 m 和 n 的值,步骤 1 只会执行有穷次。对足够大的 m 和 n,可能算法执行的次数相当多,但即使达到天文数字,仍然是有穷的。

如果一个计算不具有有穷性但具有算法其他特性,则可称其为计算方法。例如对无穷调和级数的和的计算就不是一个算法而是一个计算方法,在确定了项数或确定了对精度的要求以后,才能满足有穷性的要求,也就是说,这时对无穷调和级数的和的计算才可能成为一个算法。

2)确定性:算法的每一个步骤都必须有确定的定义。 欧几里得算法的每一个步都是确定的。例如,在步骤 1 中,除法的算术运算法则保证了

两个正整数相除的步骤,而结果的商和余数都是确定的。 3)可行性:一个算法是能行的,即算法中描述的操作都是可以通过已经实现的基本运算

执行有限次来实现的。 欧几里得算法涉及的运算包括整数的表示、整数的除法、整数是否为零的判断及整数的

赋值,这些运算都是基本的、能行的。 4)输入:一个算法有零个或多个的输入,算法的输入是算法执行的初始数据,这些输入

取自于特定的对象的集合。 欧几里得算法需要两个整数 m和 n作为初始数据。

Page 27: 计算机与程序设计基础 - Baiduimages.china-pub.com/ebook55001-60000/57390/ch01.pdf第1 章 计算机与程序设计基础 3 程序原理的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制

27 第 1 章 计算机与程序设计基础

5)输出:一个算法有一个或多个的输出,作为算法执行的结果。这些输出是同输入有某个特定关系的量。

要设计一个好的算法通常要考虑以下要求: 1)正确。算法的执行结果应当满足预先规定的功能和性能要求。 2)可读。一个算法应当思路清晰、层次分明、简单明了、易读易懂。算法主要是为了人

们的阅读、理解和交流,其次才是机器的执行。 3)健壮。当输入数据不合法时,应能适当地作出反应或进行处理,而不会产生莫名其妙

的输出结果或造成执行中断。 4)高效和低存储量。效率指的是算法执行的时间,存储量需求是指算法执行过程中所需

的最大存储空间。同一问题如果有多种算法可以解决,执行时间短的算法效率为高,而效率和低存储量需求度与问题的规模有关。

1.5.2 算法的基本结构和表示

对算法和程序设计方法的理论研究及程序设计实践指出,算法的基本组成结构只需要有三种,第一种是顺序结构,第二种是选择结构,第三种是循环结构。或者说,任何一个算法,无论其多么简单或多么复杂,都可由三种结构组合和构造而成。

前面在讨论欧几里得算法时,已经有了变量的概念和赋值运算的概念,并介绍了算法的一种类似于自然语言的表示方法。算法的作用是在于记录及交流人的解决问题的思想,同时算法也是作为编制计算机程序的前导步骤。为使算法的描述更简捷和清晰,人们研究和创造了多种表示算法的方法。常用的描述方法有:自然语言、伪代码、流程图、N−S流程图、PAD图等。

1.自然语言表示算法 自然语言就是就是人们日常使用的语言,可以是汉语、英语或其他语言。用自然语言描

述算法通俗易懂,但也存在如下缺点: 1)往往要用一段较冗长的文字才能表达清楚要进行的操作; 2)容易出现“歧义性”,往往要根据上下文才能正确判断出它的含义,不太严谨; 3)如果描述的是顺序执行的算法,还比较容易理解,当算法中包含了判断、转移和循环

等操作步骤时,用自然语言描述就不是很直观和易于理解。 如前面所述的欧几里得算法就是采用自然语言描述的。 2.伪代码表示算法 所谓伪代码,实际上是一种主要让人看的程序。它结合了自然语言表示和程序设计语言

的优点,丢弃程序设计语言中的烦琐细节,保留程序设计语言中的关键的流程结构,再适当辅之以自然语言描述。

由于伪代码借鉴了程序设计语言中的主要控制结构,同时又允许使用自然语言,因此是一种非常好的算法描述方式,而且也很容易转换成具体的程序。本书后面主要使用伪代码描述算法。

在伪码表示法中,每一个步骤称为一条语句。根据需要可将多条语句包容在 BEGIN 和END或一对花括号“{⋯⋯}”之间组成语句块(简称块,也称复合语句),即组织成以下形式:

BEGIN 或 {

语句 1 语句 1

语句 2 语句 2 … … 语句 n 语句 n END }

Page 28: 计算机与程序设计基础 - Baiduimages.china-pub.com/ebook55001-60000/57390/ch01.pdf第1 章 计算机与程序设计基础 3 程序原理的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制

28 计算机程序设计(C 语言版)

【例 1.7】输入一个年号,判断该年份是否是闰年。 根据有关的研究结果,判断闰年的条件可以表示为:(1)能被 4 整除,但不能被 100 整

除的年份是闰年;(2)能同时被 100和被 400整除的年份是闰年。用伪代码描述的算法如下。 第一种描述形式: BEGIN 输入(year)

If(year 能被 4 整除 and year 不能被 100 整除)or

(year 能被 100 整除 and year 能被 400 整除)

输出("是闰年") Else 输出("不是闰年") END

也可以用以下方式描述: BEGIN 输入(year) If(year mod 4==0)and(year mod 100≠0)or (year mod 100==0)and(year mod 400==0) 输出("是闰年") Else 输出("不是闰年") END

上面给出了同一算法的两种伪代码的描述,第一种描述更接近自然语言描述,而后一种更接近程序设计语言描述。可以看出,伪代码描述算法非常灵活,自然语言的使用可多可少,以其他人能够读懂并且易于转换为具体程序为原则。事实上对于稍有程序设计经验的人来说,上面两个算法都很容易转换成具体的程序。

3.传统流程图 传统流程图是用一些几何图形框、线条和文字来描述各种操作,是使用最早的算法和程

序描述的工具。流程图是一种图语言,用流程图可以直观地了解算法的结构,我国国家标准局制定了一些常用的流程图符号,如图 1-24所示。

起止框 输入输出框 处理框 判断框 流程线 图 1-24 常用传统流程图符号

下面分别结合算法的示例讨论顺序结构、选择结构和循环结构的含义,及相应伪代码和传统流程图的表示方法。 (1)顺序结构 顺序结构是指按照各语句或块在算法中排列的先后次序依次执行的结构。

【例 1.8】求两个数的绝对值之和。 用伪代码描述的算法: BEGIN num1 ← 第一个输入的数

num2 ← 第二个输入的数

num1 ← num1 的绝对值

num2 ← num2 的绝对值

Page 29: 计算机与程序设计基础 - Baiduimages.china-pub.com/ebook55001-60000/57390/ch01.pdf第1 章 计算机与程序设计基础 3 程序原理的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制

29 第 1 章 计算机与程序设计基础

sum ← num1+num2 输出 sum 的值 END

图 1-25所示为例 1.8的传统流程图表示。 (2)选择结构 选择结构根据某种条件选择性地执行算法的某一部分。选

择结构最常见的是判断算法中所说明的条件是否成立,如果条件成立执行某个语句或语句块,否则执行另一个语句或语句块,后一个语句或语句块在某些情况下可以省略。图 1-26所示为选择结构的流程图。可用伪码表示为:

IF〈条件〉

〈语句或语句块 1〉 [ ELSE 〈语句或语句块 2〉]

无论是执行了〈语句或语句块 1〉,还是执行了〈语句或语句块 2〉都完成了选择结构的执行。例 1.8 的表示还说明,如果我们在条件不成立时不要求做任何动作,可以省略 ELSE的那一部分。

【例 1.9】输入三个数,求其中最大的数。 用伪代码描述的算法: BEGIN num1 ← 第一个输入的数

num2 ← 第二个输入的数

num3 ← 第三个输入的数 IF(num1<num2) IF(num2<num3) max ← num3 ELSE max ← num2 ELSE IF(num1<num3) max ← num3 ELSE max ← num1 输出 max 的值 END

传统流程图表示的算法如图 1-27所示。 (3)循环结构 循环结构根据某种条件重复性地执行算法所规定的某一部分(称循环体)。循环体执行完

成后,再次判断循环的前提条件是否成立,如果条件成立再次执行循环体,如此循环重复直至条件不成立为止,从而达到重复性地执行算法所规定的某一部分的目的。

【例 1.10】设计一个算法,统计输入的一组数据中非负整数的个数。 用伪代码描述的算法: BEGIN 1 number ← 输入数据的个数

2 count ← 0 //累加器清零 3 WHILE(number≠0)

开始

输入第一个数送 num1

输入第二个数送 num2

求 num1 绝对值送 num1 中

求 num2 绝对值送 num2 中

求 num1 与 num2 之和送 sum

结束

输出 sum 中的值

图 1-25 传统流程图表示

不成立

条件

成立

语句或语句块 1 语句或语句块 2

图 1-26 选择结构的流程图

Page 30: 计算机与程序设计基础 - Baiduimages.china-pub.com/ebook55001-60000/57390/ch01.pdf第1 章 计算机与程序设计基础 3 程序原理的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制

30 计算机程序设计(C 语言版)

BEGIN 4 num ← 输入的下一个数 5 IF(num 0) 6 count ← count+1 7 number ← number-1 END 8 输出 count 的值 END

N

YY

Y N N

开始

输入第一个数送 num1 输入第二个数送 num2 输入第三个数送 num3

num1<num2

num2<num3 num1<num3

结束

输出 max 中的数

max=num1max=num3 max=num2 max=num3

图 1-27 传统流程图表示

例 1.10 的算法和例 1.9 的算法不同,例 1.9 的算法中预先确定了输入数据的个数,而例1.10 的算法并没有限定输入数据的个数,也就是说该算法能够灵活地处理不同个数的输入数据。所以定义了一个变量 number,该变量作为算法所要求的第一个输入量,代表算法当前这次所处理的输入数据的个数,从第二输入量开始才是算法所处理的输入数据。在算法执行中,每处理一个输入数据,将 number的值减 1,一直到所有的输入数据处理完成为止。

例 1.10 的算法用“//”的方法引入了对算法某个步骤的注释。为提高算法或程序的可读性,在其适当的地方加以注释是十分必要的,应有意识地逐步培养这种良好的习惯。

与前面几个算法相比,例 1.10 的算法显然要复杂一些。为了学习和验证这个算法,我们可以用人工模拟的方法,将该算法所允许的实例代入到算法中去,按算法的步骤人工执行一次,即跟踪算法的动态执行过程。同时可以对算法作进一步的改进完善。

为了方便跟踪算法的动态执行过程,可将算法中的可执行语句及包括判断的语句按顺序编号。同时为记录算法当前执行的以及下一步将执行的语句,并记录算法中的变量的值的变化过程,可以设计一张算法跟踪表。跟踪表的第一列是执行的步数,第二列和第三列分别是这一步所执行和下一步将执行的语句的编号,第四列是当前这一步的注记,以后的各列是算法中所用的各个变量。算法每执行一步,跟踪表的记录就增加一行,直至过程结束。 (4)N-S流程图 N-S 流程图简称 N-S 图。这是一种不使用流程线的结构化流程图,1973 年由 I.Nassi 和

B.Shneiderman 提出,N、S 分别是他们二人名字的头一个字母。这种流程图能清楚地显示出程序的结构。但当嵌套层数太多时,内层的方框越画越小,从而影响图形的清晰度。N-S 图将全部算法写在一个矩形框内。它只能由顺序结构、选择结构、循环结构三种基本结构单元组成,这三种基本结构构成的算法整体上是一个大的顺序结构。结构化流程图的画法介绍如下:

Page 31: 计算机与程序设计基础 - Baiduimages.china-pub.com/ebook55001-60000/57390/ch01.pdf第1 章 计算机与程序设计基础 3 程序原理的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制

31 第 1 章 计算机与程序设计基础

1)顺序结构的画法如图 1-28所示。其中 A框与 B框分别代表一个基本操作,如加、减、乘、除运算,打印、赋值等。两个或多个矩形组成一个顺序结构。

2)选择结构的画法如图 1-29 所示。它表示当条件 P成立时,执行 A 操作;当条件 P不成立时,执行 B操作。

3)循环结构包括当型循环结构和直到型循环结构。

当型循环结构的画法如图 1-30a所示。它表示当条件 P1满足时,执行操作 A,执行完 A后,再回去判断条件 P1 是否成立,若成立就再执行操作 A,如此反复,直至条件 P1 不满足为止。当型循环的特点是“先判断后操作”。

A

B

成立 不成立

P

A B

A

当 P1

A

直到 P2

a)当型循环 b)直到型循环

图 1-28 顺序结构 图 1-29 选择结构 图 1-30 N-S循环结构

直到型循环结构的画法如图 1-30b所示。它表示先执行操作 A,然后判断条件 P2是否满足,若不满足,则去执行操作 A,如此继续,直到条件 P2满足为止。直到型循环的特点是“先操作后判断”。

由于 N-S 图废除了流程线,因此比传统流程图更紧凑、易画,整个算法结构是由各个基本结构按顺序组成的,其上下顺序就是执行顺序,使写算法和看算法只需从上到下进行,十分方便。但由于 N-S 图仅适用三种基本结构设计程序,因此使某些程序设计的实现变得烦琐和困难。

【例 1.11】求两整数的最大公约数和最小公倍数。 求最大公约数采用常用的算法是辗转相除法。 求最小公倍数算法为:最小公倍数=原来的两数乘积/最大公约数。 采用当型循环的算法描述如图 1-31a所示,采用直到型循环的算法描述如图 1-31b所示。

a)流程图 1 b)流程图 2

图 1-31 N-S图示例

1.5.3 算法设计原则

算法设计是程序设计的基础,算法设计也应遵循程序设计的基本思想和原则。其中结构化程序设计思想具有重要的影响,结构化程序设计的一个重要规则是“自顶向下,逐步求精”。

输入 a,b

a→m,b→n

a<b T F

a,b交换

a%b→c(a除以 b的余数)

当 c≠0

b→a

c→b

a%b→c

输出最大公约数 b

输出最小公倍数 m×n/b

输入 a,b

a→m,b→n

a<b T F

a,b交换

a%b→c(a除以 b的余数)

b→a

c→b

直到 c=0

输出最大公约数 b

输出最小公倍数 m×n/b

Page 32: 计算机与程序设计基础 - Baiduimages.china-pub.com/ebook55001-60000/57390/ch01.pdf第1 章 计算机与程序设计基础 3 程序原理的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制

32 计算机程序设计(C 语言版)

计算机程序不但可以解决简单的问题,而且还能够解决复杂的大问题。然而人类大脑的思维是有限的,在同一时刻,人不可能记忆、思考太多的问题。面对复杂的问题,我们不可能同时把所有的细节都想清楚,只能首先把大的框架搞清楚,然后再分析解决细节问题。通常的方法是先将一个大问题分解为若干小问题,对比较复杂的子问题再继续分解为更加简单的二级子问题,直到每个子问题都有显而易见的解决方法,再实现逐一编写解决各个子问题的程序。这种先研究总体,再研究每一个局部的方法就是自顶向下的方法。

在算法和程序设计中,我们一般遵循下面的步骤进行: 1)明确算法的输入、输出数据。在设计算法和程序之前,首先应该弄清楚输入、输出数

据是什么?这一步实际上可以更好地帮助我们理解题意。 2)自顶向下,逐步求精。首先从全局出发进行整体设计,对整体布局中的较大的任务先

逐层细化为更小的任务,通过逐层分解、逐步求精、逐个解决,直到可以由计算机具体实现为止。

3)模块化设计。自顶向下逐步求精的过程中,复杂的问题分解为一个个简单问题的最基本方法就是模块化。按照功能或层次把一个问题划分为几个模块,然后对每个模块进一步细化。一方面将问题划分为由若干模块组成的层次结构;另一方面将每个模块的功能细化到可以采用三种基本结构描述为止,即一个模块解决一个特定的小问题,实现一个特定的功能,不同的模块完成的功能不同,模块之间的数据联系要简单,每个模块只有一个入口和一个出口;划分后的每个模块可以独立地编辑、调试。除最上层的模块外,每下一层次的功能模块均可以接受上层功能模块调用。

1.5.4 算法的基本分类

算法是解决问题的方法,不同的领域有各自的算法。如果根据问题的领域来区分,算法可分为数值问题的算法和非数值问题的算法。

数值问题算法是指解决传统数学问题的算法,例如解方程的算法、解方程组的算法,以及积分算法和微分算法等,随着计算机在数值计算方面的应用和研究的发展,求各种数值问题的近似解的算法也获得迅速的发展和应用。数值问题的算法是数学研究的一个重要方面,本书将在相应章节给出几个数值问题算法的例子(只限于计算机算法,即计算机能执行的算法)。由于数值运算有现成的模型,可以运用数值分析方法,因此对数值问题的算法的研究比较深入,算法比较成熟。各种数值运算都有比较成熟的算法可供选用。常常把这些算法汇编成册,或者写成程序形式存放在计算机系统内供用户调用。例如,有些计算机系统提供“数学程序库”,使用起来十分方便。

与数值问题的算法相比,计算机科学往往对非数值问题的算法给予了更多的重视,计算机非数值问题领域同样也是个相当宽广的领域,在各个不同的方向上都有不同的非数值问题的算法,例如,在图论中有涉及图的各种处理的图算法,在规划问题中有各种规划的算法。最常见的是用于事务管理领域,例如图书检索、人事管理、行车调度管理等。非数值运算种类繁多、要求各异、难以规范化,所以算法的研究基本上是依赖于具体的研究领域的。因此一般只对一些典型的非数值运算算法(例如排序、查找等算法)作比较深入的研究。其他的非数值运算问题,往往需要使用者参考已有的类似算法重新设计专门算法。

尽管不同的领域有各自的算法,但从算法所采用的方法或思路上看,最基本的大致可以分成以下几种:直接法、枚举法、递推法、递归法、分治法、贪婪法、回溯法、模拟法等。下面先介绍直接法、枚举法、递推法、递归法的基本思想,其他一些方法将随着课程的深入逐步展开。

Page 33: 计算机与程序设计基础 - Baiduimages.china-pub.com/ebook55001-60000/57390/ch01.pdf第1 章 计算机与程序设计基础 3 程序原理的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制

33 第 1 章 计算机与程序设计基础

1.直接法 直接法是指根据问题所给的条件,直接通过计算来得到解答。本章的例 1.8 就是直接算法

的一个例子,通过计算直接得到两个数的绝对值之和。 2.枚举法 枚举法又称穷举法,是最简单、最常见的一种程序设计方法,它充分利用了计算机处理

的高速特性,把每一个可能一一列举出来进行验证,符合条件的则表示该解是正确的,列举全部结束时就能得到所有解,即通过逐一考察问题的所有可能解,来找出问题的真正的解。使用枚举法的关键是要确定正确的穷举范围,既不能过分扩大穷举的范围,也不能过分缩小穷举的范围,否则程序的运行效率会降低,或遗漏正确的结果而产生错误。 (1)算法思路 枚举法的本质就是从所有候选答案中搜索正确的解。使用该算法需要满足两个条件。 1)可预先确定候选答案的数量; 2)候选答案的范围在求解之前必须有一个确定的集合。 当有了确定数量的候选答案和每个答案的确定集合,就可以使用循环语句和条件判断语

句逐步验证候选答案的正确性,从而得到需要的正确答案。一般的代码格式如下:

for(i=x1; i<=x2; i++) //循环控制变量 i 的取值范围:x1 i x2

for(j=y1; j<=y2; j++) //循环控制变量 j 的取值范围:y1 j y2

for(k=z1; k<=z2; k+) //循环控制变量 k 的取值范围:z1 k z2

if(i, j, k 满足验证条件)

printf(输出正确答案)

在上述的代码中,对 i,j,k 3个变量在设置集合内可取的值分别进行测试,找到满足条件的组合后就将其输出。这种通过循环的方式枚举每一种组合,可从所有候选答案中查找正确的答案。当候选答案集合很大时(如上百万、千万或更大数量),采用人工方式就没法处理,由于计算机能高速运算,可以很快就从这些海量信息中搜索到正确的结果。

注意:使用类似上面多重循环嵌套的控制结构代码时,循环嵌套的层数越多,需要处理

的次数就越多,为了提高程序的运行速度,应尽量简化或优化循环的嵌套。 【例 1.12】给定一个正整数,确定它的整数的立方根是否存在,如存在则找出这个立方根。 解题思路: 显然,一个正整数的整数立方根如果存在的话,肯定是在这个数和零之间的某个值,而

这之间的正整数的个数是有限的,所以可以设计一个基于枚举法的算法。 算法描述: BEGING number ← 输入一个正整数 result ← 0

WHILE(result number)

BEGIN IF(result×result×result==number) break ELSE result ← result+1 END

IF(result number)

result 是 number 的立方根,输出 result 的根 ELSE

Page 34: 计算机与程序设计基础 - Baiduimages.china-pub.com/ebook55001-60000/57390/ch01.pdf第1 章 计算机与程序设计基础 3 程序原理的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制

34 计算机程序设计(C 语言版)

输出 number 没有立方根的信息 END

【例 1.13】一辆卡车违反交通规则,撞人后逃逸。现场有三人目击事件,但都没有记住车号,只记下车号的一些特征。甲说:牌号的前两位数字是相同的;乙说:牌号的后两位数字是相同的,但与前两位不同;丙是位数学家,他说,四位的车号刚好是一个整数的平方。请根据以上线索求出肇事车号。

解题思路: 对各种可能出现的车号情况进行三重嵌套循环,对各种数据进行验证是否为待求的车号。

由于车号由 0~9这 10个数字构成且满足下面的规则: 甲在 0~9数字选择的两位数字为千位数字和百位数字且相同; 乙在 0~9数字选择的十位和个位数且相同; 丙在 10~99数字中选择两位整数的平方。

算法描述: for(i=0;i<=9;i++) //i 表示车号前两位的取值

for(j=0;j<=9;j++) //j 表示车号后两位的取值

if(i!=j){ //判断两个数字是否相等

k=i*1000+i*100+j*10+j; //计算出可能的整数 k(车号)

for(c=31;c*c<k;c++) //循环判断 k 是否为另一整数的平方

; //循环体为空语句

if(c*c==k) //若是,打印求解结果

printf("卡车车号是:%d\n",k); }

程序使用 for 循环嵌套,第 1 个 for 循环的循环变量 i 用来控制车号前两位的取值,第 2个 for 循环的循环变量 j 用来控制车号后两位的取值,变量 k 是可能出现的车号,第 3 个 for循环用来判断 k是否为另一整数的平方。

若将算法转换为程序,则程序的运行结果为: 卡车车号是 7744

3.递推法 递推法是从已知的初始条件出发,逐次推出中间结果,每一步在理想状态下应逐步接近

问题的最后解。下面举一个简单的例子。 【例 1.14】计算一个正整数的阶乘,即计算 N!。 解题思路: 根据数学知识, ! 1 2 3N N= × × × × ,所以可以从 1开始,得到 1的阶乘后乘 2得到 2的

阶乘 2!,再和 3相乘得 3!⋯⋯最后得 N!。 算法描述: BEGING number ← 输入一个正整数 result ← 1 current ← 1

WHILE(current number)

BEGIN result ← result×current current ← current+1 END

Page 35: 计算机与程序设计基础 - Baiduimages.china-pub.com/ebook55001-60000/57390/ch01.pdf第1 章 计算机与程序设计基础 3 程序原理的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制

35 第 1 章 计算机与程序设计基础

输出 result END

阶乘的计算是递推法求解的一个典型的例子,其他的递推求解的例子还有求级数的和,等等。在实际的计算中,往往要注意递推中结果值增长的情况,例如阶乘的增长就非常之快,10!=3628800,13!就超过 C语言中整数的最大允许范围。

递推法在数值计算中又称迭代法,迭代法经常用于求近似解的问题,根据对前一步结果的误差的不同处理方法,迭代法又有逼近迭代和试探迭代等不同的方法。数值计算中要注意解的稳定性问题,即在迭代中每一步的解应越来越接近真正的解,否则迭代就不会成功。

4.递归法 一个直接或间接调用自身的算法称为递归算法,一个使用函数自身给出定义的函数称为

递归函数。在有些问题的算法描述中,递归往往比非递归法直接易懂。 例如,对正整数阶乘的问题,阶乘函数的递归定义为:

0! 1! ( 1)!N N N=⎧

⎨ = − ×⎩

第一式给出阶乘函数的初始值,初始值是非递归定义的。每个递归函数都需要给出非递归定义的初始值,否则这个函数无法计算出来。第二式用较小自变量的函数值来表达较大自变量的函数值,在定义式两边都引用了阶乘记号,所以是一个递归定义。

递归算法的描述和处理将在函数这一章介绍。 由上面的简单介绍已经可以看出,算法是解决问题的基础,为解决一个问题可能设计出

不同的算法。那么什么是一个好的算法呢?衡量算法的质量的指标包括算法的正确性、可读性、健壮性以及高的执行效率和低的存储空间要求。正确性是指算法对合法的输入应当能产生所要求的输出;可读性是指算法易于交流和理解;健壮性是指算法应在一定的范围内能对不合法的输入作必要的反应,而不致产生一些莫名其妙的结果;高的执行效率和低的存储空间要求是对算法在时间和空间的效率要求。

本书不可能罗列所有的算法,只是希望通过一些典型的算法的讨论,帮助读者了解如何设计一个算法,推动读者举一反三。希望读者通过这些例子了解怎样提出问题,怎样思考问题,怎样表示一个算法。

1.6 程序设计和程序设计语言

正确理解和处理程序设计语言与程序设计之间的关系,在学习程序设计的初级阶段十分重要。程序设计的作用是表达程序设计者的思想,是按照计算机所能理解和执行的方式描述需要让计算机完成的工作,而程序设计语言则是表达这种思想的工具。在程序设计工作中,首先需要明确的是所要表达的思想到底是什么,也就是到底需要计算机按照什么样的步骤来执行过程,产生什么样的计算结果。至于用什么样的语言,以及这种语言的细节。则是第二位的。这就好像一篇文章,既可以用中文写成,也可以用英文写成一样。当然,如同语言的特性和细节对于表达的方式、修辞的手段,甚至文章的结构都会有一定的影响一样,程序设计语言对于程序设计也有不可忽视的影响。只有正确、熟练地掌握了所选择的程序设计语言,才能高质量地完成复杂的程序设计工作。但是,程序设计语言毕竟只是程序外在的表示手段,是从属于程序所要表达的思想内容的。著名的计算机科学家、图灵奖获得者 Knuth 说过,对于一个计算机专业工作者来说,熟练掌握一门新的程序设计语言只需要一周的时间。他实际的意思是说,相对于一种程序设计语言,专业化的程序设计思想和方法是更为本质的知识和能力,是独立于具体程序设计语言的。在具备了基本的程序设计能力之后,掌握一门新的语

Page 36: 计算机与程序设计基础 - Baiduimages.china-pub.com/ebook55001-60000/57390/ch01.pdf第1 章 计算机与程序设计基础 3 程序原理的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制

36 计算机程序设计(C 语言版)

言并不是一件困难的事情。

1.7 本章小结

本章介绍的是学习计算机程序设计前期所需的必要基础知识和思想方法的指导,主要有: 1)冯·诺依曼的计算机组成和工作原理的基本设想可以简要地概括为以下三条: 计算机应包括:运算器、控制器、存储器、输入和输出设备五大部件。 计算机应采用二进制表示指令和数据。 程序存储方式:程序存入内存,计算机不需要操作人员干预就能自动地执行程序。

“存储程序原理”的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在

程序的控制下一步一步进行处理,直到得出结果。 2)程序就是为完成预定任务用某种计算机语言编写的一组指令序列。 3)理解存储器的基本结构、存储单元、地址及按地址访问数据与指令的概念。 4)理解计算机中采用二进制编码及存储信息的方法。 5)理解计算机采用二进制编码、信息单位、计数法及进制概念。 6)掌握十进制、二进制、八进制、十六进制之间的转换。 7)理解正负数、实数的浮点表示及值域和精度的概念。 8)理解计算机中非数值信息表示(ASCII码、汉字编码、Unicode码等信息编码)。 9)通过计算机程序设计语言的学习可以掌握与计算机交流的一种途径和方法,但程序设

计真正的核心的部分是算法的设计。通过对算法的学习,可提高读者的逻辑思维能力,发展

有条理的思考与表达能力,最终提高利用计算机解决问题的能力。 10)只学习语言的规则是不够的,最重要的学会针对各种类型的问题,拟订出有效的解

题方法和步骤——算法。有了正确的算法,可以利用任何一种计算机高级语言编写程序,使

计算机进行工作。对于初学者来说,最困难的可能还是很难适应描述计算机算法的思维习惯,

人们也很难承受程序必须将算法描述得几乎绝对地精细和精确。但对计算机来说,这又是非

常必要的。 11)读者在学习计算机程序设计的过程中不应把重点放在 C 语言的具体语法上,而是应

从算法入手,在实践过程中逐步养成一个习惯:在求解一个问题时,首先应当考虑算法,而

不是马上动手写程序。程序处理的对象是数据,数据与数据之间会存在某种形式的联系,这

就是数据结构。在程序设计时,除了要考虑算法外,还要考虑并选择适当的数据结构。对于

不同的数据结构,要用不同的算法去处理。 12)通过本章的学习,读者应切实掌握一种好的适合自己的算法描述方法,以便熟练地

应用于后续的编程实践。 13)学习结构化程序和算法设计思想,掌握结构化的程序设计方法是学会程序设计非常

有效的途径。 14)结构化程序设计的思想和目的是使程序具有结构合理、正确性高、易验证的特点。

经过不断总结,已经积累了一套程序设计准则。可以简单归纳为以下几点: 基于自顶向下,逐步求精的设计方法; 程序书写遵循一定的格式,使结构清晰; 程序由模块构成,每个模块具有独立的功能。模块之间的数据联系要简单,每个模块

只能有一个入口和一个出口; 程序中只包含三种基本的结构:顺序、分支、循环。

Page 37: 计算机与程序设计基础 - Baiduimages.china-pub.com/ebook55001-60000/57390/ch01.pdf第1 章 计算机与程序设计基础 3 程序原理的主要思想是:将程序和数据存放到计算机内部的存储器中,计算机在程序的控制

37 第 1 章 计算机与程序设计基础

1.8 习题

1.试述现代计算机的工作原理。 2.冯·诺依曼结构的电子计算机的硬件系统由哪几部分构成?各部件的功能是什么? 3.简述计算机使用二进制的原因。 4.将下列十进制数转换成二进制数、八进制和十六进制数(精确到小数点后 4 位)。

123 8962.5827 5.将下列二进制数转换成十进制数、八进制数和十六进制数。

111011 11001011 1101101.010 6.将下列八进制数转换成二进制数和十六进制数。

176 51.32 3165.75 7.将下列十六进制数转换成二进制数和十进制数。

85E A7.2 387.15 8.输入 10 个数,将其中能被 3 和 5 整除的数输出。 9.求方程 2 0ax bx c+ + = 的根(分别考虑 2 4b ac− 大于 0、小于 0、等于 0 的情况)。 10.用下面公式求 sinx 的值(x 的值设为 3)。

3 5 7 4 1 4 1

sin1 3! 5! 7! 4 1 ! 4 1 !

n nx x x x x xxn n

− +

= − + − + − +− +( ) ( )

直到最后一项的绝对值小于 10−7 时,停止计算。 11.用自顶向下、逐步求精的方法进行以下算法的设计:已知五边形的边及对角线的长度,

求五边形的面积(如图 1-32)。

S1

S2 S3

A1 A2

A3

A4

A5A6

A7

图 1-32 多边形面积示意图

注:第 8~11 题可任选伪代码、传统流程图、N−S 图或 PAD 图中任意一种方法描述。


Top Related