第1章 FORTRAN语言简介
FORTRAN是目前国际上广泛流行的一种高级语言,适用于科学计算。FORTRAN是英文FORmula TRANslation的缩写,意为“公式翻译”。它是为科学、工程问题中的那些能够用数学公式表达的问题而设计的语言,主要用于数值计算。
这种语言简单易学,因为可以像抄写数学教科书里的公式一样书写数学公式,它比英文书写的自然语言更接近数学语言。
学习目标:
FORTRAN的发展历史
FORTRAN的新发展
FORTRAN语言的特点
1.1 FORTRAN的发展历史
FORTRAN语言至今已有40多年的历史,但仍经久不衰,始终是数值计算领域所使用的主要语言。FORTRAN语言问世以来,根据需要先后推出了很多版本。
第一代FORTRAN语言是在1954年提出来的,称为FORTRANⅠ。它于1956年在IBM 704计算机上得以实现。最初的目的是想开发一种容易理解、简单易学又能像汇编一样高效运行的语言,开发取得了极大的成功。FORTRAN语言作为第一种高级语言不仅是一次创新,也是一次革命。
它使程序员摆脱了使用汇编语言冗长乏味的负担,而且它使得不再只有计算机专家才能编写计算机程序,任何一名科学家或工程技术人员,只要稍加努力学习和使用FORTRAN,就能按自己的意图编写出用于科学计算的程序。
正因为FORTRAN满足了现实的需要,所以它传播得很快,在传播和使用过程中不可避免地产生了多种版本。各种FORTRAN语言的语义和语法的规定又不完全一致,这给用户带来了极大的不便。用户迫切希望有能在各种机型上互换通用的FORTRAN语言。
因此FORTRAN语言的标准化工作变得十分迫切。1962年5月,当时的美国标准化协会ASA(American Standard Association)成立了工作组开展此项工作,1966年正式公布了两个美国标准文本:标准基本FORTRAN X3.10-1966(相当于FORTRAN Ⅱ)和标准FORTRAN X3.9-1966(相当于FORTRAN Ⅳ)。
美国标准化协会在1976年对FORTRAN X3.9-1966进行了修订,基本上把各厂家行之有效的功能都吸收了进去,此外又增加了不少新的内容,1978年4月美国标准化协会正式将它作为美国国家标准公布,即ANSI X3.9-1978 FORTRAN,称作FORTRAN77。
1980年,FORTRAN 77被接受为国际标准,即“程序设计语言FORTRAN ISO 1539-1980”,这种新标准并不是各非标准FORTRAN的公共子集,而是自成一体的新语言。我国制订的FORTRAN标准基本采用了国际标准(即FORTRAN 77),于1983年5月公布执行,标准号为GB3057-82。FORTRAN 77还不是完全结构化的语言,但由于增加了一些结构化的语句,使FORTRAN 77能用于编写结构化程序。此外,还扩充了字符处理功能,使FORTRAN不仅可用于数值计算领域.还可以适用于非数值计算领域。
因为FORTRAN 77有明显的局限性,为了引入一些新的功能,适应语言的发展,ANSI在1991年通过了FORTRAN 90新标准ANSI X3.198-1991,相应的国际化标准组织的编号为ISO/IEC1539:1991。新的FORTRAN标准废弃了过时的严格的源程序书写格式,改善了语言的正规性,并提高了程序的安全性,功能有更大的扩充,是一个能适应现代程序设计思想的现代程序设计语言。
随着其他程序设计语言的迅速发展,FORTRAN语言不再是唯一适用的程序设计语言。然而,尽管在一些特殊领域,使用其他程序语言更为合适,但在数值计算、科学和工程技术领域,FORTRAN仍具有强大的优势。其强大的生命力在于它能紧跟时代的发展,不断更新标准,每次新的版本推出都在功能上有一次突破性进展。
FORTRAN 90不仅仅是将已有的语言进行标准化,更重要的是发展了FORTRAN语言,吸取了其他语言的一些优点。所以,虽然FORTRAN语言历史悠久,但仍在日新月异地发展。
随着巨型计算机(向量机和并行机)的异军突起,出现了新的高性能FORTRAN语言——HPF。它是FORTRAN 90的一个扩展子集,主要用于分布式内存计算机上的编程,可以减轻用户编写消息传递程序的负担。HPF1.0的语言定义是在1992年的超级计算国际会议上提出的,正式版本是在1993年公布的。其后几年的会议上又对它进行了修改、重定义、注释等工作,于1997年发布了HPF2.0语言定义。FORTRAN 95包含了许多HPF的新功能。在FORTRAN 90出现之前,在并行机上运行程序需要结合专门的矢量化子程序库,或者依赖FORTRAN编译系统进行自动矢量化。而在FORTRAN 90推出之后,程序员在编程时可有目的地控制并行化。
在程序设计语言层出不穷的今天,学习FORTRAN语言的意义在于继承传统和紧跟时代。不仅一些爱好者推崇FORTRAN语言,而且科学计算编程的专家也认为,科学与工程相关专业的学生应该采用FORTRAN而非C和C++编程。这是因为,FORTRAN 90具有C++所有的重要功能,然而C语言主要是用于微机上的廉价开发,而FORTRAN的目的是为了产生高效的、最优化运行的可执行程序。用FORTRAN编写的大型科学计算软件较C语言编写的通常要快一个量级,其程序编写更为自然和高效,且易学易懂。尤其是在高性能并行计算逐渐成为时代必然的今天,巨型机甚至微机和工作站都有了多处理器,其串行机上的线性内存模式已不再适用,而只有FORTRAN具备处理相应问题的标准并行化语言,其独特的数组操作充分体现了它的先进性。
. 1.2 FORTRAN的新发展
1992年,FORTRAN 90作为ANSI标准发表,这一版本增加了以下新特性:
1)自由格式源代码输入以及小写的FORTRAN关键字。
2)模块将有关联的过程和数据组合在一起,使它们可以被其他程序单元调用,包括允许限制一些模块的特定部分访问。
3)极大地改善了参数传递机制,允许在编译时检查接口。
4)通用过程的用户自定义接口。
5)派生/抽象数据类型。
6)可以在表达式和赋值语句中按整体操作数组(或数组节),因此极大地简化了数学和工程计算。这些特性包括整体、部分和通配的数组赋值(比如用WHERE语句做选择性赋值)、数组常数和表达式、用户定义的数组函数和数组构造。
7)通过ALLOCATABLE属性、ALLOCATE和DEALLOCATE语句动态内存分配。
8)POINTER属性、指针赋值和NULLIFY语句便于创建和操作动态数据结构。
1995年,FORTRAN 95发布,与FORTRAN 90相比较来说,这一版增加了以下全新的功能:
1)FORALL语句与结构。
2)纯(PURE)过程。
3)逐元(ELEMENTAL)过程。
4)WHERE结构的扩展。
5)默认初始化。
6)NULL固有函数。
7)CPU_TIME固有子例行程序。
8)固有函数CEILING、FLOOR、MAXLOC、MINLOC的扩展。
9)可分配数组的动态去分配。
10)名称列表输入里面的注释。
11)最小域宽格式说明。
12)用于支持IEEE 754/854浮点运算标准的某些修改。
2003年,FORTRAN 2003发布,与FORTRAN 95相比增加了以下新特性:
1)增强了派生类型:带参数的派生类型,改善了控制的可操作性,改善了结构化的创建和释放。
2)支持面向对象编程:扩展类型和继承、多态、动态类型分配,以及类型绑定过程。
3)改善了数据操作:可分配的组件(编入IEEE TR 15581),延期的类型参数,VOLATILE属性,在数组构造和分配语句中显式定义类型,增强的指针,扩展的初始化表达式,增强的内部过程。
4)增强的输入输出:异步传输,流访问,用户指定派生类型的传输操作,用户在格式转换时指定舍入控制,为连接前单元指定常数,FLUSH语句,关键字的规范,访问错误信息。
5)过程指针。
6)支持IEEE浮点算法和浮点异常处理(编入IEEE TR 15580)。
7)与C语言的交互性。
8)支持国际化:可访问ISO 106464字节字符和在格式化的数字输入输出中选择数字或者逗号。
9)与宿主操作系统增强的集成:访问命令行参数,环境变量和处理器错误信息。
2008年,FORTRAN 2008发布,这一版对FORTRAN 2003进行了一些小幅度的改动,本书后面章节将对FORTRAN 2008的新特性给予详细介绍。另外,由于FORTRAN 2008相比较FORTRAN 2003而言改动不大,所以本书的主要讲解版本为FORTRAN 2003,请读者在学习的时候注意。
1.3 FORTRAN语言的特点
FORTRAN语言从产生发展到现在,有着很强的生命力,在各种高级语言如C++、Java、Delphi、C#等层出不穷的今天依然占有重要的地位,这与FORTRAN语言的优点有密切的关系。下面对FORTRAN语言的主要特点进行简要介绍。
1)FORTRAN容易学习,语法简明严谨。FORTRAN语法的最大特性就是接近数学公式的自然描述,可以直接对矩阵和复数进行运算,特别适合做矩阵数组运算,在计算机里具有很高的执行效率。因此FORTRAN非常适合科学计算,至今仍然是最主要的科学计算语言。现在很多的商用工程软件,如著名的有限元软件ANSYS、MAC等就是用FORTRAN来编制核心算法的。
2)FORTRAN历史悠久,从其开发出来以后就一直在做数值计算,长时间以来,FORTRAN产生了一大批高效、严格、成熟的函数库和软件包,在做数值计算的时候这些可以直接拿来使用,而没有必要用C或C++再写一遍,这是一笔巨大的资源,对工程技术人员来说,会省时省力。另外,Intel等成熟的FORTRAN编译器,有助于将FORTRAN代码在计算机上高效地优化编译,产生比同样的C/C++更快的执行代码。现在主流的高性能计算和并行库大多是基于FORTRAN的。
3)FORTRAN运算速度要快于C++语言。这在大的工程计算软件中可以提高运行效率,降低成本。
另外,需要看到的是,FORTRAN只是在数值计算领域比其他语言有较强的优势,但是,FORTRAN的其他高级特性,比如指针就没有C/C++那样灵活。而且,FORTRAN的应用范围局限于做算法、做核心部件,而C则有广阔的适用空间。从上面的介绍可以看出,如果想要做工程计算的话,那么FORTRAN是首选语言。
第2章 FORTRAN编译器的安装及使用
本章将对FORTRAN不同种类的编译器,比如Visual FORTRAN系列、G95/gFORTRAN的Windows版本、Absoft FORTRAN、PGI Visual FORTRAN等进行简要介绍,并比较不同编译器的优缺点,使读者对编译器能有进一步的了解。另外选择Intel Visual FORTRAN 2011和Microsoft Visual Studio 2010作为集成开发环境进行讲解,使读者掌握编译器的使用方法。
学习目标:
了解不同种类编译器的优缺点
掌握Microsoft Visual Studio 2010和Intel Visual FORTRAN 2011的安装方法
掌握如何利用Visual FORTRAN开发FORTRAN应用程序
2.1 编译器简介
编译器(Compiler)就是把FORTRAN、C等高级语言翻译成机器码,从而使计算机能够执行并得出相应结果的软件。当然也有一些解释语言并不需要编译器就可以直接运行,例如Visual Basic、PHP、JavaScript等。
当FORTRAN语言开发出来以后,出现了很多种的编译器,Windows系统下计算机上的常用平台如下。
1)FORTRAN Power Station 4.0。微软公司将FORTRAN 90集成到Developer Studio开发环境之后推出的FORTRAN编译器,这个平台真正实现了FORTRAN的可视化编程。
2)Digital Visual FORTRAN。由微软公司和DEC公司联合开发的功能更强大的FORTRAN编译器。
3)其他的还有G95/gFORTRAN的Windows版本、Absoft FORTRAN、PGI Visual FORTRAN等。
这其中,影响较大、功能较全、性能较好、应用最广泛的FORTRAN编译器是提供了集成开发环境的Visual FORTRAN系列。这些编译器各有自己不同的特点,在本节对Visual FORTRAN系列的编译器进行一个简要介绍,读者在选择的时候根据实际需要选择合适的编译器即可。
2.1.1 Compaq Visual FORTRAN编译器
Visual FORTRAN系列编译器的前身是微软公司开发的FORTRAN Power Station 4.0编译系统。该系统结合了当时微软最新开发的Developer Studio集成开发环境(IDE),使得FORTRAN程序的开发方式跟上了时代的潮流。
Visual FORTRAN编译器的优势包括:全面支持FORTRAN 90语言标准;对FORTRAN语言进行丰富扩展;具有系统全面的在线文档;能方便地与Microsoft Visual C++进行混合编程等。但是该编译系统在实际使用中出现的问题较多,例如没有严格的数组越界检查功能等。
1997年3月,微软公司与DEC公司达成协议,授权DEC提供其后继版本Digital Visual FORTRAN 5.0版本;1998年1月,DEC公司和Compaq公司合并,于是Digital Visual FORTRAN 更名为Compaq Visual FORTRAN。现在流行的最新版本是Compaq Visual FORTRAN Version 6.6。
Compaq Visual FORTRAN由于具有以下突出特性,从而使以往的其他工具无法与之相媲美。
1)具有集成开发环境Developer Studio,程序设计者可以在集成开发环境中方便地进行编辑、编译、连接和调试。
2)生成的是Windows操作系统下的32位应用程序,提高了代码的执行效率,突破了原先PC系统下FORTRAN程序64KB寻址空间的限制,更加充分地利用了系统资源。
3)在集成开发环境中,可以可视化地进行Windows用户图形界面设计、设置编译连接选项和编译连接。
4)FORTRAN Power Station的调试(Debug)功能使程序设计者可以在集成开发环境中方便地跟踪和控制程序的执行,查看或修改变量和表达式的值,查看反汇编代码或查看堆栈情况。
5)不仅可以开发传统的控制台应用程序和图形界面程序,还可以使用QuickWin库在不必深入了解Windows系统的情况下,简便地开发出具有Windows图形界面特点应用程序,甚至可以更进一步地利用Windows API函数接口进行Windows程序设计。
6)可以方便地与Visual C/C++、MASM和Visual Basic进行混合语言编程,以充分利用各个语言所具有的优点。
7)所建立的动态链接库可以被Excel中的VBA调用,使开发出的应用程序与Excel相结合。
2.1.2 Intel Visual FORTRAN编译器
随着计算机处理器技术的飞速发展,64位的计算机已经越来越普遍了,Intel公司的CORE处理器也从酷睿双核升级为i5、i7,微软的Windows 7系列的64位操作系统以其全新的界面、流畅的用户体验占有了极大的操作系统市场。
随着64位操作系统的不断发展,相应的FORTRAN开发也出现了一个问题——Compaq Visual FORTRAN(CVF)不支持64位系统,因为2005年以前FORTRAN 90/95 的Win32 开发环境多采用Compaq Visual FORTRAN 6.x,但2005年CVF 开发团队加盟到Intel 公司,HP 宣布其CVF6.6有效期截至2005年12月31日,Intel Visual FORTRAN(IVF)9.0 将作为其新一代后继编译器。
IVF是在CVF的基础上开发的FORTRAN编译器,它将CVF 前端与Inter处理器后端相结合,拥有CVF 丰富的语言功能和Inter处理器的代码生成及优化功能,使运行在Inter平台上的程序能得到大幅度提高。
随着计算规模的增大,对计算内存的要求必须采用64位的程序才能够满足开发的要求,但CVF没有提供64位系统的编译平台。
另外,程序并行功能的实现可以用Intel的MKL所提供的函数库,这些函数库采用了共享内存并行计算的OpenMP,但以前的CVF没有提供对OpenMP的支持,所以无法调用MKL的并行函数库。所以,从CVF 6.x转移到IVF 9.0已是势在必行,选用IVF来编译FORTRAN程序也是很有必要的。
在使用CVF6.5/6.6编写运行FORTRAN程序时,只需要安装Compaq Visual FORTRAN 6.5/6.6即可。这是因为在这个安装源程序中,Visual FORTRAN已经被集成在Microsoft Visual Studio(VS)的图形接口开发环境中了,所以可以直接安装使用。
与C++相似,FORTRAN语言本身并没有提供图形界面输出方面的功能,为了使用FORTRAN语言编写图形接口程序,必须借助Intel Visual FORTRAN等图形化的编译器。Intel Visual FORTRAN编译器几乎封装了完整的Win32 API和OpenGL函数,提供了良好、稳定的编程接口,所以借助IVF,FORTRAN可以完成UI设计,同时也可以完成图形编程。
采用IVF来编写运行FORTRAN程序则稍微麻烦些。因为Intel Visual FORTRAN Compiler版本都只是编译器,它需要放到集成开发环境(Integrated Development Environment,IDE)中去才能使用。故而IVF Compiler还需要VS 6.6以上版本IDE的支持,所以必须事先安装好VS后,才能安装编译器。为了兼容Window 7操作系统,本书中使用的编译器就是Intel Visual FORTRAN XE 2011和Microsoft Visual Studio 2010(Microsoft Visual Studio 2008也可以集成到IVF XE 2011上面,读者也可选择VS 2008)。
提示:集成开发环境软件是用于程序开发环境的应用程序,一般包括代码编辑器、编译器、调试器和图形用户界面工具,就是集成了代码编写功能、分析功能、编译功能、调试功能等一体化的开发软件套。所有具备这一特性的软件或者软件套(组)都可以叫作IDE。如微软的Visual Studio系列、Borland的C++ Builder、Delphi系列等。该程序可以独立运行,也可以与其他程序并用。
2.2 Visual FORTRAN的安装
前面已经对Visual FORTRAN编译器进行了一个简要的介绍,本节将为读者介绍集成开发环境Visual Studio 2010和Intel Visual FORTRAN XE 2011的安装过程。
提示:在安装的过程中,一定要先安装VS 2010,再安装IVF,否则无法进行集成应用。
2.2.1 Visual Studio 2010安装
Microsoft Visual Studio(简称VS)是美国微软公司的开发工具包系列产品。VS是一个基本完整的开发工具集,它包括了整个软件生命周期中所需要的大部分工具,如UML工具、代码管控工具、集成开发环境等。所写的目标代码适用于微软支持的所有平台,包括Microsoft Windows、Windows Mobile、Windows CE、.NET Framework、.NET Compact Framework和Microsoft Silverlight等。
下面对VS 2010的安装过程进行详细说明。注意:不同版本安装界面可能与本书所述略有差异,请读者安装的时候仔细甄别。
① 打开软件安装包源文件,双击setup.exe文件,出现如图2-1所示界面。
② 单击Install Microsoft Visual Studio 2010,出现如图2-2所示界面。
图2-1 VS安装开始界面图2-2 VS安装提示界面
③ 待下方进度条完全完成之后出现如图2-3所示界面。
④ 单击Next按钮,出现如图2-4所示界面。
图2-3 VS安装许可协议界面图2-4 接受安装协议界面
⑤ 单击选择I have read and accept the license terms,单击Next按钮进入下一步,出现如图2-5所示界面。
⑥ 在图2-5所示界面中,左侧的Full选项表示将安装VS 2010的全部组件,Custom表示典型安装,需要用户选择安装的组件,建议不熟练的读者选择Full选项安装。右侧的Product install path表示选择安装路径,读者可根据自己的需要选择自己的安装路径。如果不选择的话,默认会安装到C:\Program Files\Microsoft Visual Studio 10.0下。单击Install按钮进入下一步,出现如图2-6所示界面。
图2-5 VS安装类型选择界面图2-6 VS 2010安装组件界面
⑦ 出现安装组件界面之后,需要等待大约30分钟,当所有的组件安装完毕之后即可。
注意:安装过程中需要重新启动(restart)计算机一次,读者安装的时候按要求重启即可。如出现如图2-7所示界面,则表示安装完毕。
图2-7 VS 2010安装完毕界面
当VS 2010安装完成之后,可以从开始菜单中打开VS 2010界面运行一下。下面继续讲解IVF XE 2011的安装。
提示:安装IVF XE 2011之前一定要关闭VS,否则安装无法完成!
2.2.2 Intel Visual FORTRAN XE 2011安装
下面讲解Intel Visual FORTRAN XE 2011的安装过程。
① 打开软件安装包,双击setup.exe文件,出现如图2-8所示界面。
② 单击“下一步”按钮,出现如图2-9所示界面。
图2-8 IVF安装初始界面 图2-9 软件协议界面
③ 选择I accept the terms of the license,单击“下一步”按钮,出现如图2-10所示界面。
④ 输入安装序列号,并单击“下一步”,出现如图2-11所示界面。
图2-10 输入安装序列号 图2-11 等待安装
⑤ 单击Install按钮进行安装,出现如图2-12所示界面。
⑥ Full installation(recommended)表示安装IVF的全部功能组件,建议读者选择此项。Custom installation(for advanced user)表示选择必要的组件进行安装并可以修改安装路径。选择安装类型之后,单击“下一步”按钮,出现如图2-13所示界面。
图2-12 安装类型选择界面 图2-13 安装界面
⑦ 单击Install按钮,出现如图2-14所示组件安装界面。
⑧ 当安装进度条完成之后,单击“下一步”按钮,出现如图2-15所示界面,表示IVF安装完成。至此,软件安装完毕。
图2-14 IVF组件安装界面 图2-15 IVF安装完成界面
当VS 2010和IVF XE 2011安装完成之后,就可以使用它们进行程序编写和运行了。
2.3 Visual FORTRAN的使用
在本节中,将对IVF和VS 2010集成的开发环境进行详细的说明和介绍,使读者能够明白如何进行程序的编写、编译和运行。
2.3.1 初次使用配置
① 从“开始”菜单中找到Parallel Studio XE 2011 with VS 2010并单击,在第一次使用的时候会出现VS开发环境设置和等待加载设置界面,如图2-16和图2-17所示。
图2-16 VS 2010开发环境设置 图2-17 加载用户设置
② 在进行FORTRAN开发的时候,选择“常规开发设置”即可。待程序加载完成之后,出现开始界面,如图2-18所示。
图2-18 VS 2010开始界面
2.3.2 用Visual FORTRAN编写、编译运行程序
① 当VF打开之后,依次选择File->New->Project,如图2-19所示。
图2-19 新建应用程序
② 完成上一步以后会出现如图2-20所示界面。在图2-20所示界面中,首先选择左侧Intel Visual Fortran选项下面的Console Application。Console Application是基于字符形式的应用程序,这类项目适用于不需要图形输出的程序设计,其优点就是执行速度快,执行效率高。在本书中讲解的程序主要都是这种类型的。
图2-20 新建FORTRAN项目
选择项目文件类型之后,继续选择上侧的Empty Project,然后在下面的Name输入框中输入项目文件(Project)的名称,最后单击Browse按钮选择文件存放位置,选择完成之后在Location后面的输入框中相应的路径名称会自动改变过来。
③ 对项目名称、位置等进行相应设置以后,单击OK按钮,出现如图2-21所示界面。
图2-21 程序主界面
程序主界面主要包括6个部分。最上面一行是“菜单栏”,这是所有软件都会有的。“菜单栏”下面是“工具栏”,可以将常用工具放置这里,从而提高编程开发效率。
左侧是“服务器资源管理器(Server Explorer)”面板,右侧上方是“解决方案资源管理器(Solution Explorer)”面板,右侧下方是“属性(Properties)”面板,中间下方是“错误列表(Error List)”和“输出(Output)”面板。如果想改变这个面板所显示的内容,可以从菜单栏中View下拉菜单中选择不同的内容进行显示。
④ 下面为项目添加源文件。在“解决方案资源管理器”面板中选中Source Files右击,依次选择add->New Item选项,出现如图2-22所示界面。
首先选择“自由格式文件(FORTRAN Free-form File)”,下面的“FORTRAN Fixed-form File”表示固定格式文件,这是原来FORTRAN 77版本的书写格式,现已废弃不用。Header File表示头文件,这在后续章节会讲到。
在下面的Name输入框中输入源文件的名字,最后单击Browse按钮,选择文件存放位置,选择完成之后在Location后面的输入框中相应的路径名称会自动改变过来。
图2-22 添加源文件
⑤ 将文件名、文件位置设置好之后,单击Add之后会出现如图2-23所示界面。图中上方中间部分就是代码编辑区域,下方为“错误列表”和“输出”面板。
⑥ 将下面一段代码输入到如图2-23所示代码编辑区域中。
PROGRAM Ex0201
IMPLICIT NONE
WRITE(*,*) "Hello World,This is my first FORTRAN project!"
END
图2-23 源代码编辑区域
⑦ 输入完成之后,依次选择菜单栏中的Debug->Start Without Debugging或者按下快捷键Ctrl+F5,运行程序,出现如图2-24所示窗口,说明程序运行成功。
图2-24 程序运行结果
2.3.3 用Visual FORTRAN调试程序
在实际开发中,编写出来的程序总是会出现各种各样的问题,比如语法错误或者逻辑错误,这时就需要程序开发人员依据编译器返回的错误信息进行错误排除,从而能够迅速地找到程序的错误,并尽快将其进行改正。
FORTRAN语言的编译器功能非常强,它既能够指出错误的可能位置,也能给出错误的原因和相应的建议。
这里需要初学者注意的一个问题就是:由于一个错误,可能会导致许多相关的错误,这里编程出现错误之后首先修改明显的错误,再进行编译,检查是否还有其他语法错误,没有必要对所有的错误都去修改。对于初学者来说,常出现程序只有几行,可错误却有几十行的情况,这是非常正常的。这是因为,初学者对语法不熟悉,常出现拼写、中英文符号混淆等错误。
上一节编写的程序中,由于没有语法错误,因此可以正常地编译运行通过。如果在实际开发过程中,程序代码出现语法错误,那么是无法调试运行通过的,这时可以查看程序错误信息中显示的说明。
在程序编写完成运行之后,如果出现了错误,那么编译系统会给出如图2-25所示类似的错误信息(此处为说明如何查看错误,故意在程序中插入语法问题)。下面对图2-25的信息进行说明。
当程序出现错误时,Output面板下方倒数第二行的地方出现了“2 error(s),0 warning(s)”,这表示当前程序有两个错误,上面的两行就是错误的具体信息。当对其中一行进行单击时,在上方的程序源代码处具体的错误一行左边会有一个标志出现,表示错误行所在位置,因此可根据错误行对错误的具体描述,对程序语法错误进行修正,改正之后,程序就可以运行了。
图2-25 错误程序调试
提示:读者在实际开发过程中,要不断关注编译系统给出的错误提示,从而能够快速发现并改正错误,提高编程效率!
跟踪运行步骤调试程序的过程如下。
当程序没有语法问题而有逻辑问题的时候,程序可以调试通过,但是却不能得到正确的运行结果,这时可以启用单步调试工具。
单步执行时一次只执行一行代码,执行后暂停运行程序,等待接着按“单步运行”按钮或其他操作。常用来跟踪程序每一步的执行情况。
程序进行单步执行时,首先要在觉得可能会出现问题的地方设置一个执行的断点,让程序从设置断点所在的行开始向下执行。通过暂停执行来查看当前变量的值,从而检查出程序的逻辑错误。下面对如下程序进行单步运行调试。
program Ex0202
implicit none
integer::x=1
integer::y=3
do while (y<=11)
x=x*y
y=y+2
end do
write(*,*) x
end?????
首先依次选择菜单栏上的Debug->Windows->Breakpoints或者直接按下快捷键Ctrl+Alt+B,如图2-26所示。然后在程序源代码要设置断点的行的左侧单击,会出现如图2-26第3行代码处所示的图标,这表示断点设置成功。
图2-26 设置断点
设置断点之后,按下F10键,程序会进入调试运行状态,如图2-27所示。
在图2-27中,左侧程序断点处会出现一个箭头状的标记,表示程序目前运行所在的行,通过切换到下方左侧面板中的Locals选项卡,可以查看运行到当前步骤时变量的值。下方右侧表示程序运行内存中的堆栈信息,可以不用考虑。
通过不断按F10键,可以使程序一步一步地向下运行,从而查看变量值的变化,从中发现程序编写时出现的逻辑错误,最终使程序顺利通过。
当程序执行完毕时,可以依次选择菜单栏上的Debug->Stop Debugging或者按Shift+F5键,结束单步运行状态,返回到程序初始界面。
特别说明:
在关闭一个项目文件时,一定要依次选择File->Close Project,否则再写新的项目文件时会出错。
要写新的程序可以新建一个Project,或者将已有的程序文件进行替换,不要把两个独立的程序文件放到同一个Project中,否则编译过程会出错。
下次进行修改时,可以依次选择File->Open->Project/Solution直接打开解决方案文件(后缀为.sln格式)进行修改编辑。解决方案文件中包含解决方案中的工程、项目以及它们的位置信息等。
图2-27 单步程序调试
2.3.4 利用Intel Visual FORTRAN移植Compaq Visual FORTRAN的工程
由于Intel Visual FORTRAN开发晚于Compaq Visual FORTRAN,因此IVF可以向后兼容用CVF编写的FORTRAN工程文件。下面来具体讲解如何利用Intel Visual FORTRAN来移植Compaq Visual FORTRAN的工程。
① 找到要进行移植的CVF工程(.dsw格式文件),右击选择“打开”或者在IVF开发环境中依次选择File->Open->Project/Solution打开CVF工程,出现如图2-28所示页面。
图2-28 确认移植页面
② 单击Yes按钮以后等待文件移植,会出现如图2-29所示打开界面。在“解决方案资源管理器”面板上可以看到项目名称。
③ 在工程文件名称上单击右键,选择Extract Compaq Visual FORTRAN Project Items进行FORTRAN项目文件的提取,提取完成之后就完成了从CVF到IVF的转换。
④ 可以依次选择File->Open->File来打开相应的FORTRAN源文件,查看或者修改程序源代码。
至此,Intel Visual FORTRAN集成开发环境的使用、编写程序、编译、单步调试、工程文件的转换讲解完毕,希望读者能够认真研读本章,从而能够熟练运用IVF。
图2-29 打开界面
2.4 本章小结
本章对不同种类的FORTRAN编译器进行了简要的介绍,并重点讲解了Microsoft Visual Studio 2010和Intel Visual FORTRAN 2011集成开发环境的安装方法,及FORTRAN程序的编译、调试方法,这些基础工作为后面学习程序设计打下坚实的基础,同时也为其他语言的学习提供了借鉴作用。
第3章 程序设计方法及程序算法
想要编写一个高质量、高效率的程序,必须要设计一个优秀的程序算法。在现代语言程序设计中,算法是一个程序的核心和灵魂之所在,作为一名合格的程序员,对程序设计方法和程序算法要有较好的了解和掌握。
学习目标:
了解程序设计方法的基本概念
熟悉算法的概念和常用基本算法的编写
掌握传统流程图编写算法的方法
掌握N-S流程图编写算法的方法
3.1 程序设计方法简介
在现代社会中,随着科学技术的迅猛发展,越来越多的工程方法都要由程序来完成,比如数值计算、图像处理、人工智能、语音识别等。那么究竟什么是程序呢?简单来说,程序就是程序员利用计算机语言编写的、能够完成特定功能和任务的计算机代码,程序编写的目的是为了提高工程应用的自动化水平,简化人的操作,提高工作效率,促进社会发展。著名计算机科学家沃思(Niklaus Wirth)提出了如下公式,可以作为程序设计的最好解释。
程序=数据结构+算法
此公式可以说是计算机程序设计的根本灵魂之所在,它深刻地诠释出了计算机程序设计的本质。
随着现代软件行业的不断发展,作为一名程序员,除了对数据结构和算法有深刻的理解之外,还要选择适当的开发工具进行程序的开发和编写,这样能够提高工作效率。我们在第2章中讲到的Intel Visual FORTRAN和Visual Studio 2010集成的工具就是一个高效的FORTRAN语言开发环境,利用这些可以极大地提高开发效率,达到事半功倍的效果。
一名优秀的程序员不仅要有扎实的基础知识和熟练的开发技巧,还要有专业化的程序设计方法。因此,现代程序设计方法定义还可以扩展为:
程序=算法+数据结构+开发工具+程序设计方法
现代软件工程行业对于软件设计开发主要基于两种方法。
1.结构化程序设计方法
结构化程序设计由迪克斯特拉(E.W.Dijkstra)在1969年提出,它是以模块化设计为中心,将待开发的软件系统划分为若干个相互独立的模块,这样使每一个模块的工作变得单纯而明确,为设计一些较大的软件打下了良好的基础。
结构化程序设计的原则是自顶向下、逐步细化、模块化设计及结构化编码,这样做的优点就是,由于所有的模块相互独立,不会受到其他模块的干扰,从而提高了程序设计的独立性,并且可以将一系列复杂的软件设计改为相互独立的、简单的软件设计方式。
2.面向对象程序设计方法
面向对象(Object-Oriented,OO)是20世纪90年代开始形成的,是现代软件开发方法的主流方法,它是一种适用于设计、开发各类软件的范型。它将软件看成是一个由对象组成的社会,这些对象具有足够的智能,能理解从其他对象接受的信息,并以适当的行为做出响应;允许低层对象从高层对象继承属性和行为。通过这样的设计思想和方法,将所模拟的现实世界中的事物直接映射到软件系统的解空间。
与传统的结构化程序设计相比,面向对象程序设计吸取了结构化程序设计的一切优点(自顶向下、逐步求精的设计原则)。而两者之间的最大差别如下:
面向对象程序采用数据抽象和信息隐藏技术,使组成类的数据和操作不可分割,避免了结构式程序由于数据和过程分离引起的弊病。这正是面向对象设计方法和结构化程序设计方法的根本差异,也是面向对象设计方法的精华所在。
面向对象程序是由类定义、对象(类实例)和对象之间的动态联系组成的。而结构式程序是由结构化的数据、过程的定义以及调用过程处理相应的数据组成的。
本书主要讲解FORTRAN程序设计的基本方法,对于程序设计思想的方法只做一个简要的介绍,读者想要深入学习可以参考有关书籍。
3.2 算法的概念及特性
本节中我们对算法的基本概念和算法的特性进行详细的介绍,从而加深读者对算法的理解,为后面学习算法的表示方法打下基础。
3.2.1 算法的概念
正如我们做某一件事情需要按照一定的步骤进行一样,那么用计算机程序解决一个问题所采取的方法和步骤就是算法。算法是程序设计必不可少的部分,也是程序设计的核心内容,算法设计的好坏直接影响到程序的执行效率,并且不好的算法可能会导致问题求解失败。因此,本书将对程序算法做详细的介绍。
在数学和计算机科学之中,算法(Algorithm)为一个计算的具体步骤,常用于计算、数据处理和自动推理。算法应包含清晰定义的指令用于计算和解决问题。一个完整的算法能够对具有一定规范的输入,在有限时间内获得所要求的输出。如果一个算法有缺陷,或不适合于某个问题,执行这个算法将不会解决这个问题。不同的算法可能用不同的时间、空间或效率来完成同样的任务。
注意:“计算方法”(computational method)和“算法”(algorithm)是两个不同的概念。前者指的是求数值解的近似方法,后者是指解决问题的一步一步的过程。在解一个数值计算问题时,除了要选择合适的计算方法外,还要根据这个计算方法写出如何让计算机一步一步执行以求解的算法。
对于计算机外行来说,他们可以使用别人已设计好的现成算法,只需根据算法的要求给以必要的输入,就能得到输出的结果。对他们来说,算法如同一个“黑箱子”一样,他们可以不了解“黑箱子”中的结构,只是从外部特性上了解算法的作用,即可方便地使用算法。但对于程序设计人员来说,必须会设计算法,并且根据算法编写程序。
对同一个问题,可以有不同的解题方法和步骤。例如,求1+2+3+…+100,可以先进行1+2,再加3,再加4,一直加到100,也可采取100+(1+99)+(2+98)+…+(49+51)+50=100+50+49×100=5050,当然还可以有其他方法进行运算。不同的算法有质量优劣之分。有的方法只需进行很少的步骤,而有些方法则需要较多的步骤。一般来说,希望采用方法简单、运算步骤少的方法。因此,为了有效地进行解题,不仅需要保证算法正确,还要考虑算法的质量,选择合适的算法。
算法可以分为计算型算法和非计算型算法。
计算型算法的主要目的是解决某一数值问题,对问题求解出数值解,如求方程的根、计算函数的微分、计算圆形的面积、开平方等。非计算型算法的范围比较广泛,如各种人事管理系统、信息检索系统、语音识别系统等,但是其成熟度不如计算型算法高,这是因为计算型算法可以用现成的数值分析的方法进行程序的编写,写成函数库供不同的用户来调用,比如FORTRAN语言中的IMSL库就是很方便的数值计算库,这为用户的操作提供了极大的方便。
而非计算型算法的用户需要千差万别,想要完成某一具体任务需要重新设计方法并编写程序,所使用的算法各不相同,比如图书馆信息管理系统和行车高度系统需要相差极大,所以这也导致算法的开发各异,其成熟度不高。本书不可能将所有算法都罗列出来,只能通过一些典型算法的介绍,使读者对算法能够有一个较深入的理解和掌握,为将来设计算法、编写程序打下一个坚实的基础。
3.2.2 简单算法举例
在本节中,我们对一些简单算法进行举例说明,从而使读者对算法有一个深入的理解,请读者仔细阅读下面讲解的算法。
例3.1:求1×3×5×7×9×11。
用原始的方法进行求解的步骤如下:
1)求1×3得到结果3;
2)将得到的结果3乘以5,得到结果15;
3)将结果15乘以7,得到105;
4)将结果105乘以9,得到945;
5)将结果945乘以11,得到10395,这就是最终的结果。
从上述步骤我们可以看出,这种计算方法可以得到正确的结果,但是却比较麻烦。如果要求的是1×3×5×7×9×…×100,那么将导致计算非常繁琐。因此,我们需要对这种方法进行改进,得到一个通用的方法来进行计算。
可以如下考虑:因为乘法计算从第二步开始每一步都可以看成将上一步得到的新结果值与下一个数进行相乘,那么我们可设置两个变量,第一个变量存放上一步得到的结果(在乘法运算中被称为被乘数),第二个变量存放待乘的数(乘法运算中的乘数),经过不断的循环最终将结果计算出来。现设x为被乘数,y为乘数,将算法改写如下(其中,S代表Step,表示步骤的意思)。
S1:使x=1;
S2:使y=3;
S3:使x*y;将得到的结果存放到x中,可表示为:x*y→x;
S4:使y的值加2,即:y+2→y;
S5:如果y不大于11,则返回重新执行步骤S3及其后面的步骤S4、S5;如果y大于11则算法结束,最后得到的x值就是1×3×5×7×9×11的结果。
从上面的算法可以看出,改进之后的算法比较简洁,请读者仔细分析。
如果将题目的要求改为1+3+5+7+9+11,那么只需要进行少量的改动就可以实现问题的求解:
S1:使x=1;
S2:使y=3;
S3:x+y→x;
S4:y+2→y;
S5:如果y≤11,则继续,否则结束。
从上面可以看出,改进后的算法通用性和灵活性都要优于原来的算法。步骤S3到S5组成一个循环,这在计算机中是可以轻而易举地实现的,所有高级语言都有专门用于循环的语句,可以方便地实现此算法。
例3.2:对一个大于或等于3的正整数,判断它是不是一个素数。
所谓素数,是指除l和该数本身之外,不能被其他任何整数整除的数。例如,13是素数,因为它不能被2,3,4,…,12整除。
判断一个数n(n≥3)是否素数的方法是很简单的:将n作为被除数,将2到(n-1)各个整数轮流作为除数,如果都不能被整除,则n为素数。算法可以表示如下:
S1:输入N的值;
S2:i=2;
S3:N被i除;
S5:如果余数为0,表示N能被i整除,则打印“N不是素数”;算法结束;否则继续;
S6:i=i+1;
S7:如果i≤N-l,返回到S3;否则打印“N是素数”,然后结束。
实际上,n不必被2到(n-1)的整数除,只需被2~n/2间整数除即可,甚至只需被2~ 之间的整数除即可。例如,判断13是否素数,只需将13被2、3除即可,如都除不尽,n必为素数。因此,步骤S6可改为:
S6:如果I≤ ,返回S3;否则算法结束。
例3.3:输入两个数,求出其中最大值。
S1:输入第一个数,将其存入变量a;
S2:输入第二个数,将其存入变量b;
S3:如果a>b,输出“第一个数最大”;如果a<b,输出“第二个数最大”;如果a=b,输出“两个数一样大!”。
例3.4:求两个自然数的最大公约数,设两个变量为M和N。
S1:如果M<N,则交换M和N;
S2:M被N除,得到余数R;
S3:如果R=0,则N即为“最大公约数”,否则转到下一步;
S4:将N赋值给M,将R赋值给N,转到S1。
在这个算法中,要不断地进行循环和判断,当余数为0时,就求解出最大公约数。
例3.5:根据学生成绩的多少可分为不及格、及格、中等、良好和优秀5个等级。通常规定如下:
1)不及格:成绩小于60分;
2)及格:成绩大于等于60分小于70分;
3)中等:成绩大于等于70分小于80分;
4)良好:成绩大于等于80分小于90分;
5)优秀:成绩大于等于90分小于等于100分。
从键盘上接收一个成绩,输出成绩的级别。
求解的步骤如下:
S1:从键盘接收一个正实数r;
S2:若r<60,则输出“不及格”并转S7;
S3:若60≤r<70,则输出“及格”并转S7;
S4:若70≤r<80,则输出“中等”并转S7;
S5:若80≤r<90,则输出“良好”并转S7;
S6:若90≤r≤100,则输出“优秀”并转S7;
S7:算法结束。
说明:数据的合法性没考虑,实际应用中需对输入的数据进行合法性检查。
例3.6:写一个算法,输入北京市2012年9月中每天的气温,求出这个月的平均气温并输出。
依题意,先给出求解的步骤如下。
S1:定义一个30个元素的实型数组T,以及总的温度SumTemperature、平均温度AvgTemperature;
S2:借助循环,从键盘接收每天的气温;
S3:借助循环,统计这个月的温度总和;
S4:用温度总和SumTemperature除以30天,得该月的平均气温AvgTemperature;
S5:输出平均气温AvgTemperature;
S6:算法结束。
对S2:进一步细化为:
S21:循环变量初始化day=1;
S22:接收一个温度,并存入相应温度数组元素T[day]中;
S23:day=day+1;
S24:如果day≤30,则转S22;
S25:输入结束。
对S3进一步细化为:
S31:循环变量初始化day=1;
S32:从温度数组中读取T[day]元素,SumTemperature=Sun Temperature+T[day];
S33:day=day+1;
S34:如果day不大于30,则转S32;
S35:统计结束。
说明:数据的合法性没考虑,实际应用中需对输入的数据进行合法性检查。
例3.7:判断1900年~2000年中的每一年是否是闰年,将结果输出。
闰年的求解原则是:
1)能被4整除,但是不能被100整除的年份是闰年,如1964年、1980年、1988年等;
2)能够被100整除,又能被400整除的年份也是闰年,如1200年、2000年等。
该算法可表示如下:
首先用变量year表示所要检测的年份,步骤如下:
S1:1900->year;
S2:若year不能被4整除,就直接输出“不是闰年”,然后转到步骤S6;
S3:若year能被4整除,不能被100整除,则输出“是闰年”,然后转到步骤S6;
S4:若year能被100整除,又能被400整除,则输出“是闰年”,然后转到步骤S6;
S5:输出“不是闰年”;
S6:year+1->year;
S7:当year≤2000时,转S2继续执行,否则算法结束。
在此步骤中,我们进行了多次判断。首先判断year能否被4整除,如果不能的话,那么year肯定不是闰年。如果year能够被4整除,还要进行进一步判断,还要判断它能否被100整除,如果不能被100整除,那么肯定是闰年(比如1980年)。如能被100整除还不能完全判定是否是闰年,还要进一步被400整除,如果不能被400整除,则肯定不是闰年,如果能被400整除,则肯定是闰年。
在此算法中,每进行一步,判断范围就缩小了一些,直到执行到S5时,只可能出现“不是闰年”的情况,这时直接输出“不是闰年”即可。
我们在实际编程设计算法的过程中,要首先对题目的要求进行仔细的分析,判断题目都需要进行哪些判断、循环,如何一步一步地进行范围判定及数值计算。很多问题的解决都需要循序渐进,不断将判定条件缩小,直到最终求解出答案。
3.2.3 算法的特性
一般地,一个有效的算法应该有如下一些基本特征。
(1)有穷性
一个算法必须总是在执行有限步骤之后结束,即一个算法必须包含有限个操作步骤,而不是无限的。例如在例3.7中,如果将S7改成当year>0,那么循环将永远执行下去,永不终止,这个算法在实际中是无效的,也是没有任何实际意义的,因为程序无法结束,答案就永远不会计算出来。
另外,在实际设计算法中还要注意一点,那就是设计的算法不仅是有穷的,而且计算时间也要考虑一下。一般的有特殊要求的行业除外(进行有限元分析、液体力学的计算等),大部分的算法设计都要考虑计算时间的长短。如果一个算法是有穷的,但是需要计算100年,那么这个算法在实际中也是无意义的,这超出了一个合理的范围,因此不能算作一个有效的算法。
(2)确定性
算法中的每一个步骤应当是确定的,而不应当是含糊的、模棱两可的,即程序员在阅读算法时不产生二义性。在任何条件下,算法只有唯一的一条执行路径,即对于相同的输入只能得出相同的输出。
在编写程序中,程序员必须利用程序代码,清楚明确地告知计算机要做什么事情,就像在实际生活中,如果上级领导给下级人员下一个“购买书”的指令一样,那么下级人员并不能确定到底要买什么书、买多少本、从哪买之类的问题,这样必然会产生很多问题。计算机中的算法也同样如此,如果程序员不能在设计算法的时候确定一个明确的步骤,那么计算机是不能执行的。比如在例3.5中,如果我们不把所有的情况(如分数在不同的区间段的输出情况)都罗列清楚的话,当从键盘输入一个数据的时候,如果在没有给出确定的判断条件下,那么程序就会出错,算法无法向下进行,如图3-1所示。
(3)有零个或多个输入
所谓输入是指在执行算法时,从键盘或其他设备中获取的信息。一个有效的算法可以有多个输入,也可以没有输入。例如在例3.6中,我们就需要首先接收30个温度信息,这就是有多个输入的情况,如果不输入温度信息的话,后续的计算就无法进行。而在例3.5中,就只需要一个输入信息(学生的成绩)即可,只有按照程序的要求进行输入才可以得到正确的求解答案。
(4)有一个或多个输出
编程的目的是为了求解问题,“解”就是输出。一个算法可以有一个或多个输出,无输出的算法是没有意义的。例如在上面举的每一个例子中,我们都在有确定结果的情况下输出了一个结论,这样的程序才能真正解决问题。
注意:并不是用计算机打印的输出才算是真正的输出,一个算法得到的结果就是算法的输出。
(5)可行性
算法做的每一步都能有效地被执行,并且能得到确定的结果。比如在计算除法运算时,如果y=0,那么x/y是不能被有效执行的。
在实际应用中,我们编写算法的目的就是为了解决某个特定的问题,那么可以将设计好的算法进行封装,使之有必要的输入和输出即可。就如同一个黑匣子一样,使用人员不必要知道其内部的具体结构,只需要按照要求输入一定的数据,算法就会输出结果,如图3-2所示。
图3-2 求最小值算法
3.3 算法的表示方法
有效、简洁地描述一个计算机求解过程,称为算法的表示。为了表示一个算法,可以用不同的方法。常用的有:自然语言、传统流程图、结构化流程图、伪代码、PAD图等,这里我们对这几种表示方法进行详细的介绍。
3.3.1 用自然语言表示算法
自然语言描述就是用人们日常使用的语言,如汉语、英语或其他语言来描述算法。如前面3.2.2节中的所有例子就都是用自然语言来描述算法的求解过程的。用自然语言来描述和表示算法的优点是通俗易懂,缺点是文字过于冗长,容易出现歧义性。比如这句话“我们这个教室里有10个计算机学院的学生”,这句话既可以指教室里只有10个学生,也可以指教室里可能有很多个学生,其中计算机学院的学生有10个,此处使用自然语言就出现了语义的歧义。此外,用自然语言来表示算法还不能较好地表示循环和分支,使得算法描述起来很不方便,因此,除了简单的问题外,一般不用自然语言描述算法。
3.3.2 用流程图表示算法
用图表示的算法就是流程图。流程图是用一些图框来表示各种类型的操作,在框内写出各个步骤,然后用带箭头的线把它们连接起来,以表示执行的先后顺序。用图形表示算法,直观形象,易于理解。
美国国家标准化协会ANSI(American National Standard Institute)曾规定了一些常用的流程图符号,为世界各国程序工作者普遍采用,如图3-3所示。下面对图3-3中的各种图形的使用进行简要的说明。
1)处理框(矩形框),表示一般的处理功能。
2)判断框(菱形框),表示对一个给定的条件进行判断,根据给定的条件是否成立决定如何执行其后的操作。它有一个入口,两个出口。
3)输入输出框(平行四边形框),表示输入或输出操作。
4)起止框(圆弧形框),表示流程开始或结束。
5)连接点(圆圈),用于将画在不同地方的流程线连接起来。用连接点可以避免流程线的交叉或过长,使流程图清晰。
6)流程线(指向线),表示流程的路径和方向。
7)注释框,是为了对流程图中某些框的操作做必要的补充说明,以帮助阅读流程图的人更好地理解流程图的作用。它不是流程图中必要的部分,不反映流程和操作。
程序框图表示程序内各步骤的内容以及它们的关系和执行的顺序,它说明了程序的逻辑结构。框图应该足够详细,以便可以按照它顺利地写出程序,而不必在编写时临时构思,甚至出现逻辑错误。流程图不仅可以指导编写程序,而且可以在调试程序中用来检查程序的正确性。如果框图是正确的而结果不对,则按照框图逐步检查程序是很容易发现错误的。流程图还能作为程序说明书的一部分提供给别人,以便帮助别人理解程序员编写程序的思路和结构。
下面我们将3.2.2节讲的例子用流程图重新表示一下,以帮助读者清楚地理解流程图的用法。
例3.8:将例3.1中求1×3×5×7×9×11的算法用流程图表示,如图3-4所示。
例3.9:将例3.2中的算法用流程图表示,如图3-5所示。
例3.10:将例3.3中求两个数最大值的算法用流程图表示,如图3-6所示。
例3.11:将例3.4中求两个数的最大公约数的算法用流程图表示,如图3-7所示。
图3-4 例3.8流程图图3-5 例3.9流程图
图3-6 例3.10流程图图3-7 例3.11流程图
例3.12:将例3.5中的算法用流程图表示,如图3-8所示。
例3.13:将例3.6中求2012年9月平均气温的算法用流程图表示,如图3-9所示。
图3-8 例3.12流程图 图3-9 例3.13流程图
例3.14:将例3.7中判定闰年的算法用流程图表示,如图3-10所示。
通过以上几个例子我们可以看出,用流程图表示算法是一种很方便的工具。下面我们对流程图的用法进行一下简要的总结。
一个流程图必须包括如下几个部分:
1)表示不同操作的框,如处理框、判断框等。
2)带箭头的流程线,这一点尤其重要,因为箭头线表示程序的执行过程,如果没有画出的话,那么很难判断程序如何执行。
3)框内外的文字、符号说明,这样将使程序更直观易懂。
4)开始和结束框,如果没有这两个框的话,无法确定程序从哪里开始及结束。
用流程图表示程序算法直观形象、易于理解,能够清楚地表达各个步骤之间的逻辑关系,因此,在很多书籍和论文中得到了广泛的应用。但是利用流程图也有其相应的缺点及不足之处,即占用篇幅较多,画流程图费时费力等。那么为了解决这个问题,改进之后的N-S流程图逐渐取代了传统的流程图,N-S流程图也得到了更广泛的应用。但是,作为一个合格的计算机程序员,请读者一定要掌握这种传统流程图的表示方法,做到会看会用,这样可以看懂别人画的程序,同时也能具备画传统流程图的能力。