1、第3章 编程语言与数据表达语言是人类区别于动物的重要标识目录 3.1汇编语言汇编语言 3.2高级语言高级语言 3.3高级语言的高级语言的特征特征 3.4基本数据类型与变量基本数据类型与变量运算运算 3.5浮点数浮点数 3.6扩展的扩展的数据结构数据结构 3.7编程语言的可靠与编程语言的可靠与安全安全3.1汇编语言汇编语言 3.1.1 用机器指令编程的用机器指令编程的困扰困扰 3.1.2 汇编语言和编程汇编语言和编程3.1.1 用机器指令编程的困扰用机器指令编程的困扰3.1.1 用机器指令编程的用机器指令编程的困扰困扰 用机器指令构造出的程序,对计算机来讲是直接的:计算机可以直接一条条第解释指令
2、和执行指令,直到所有的指令执行完毕,或按要求停机。计算机的运行效率自然很高。然而,设想一下,如果个计算算法很复杂,需要许多人编写机器指令,并合成后才能完成计算任务。那么,用机器指令就会导致许多问题:1)写程序的程序员对二进制方式的指令代码难以记忆和查错;2)如何把多人写的多个指令集合合到一起;3)如果某人的写的程序中,需要读取其他人程序中的(中间或最后的)计算结果,如何办?4)等等。这些问题,对于写更大的程序是严重的障碍。3.1.2 汇编语言和编程 首先,要设计一个帮助程序员进行记忆的符号,简称为助记符(Mnemonics),例如,指令(00001010)的助记符是LOAD MQ,其意思与该二
3、进制代码是一样的,即,“把寄存器MQ的内容传递到累加器AC中”。其次,要有一个汇编器,能实现从助记符到二进制代码的转换,称为汇编器(Assembler),汇编器的命令格式一般是:ASM 待转换的程序名 第三,建立主程序和子程序的概念。一个子程序是指该程序完成特定的功能后,并不停机,而是计算的结果放到特定位置后,把指令计数器转给调用该子程序的主程序。主程序的目的主要是控制各个子程序的执行,并对子程序的结果进行再处理。一个汇编子程序的例子实现把寄存器AL中存放的字符变大写AL=aAL=AL-20RETOVER:AL=z小于大于PROCCMP AL,a ;把寄存器AL中的值与a的;ASCII码对比J
4、B OVER ;如果小于,跳转到地址OVERCMP AL,z.;把寄存器AL中的值与z的;ASCII码对比JA OVER ;如果大于,跳转到地址OVERSUB AL,20H ;AL减去20后,放回ALOVER:RET ;返回到调用该子程序的程序注释:;后面的是对代码的注释,说明,机器不翻译AL是机器的寄存器。CMP是比较指令SUB 是减法指令(a)汇编语言的子程序(b)子程序算法汇编语言指令与机器指令一一对应1.助记符;2.多了说明性指令,例如,BGN,End 第四,建立程序库,让子程序可以被其他人复用。如果张三编写了一个子程序,其他人只需要调用他的程序,而不在需要自己编写了。为此,张三要给自
5、己的工作建立一个库,在这个库里放置很多个子程序,例如,一个数学函数库,期末要包括:sin(x)、cos(x)、tan(x)、log(x)、sqrt(x)、exp(x)等等。级数展开是实现这些函数基本方法。因此,我们需要一个建库的工具,版把这些函数的汇编编译成机器代码后,放置到库里。等待其他程序员使用。常用的命令形式是:Lib a1.obj+a2.obj+a3.obj+an.obj 其中,q1.obj 是一个或多个子程序的名称,是最终建立的库的名称,例如,微软公司的math.lib,其中,包括了常用的数学函数。第五,装配程序,或称为链接程序。常用的命令像LINK。例如,LINK main.obj
6、 subpro.obj math.lib stdio.lib 其结果为:main.exe 在集成开发环境下,Build命令可以完成上述15的工作,但是你必须先建立一个项目。第六,装载程序:将main.exe加载到内存,交给CPU运行。在Windows操作系统下,双击main.exe就行目录 3.1汇编语言汇编语言 3.2高级语言高级语言 3.3高级语言的高级语言的特征特征 3.4基本数据类型与变量基本数据类型与变量运算运算 3.5浮点数浮点数 3.6扩展的扩展的数据结构数据结构 3.7编程语言的可靠与编程语言的可靠与安全安全3.2高级语言高级语言 3.2.1高级编程语言简史 3.2.2高级语言
7、的执行 3.2.3高级语言分类3.2.1高级编程语言简史 第一个高级编程语言出现在1950年代。1952年,英国曼彻斯特大学在MARK 1上开发了第一个编译器,将高级语言转为二进制机器语言。1951年:美国IBM公司约翰贝克斯(John Backus)针对汇编语言的缺点着手研究开发FORTRAN(Formula Translation)语言,其含义为公式翻译器。FORTRAN非常适合于工程师们把数学公式直接写成代码。FORTRAN Fortran(Formula Translation)广泛应用于科学和工程计算领域 1954年:约翰贝克斯在纽约正式对外发布,称为FORTRAN。FORTRAN
8、功能简单,但它的开创性工作,在社会上引起了极大的反响。1957年:第一个FORTRAN编译器在IBM704计算机上实现,并首次成功运行了FORTRAN程序。1958年:对FORTRAN 进行了扩充和完善,引进了子函数等概念,推出了商业化的FORTRAN 版本。1962年:推出了FORTRAN。COBOL 在企业信息管理中,数值计算并不复杂,但数据处理信息量却很大。COBOL(Common Business Oriented Language)是第一个广泛使用的数据处理的高级编程语言。五角大楼委托G.Hopper博士领导一个委员会并由Rear Admiral Grace Hopper公司主持开发
9、,1961年美国数据系统语言协会公布。与FORTRAN对比,COBOL的数值运算、逻辑运算能力比较弱。COBOL适合于具有循环处理周期的环境(例如打印工资支票)以及数据操纵量相当大的环境。COBOL COBOL(Common Business Oriented Language)是第一个广泛使用的数据处理的高级编程语言。对比C或FORTRAN,COBOL的数值运算、逻辑运算能力比较弱。COBOL适合于具有循环处理周期的环境(例如打印工资支票)以及数据操纵量相当大的环境。COBOL主要应用于商业数据处理领域,对各种类型的数据进行收集、存储、传送、分类、排序、计算及打印报表、输出图象是它的强项。C
10、OBOL语法与英文很接近,即使不懂电脑的人也能看懂程序 银行的票据等处理非常需要COBOL编程ALGOL、Pascal、Delphi 19601970年代,出现了多种编程语言,例如,APL 语言引入数组编程和函数编程。ALGOL 实现结构化过程编程(structured procedural programming);Pascal语言是Niklaus Wirth于19681969年期间设计的,发表于1970年。其名称用来纪念法国数学家和哲学家Blaise Pascal。1985年,基于Pascal语言开发了面向对象的Delphi。C languageC 是Dennis Ritchie于 196
11、9 1973年在 Bell Labs开发的,目的是重写Unix操作系统。C 是通用目的、imperative(命令式)语言,支持结构化编程、递归调用,具有静态类型预防未定义的操作。C的语句能够高效地映射到机器指令,因此,适用于编写操作系统这样的系统软件,也适合于编写各种应用,从超级计算机到嵌入式系统。C是最广泛使用的语言中,许多就是计算机结构设计和操作系统厂商都提供C编译器。1989年,ANSI(American National Standards Institute)发布C标准,后来,ISO组织也采纳其标准。Ken Thompson(left,Unix发明者)with Dennis Rit
12、chie(right,the inventor of the C programming language),两人获1983年图灵奖K&R C Programming LanguageC语言 不同于ALGOL等,C语言强调的其编译和运行效率,接近汇编语言。虽然C语言是编写计算机系统程序而发明的,但是,因为其强大的能力,也被编写应用程序的人接受。C基本上是各大学计算机、软件专业和相关专业的必修课程。C 的例子类与对象的引入 1979年,丹麦的计算机学者Bjarne Stroustrup开始在C语言中增添类(Class)的概念,目的是创立新语言,以便完成自己的博士论文。他研究了Simula语言的特
13、征,发现其中的对象概念有助于提高编程效率,但是,Simula运行效率太低。后来,Stroustrup到AT&T Bell Labs工作,分析UNIX 内核对分布式计算问题。回顾自己做博士论文的经验,触发他在C语言上增加Simula的对象特征。开始,只是在C编译器中,增加了类(Classes)、派生类(derived classes)、强类型(strong typing)、直接插入(inlining)和省缺变量等概念。1985年出版了C+语言,由Bjarne Stroustrup创立。1998年正式成为国际标准(ISO/IEC 14882:1998)。函数演算与逻辑编程语言 Lisp,创立于 1
14、958年,目的是为了方便于用Alonzo Church的 lambda演算的数学表达。lambda演算是与图灵机基本等价的理论计算机模型演算是与图灵机基本等价的理论计算机模型。Lisp出现后,很快成为人工智能(AI)研究领域(符号演算)的应用语言。Lisp语言是第一个实现函数演算方式的编程语言。1972年,出现Prolog,是第一个逻辑编程语言。与其它语言不同,Prolog的基础是一阶逻辑或形式逻辑,因此,被广泛用于理论证明、专家系统、自动规划、自然语言理解等领域的编程。Perl和Python 1990年中期后,互联网迅速发展,促进了新语言的发展。早期的一些脚本语言,例如,Perl语言(198
15、7年推出的Unix上的脚本工具,转变为动态网站(WebSite)的通用语言。Python(美国发音:/pan/)由荷兰人Guido van Rossum于1989年发明,是一种面向对象的解释型程序设计语言,第一个公开发行版发行于1991年。现在,也被逐渐广泛应用于系统管理任务的处理和Web编程。Python是完全面向对象的语言。函数、模块、数字、字符串都是对象。并且完全支持继承、重载、派生、多继承,有益于增强源代码的复用性。Python支持重载运算符和动态类型。执行 Python在执行时,首先会将.py文件中的源代码编译成Python的byte code(字节码),然后再由Python Vir
16、tual Machine(Python虚拟机)来执行这些编译好的byte code。这种机制的基本思想跟Java或.NET是一致的。JavaSun Microsystems于1996年发布 Java 1.0 开始是为数字电视机顶盒制定的语言,便于机顶盒的软件升级 提出的目标是:编写编写一次,到处运行一次,到处运行(Write Once,Run Anywhere-WORA),勉去代码跨越平台的移植工作,对此,需要定义Java虚拟机。如果硬件平台或操作系统上支持了Java虚拟机,那么,就可以直接运行用Java编写的应用程序。Java后来又分为J2EE平台、J2ME和J2SE。J2EE提供企业应用的
17、API和服务器运行环境,J2ME针对应用设备,J2SE针对台式机(PC台)。2006年后改名为:Java EE、Java ME和Java SE。第三学期学习Java 程序设计,第四学期做Java实践C#C#是微软公司的一种面向对象的、运行于.NET Framework上的高级程序语言。C#与Java非常的相似;它包括了诸如单一继承、接口、与Java几乎同样的语法和编译成中间代码再运行的过程。但是C#与Java有着明显的不同,它借鉴了Delphi的一个特点,与COM(组件对象模型)是直接集成的,而且它是微软公司.NET windows网络框架的主角。第四代编程语言 习惯上,人们把机器语言称为第一
18、代编程语言,汇编语言称为第二代编程语言,而(上面的)高级编程语言称为第三代编程语言。那么,第四代语言就应当是为应用领域程序员创立的编程语言。包括:数据库管系统的语言,例如SQL;报表或报告生产器;数学工具,MATLAB、Mathematica等;GUI的开发工具、Web页面的HTML等。第四代语言(4GL)与第三代语言对比,第四代语言(4GL)的目的是让编程者更远离计算机结构和硬件细节。4GL was first used formally by James Martin in his 1981 book Applications Development Without Programmers
19、 to refer to non-procedural,high-level specification languages.Languages claimed to be 4GL may include support for database management,report generation,mathematical optimization,GUI development,or web development.Some researchers state that 4GLs are a subset of domain-specific languages.第五代编程语言 第五代
20、语言(5GL)应当是,能够让程序员定义解决问题约束条件,而要降低让程序员用语言写算法的工作量 能否让非计算机和软件专业的、具有应用领域知识的人,直接编写他们所期望的程序,而不是用传统意义上的C/C+,JAVA等。5GL到底是个啥?仍不清楚。编程语言仍需要不断进化和创新,工业界和学术界仍在做工作。当前的方向包括:security and reliability verification,new kinds of modularity(mixins(混合),delegates(表达),aspects(某方面),and database integration such as Microsofts
21、LINQ.3.2高级语言高级语言 3.2.1高级编程语言简史 3.2.2高级语言的执行 3.2.3高级语言分类3.2.2高级语言高级语言执行执行 计算机是不能执行高级语言的,一般有两种方式解决高级语言的运行:1)编译方式(compilation):用编译器把高级语言编译为机器可执行的二进制代码,然后,组装成可执行的文件。2)解释方式(interpretation):用一个解释器逐条解释高级语言的每条语句,例如,BASIC语言。另外就是,把高级语言的代码编译为虚拟的指令格式,而不是(硬件)机器语言的指令,如,Java虚拟机(JVM-Java Virtual Machine)用字节码(byteco
22、de)的形式表达虚拟指令。当然这种方式会导致执行速度慢,但是,可以更好地做到“编写一次,到处运行”,只要该平台上有虚拟机。3.2.3高级语言分类高级语言分类 依据HOPL(online database of languages),有 8500多种 编程语言,有2400种是美国开发的,英国600多,加拿大160,澳大利亚75种语言。常用的编程语言并不多。经常,我们会说哪个语言是哪种类型的。而实际上,很难划分清楚。因为高级语言的设计者会综合考虑问题。一般会考虑到:应用领域、实现方式、语言特征等。按用途分,可以分为:通用目的,系统编程语言(system programming languages)
23、、脚本(scripting)、领域特定语言、并行/分布式语言(concurrent/distributed languages)等 从计算的描述上看,分为命令式(Imperative),例如,C语言;以及说明式或声明式(declarative)编程语言,例如,数据库管理中的结构化查询语言SQL。从编程方法的角度出发,一般分为:过程型(procedural)、面向对象(object-oriented)、函数式(functional)、逻辑式(logic)编程语言等。常用编程语言类型语言应用用途计算的描述编程方法FROTRAN 科学计算并行FRORAN支持并行计算命令式过程型C系统编程系统编程命令
24、式过程型C+系统编程系统或应用软件编程命令式面向对象COBOL商业信息处理商业命令式过程型Java商业应用信息管理命令式面向对象C#商业应用信息管理命令式面向对象LISP数学应用函数式演算命令式函数式Prolog数学数学逻辑演算命令式逻辑式Perl脚本脚本命令式过程型Python脚本脚本命令式面向对象SQL结构化数据访问数据库管理声明式 目录 3.1汇编语言汇编语言 3.2高级语言高级语言 3.3高级语言的特征高级语言的特征 3.4基本数据类型与变量基本数据类型与变量运算运算 3.5浮点数浮点数 3.6扩展的扩展的数据结构数据结构 3.7编程语言的可靠与编程语言的可靠与安全安全3.3高级语言的
25、基本高级语言的基本特征特征 3.3.1词法和与语法 3.3.2语法与语义 3.3.3语句 3.3.4变量类型定义与运算3.3.1词法和与语法 大多数高级语言用文本形式表达。有几类文本词:1)保留字(reserved word):这是语言本身保留的,具有特定的含义。程序员在编写程序时,不允许使用这些字作为变量名。例如,C语言的for,float等。2)数字(numbers),可以是10进制的0.9,或十六进制的0.9.A.F,组成数据表达。3)标点符号(Punctuation):每种高级语言会定义一下标点符号的含义,例如,C语言中的“;”表示一个语句的结束,而FORTRAN语言以行(回车或换行)
26、做为语句单位。注意,在ASCII中,回车,换行是两个编码 在定义一个语言时,会用正则表达式(regular expressions)表达词法(lexical),用巴克斯范式(Naur form)表达句法(grammatical)结构。例如,下面是Lisp语言的表达式的定义:expression:=atom|list atom :=number|symbol number :=+-?0-9+symbol :=A-Za-z.*list :=(expression*)例子,12345,(),(a+b-c232(1).3.3.2语法与语义 虽然高级编程语言的词法采用英文词,但是仅仅把词按语法拼在一起可
27、能没有任何意义(语义)。编程语言是不允许有二义性的。而自然语言常常是有二义性的,例如“开刀的是他的父亲”到底是谁动的刀谁被开的刀!自然语言中,听者可以根据该句话的前言后语,推断出结论。编程语言的文法必须是形式化的,不能有任何二义性,程序员容易读懂,还要能容易地转换(或翻译)为机器的指令。编程语言的形式化文法 Chomsky将编程语言的形式化文法划分为四类:0型文法、1、2、3型文法。0型最强,是短语结构文法,与图灵机相当,可以抽象地描述冯诺伊曼机;1型是上下文有关文法,相当于线性有限自动机 2型是上下文无关文法,是下推自动机,是目前高级编程语言语法描述的主要文法 3型是正规文法,相当于有限状态
28、自动机。能力较弱,只能描述词法 目前,大多数高级编程语言采用上下文无关的(context-free)文法,对应于Chomsky定义的2型文法。高级编程语言的编译过程,是将程序员能读懂和表达的2型文法转换为冯诺依曼机能够正确执行的0型文法。静态语义 只有语法是不够的,语义是一个代码语句或结构的真实含义。又分为静态语义和动态语义。静态语义:对于编译型语言,在编译时进行语义规则检查,例如,检查每个标识符使用前是否声明?检查Switch语句的case分支是否明确区分开了。针对上下文,做(变量和表达式的)类型检查;检查函数名不能是纯整数,子程序中的每个参数是否与调用的一样。或者,做数据流(data-fl
29、ow)分析,看某个变量是否会永远也用不到。在Java和 C#语言中,还做赋值语句的类型分析。动态语义 一旦数据被说明,机器按指令对数据执行操作。只有执行时,才可能知道,例如,语义定义了表达式如何被计算,或控制结构按条件执行某语句,是否会出现除零错误等。这类语义称为动态语义或执行语义表明语言的各种构件的运行时的行为。针对动态语义的检查时是否重要的,例如,飞机上控制程序是否会出现除零错、数组下标是否会越界,在高可靠系统中避免出现灾难;以及,在网路系统中判断外来的数据是否网络病毒攻击性的指令等安全问题。3.3.3语句 一个高级语言中至少包括变量的说明或定义,以及多种可执行的语句类型。对于过程型的语言
30、,例如,C语言等,一般由三类语句。赋值语句;循环语句 条件判断语句 赋值语句的左边是接受赋值的变量 中间一般“=”,例如,C语言;而Pascal语言中用“:=”。右边是计算的表达式。表达式的运算符号一般由算术型的:+、-、*、/(加减乘除),逻辑运算的“与或非(&,|,)”等。循环语句分为:固定次数的循环,例如,C语言的for语句;判断条件在前的循环语句,例如,While(条件)循环,或判断条件在后的Until(条件)语句。条件判断语句,其结构分为:单分支的判断,例如,C语言的if(条件)语句块 两分支的判断,例如,C语言的if(条件)语句块1 else 语句块2 以及,多分支的判断,例如,C
31、语言中的Switch(条件)Case条件1 语句块1 ;Case条件2 语句块2 ;.Case条件n 语句块n ;Statements(语句)赋值,例如,A=5.5;MyBUPT=Myname+“in Beijing University of Posts and Telecomm.”;判断语句:If(Myname=Wang)then 循环语句:For(I=1,100,2)Goto 语句目录 3.1汇编语言汇编语言 3.2高级语言高级语言 3.3高级语言的特征高级语言的特征 3.4基本数据类型与变量运算基本数据类型与变量运算 3.5浮点数浮点数 3.6扩展的扩展的数据结构数据结构 3.7编程语
32、言的可靠与编程语言的可靠与安全安全3.4基本数据类型与变量运算基本数据类型与变量运算 3.4.1 数值数值型型 3.4.2 逻辑逻辑型型 3.4.3 枚举枚举量量 3.4.4 字符与字符与字符串字符串 3.4.5 指针指针运算运算 3.4.6 不同类型变量之间的不同类型变量之间的运算运算3.4.1 数值数值型型 算术运算仅有整数是不够的,也需要表达定点数和浮点数。整型数、定点数和浮点数一起称为数值型。定点数也称为定点实型数。定点实型是指小数点前和后的位数是固定的。浮点数的表达要麻烦一些,见3.5节。两个整型的运算结果仍然是整型。一个整型与一个浮点数的运算时,一般先转换为浮点数后,才进行运算。如
33、果运算结果要放回到整型变量中,就必须再转换为整型,即,截掉小数部分。截掉小数部分的原则可以自己定义,例如,直接截掉,或向上靠近(参见3.5.2节)。3.4.2 逻辑逻辑型型 一般来讲,用一个字节或16位的二进制数表达逻辑逻辑变量,全零代表“假”,非零表达“真”。多个逻辑变量可以进行逻辑运算,参见1.6节,结果仍是逻辑变量。逻辑运算一般用于判断语句或循环语句的条件部分。需要注意的是,在恶劣环境下,例如高电磁辐射、外空间的太阳黑子的干扰下,计算机内存代表0和1的位会发生反转。如果“全零代表假,反之为真”是很危险的,只要有1位发生反转,含义就不对了。对此,可规定“全0为假,全1为真,其它状态不定”。
34、3.4.3 枚举枚举量量 枚举量是一个或多个元素的集合体。例如,只有三种颜色的枚举量类型定义为:Enum Color Red,Blue,Yellow;那么,变量Color就只有三个值:Red,Blue,Yellow。枚举量运算包括:1)判断一个枚举量是否属于这个集合;例如,可以判断一个变量的值是否属于Color中的值。2)比较两个枚举变量是否相等。例如,如果两个变量都是Color类型的,就可以比较是否相等。3.4.4 字符与字符与字符串字符串 计算机中以7位二进制数代表一个字符,字符集合起码包括英文字母、常用的算术符号、标点符号、以及其控制作用的不可见字符。ASCII码表就是这种字符的一种集合
35、(参见表5-2)。若干个字符按顺序放在一起,称为字符串。字符是长度为1的字符串。运算:单个字符串变量的运算,包括:求长度,判断字符串是否为空。两个字符串变量可以做比较运算,判断是否相等。两个字符串变量可以做加法运算,结果是前一个变量的值后面拼接上后一个变量的值。大部分的编程语言会给出上面几个基本运算。更复杂的一点的运算,往往需要编写相应的程序:两个字符串变量可以做减法运算,结果是从前一个变量中删除与后一个变量相同的字符串。两个字符串变量可以做子集运算,即,查询前一个变量是否包含后一个变量,以及含有多少个。例如,字处理软件中的查询 三个字符串变量可以做替换运算,即,先查找第一个变量是否含有第二个
36、变量,然后,(全部)替换为第三个变量的值。例如,字处理软件中的替换3.4.5 指针指针运算运算 指针指向一个变量(内存空间)的地址。指针就是地址,地址就是内存单元的编号。指针变量的范围是内存的非零地址和最大地址。指针变量的运算,自然就是地址的运算,以从地址中存取其内容(数据)。3.4.5 指针指针运算运算 指针指针变量加变量加/减一个整数:减一个整数:如果,p是指针变量,那么,p+,表示指针加1,即,指向下一个地址。同样,p-,表示指针减1,即,指向上一个地址。p+i,这里i是一个整数。即,从当前地址,再向下面数i个内存单元的地址。指针变量赋值:指针变量赋值:可以将一个变量或一个函数的入口地址
37、赋值给相应的指针变量。例如,假设p是指针变量,那么,p=&a;(a是一个整型变量,p是其存储地址)p,q是两个指针变量,则可以有p=q;指针指针变量相减变量相减:如果两个指针变量指向同一个数组的元素,则两个指针变量之差是两个指针之间的元素个数。注意,指针变量相加无实际意义。指针变量比较指针变量比较:如果两个指针变量指向同一个类型数据的元素,则可以进行比较。指向前面元素的指针变量小于指向后面元素的指针变量。指针变量的定义或指针变量的定义或声明声明 指针指针变量的定义或变量的定义或声明声明 变量都是需要定义的,指针变量也需要定义,且要区别于其它变量的定义。例如,在C语言中,定义一个指针变量,表达为
38、:int *p;表示p是一个指向整型数的指针变量。而一个整型变量的定义是:int q;表示q是一个整型变量3.4.6 不同类型变量之间的不同类型变量之间的运算运算 变量类型变量类型变量类型变量类型整型整型实型实型字符字符字符串字符串逻辑型逻辑型枚举枚举指针指针整型整型整型实型*指针实型实型实型实型 字符字符 字符字符串 字符串字符串*字符串字符串字符串 逻辑型逻辑型 字符串逻辑型枚举 枚举枚举 枚举枚举 指针指针指针 指针*有些编译器,在字符串与数字有些编译器,在字符串与数字(整型或实型整型或实型)运算时,会先把数字转换为字符串,然后运算时,会先把数字转换为字符串,然后运算,但是如果做除法和乘
39、法就变的无意义了。运算,但是如果做除法和乘法就变的无意义了。运算符 算术运算:+,-,*,/(加、减、乘、除)简单数据(整型、浮点、字符串)运算符:+,-,*,/复杂数据(数组、结构)运算,一般要自己写。有些语言也提供,例如,并行FORTRAN语言 逻辑运算符:与、或、非(&,|,)判断运算符:大于、小于、大于等于、小于等于、等于、不等于(,=,=x NaN x NaN=x NaN x 结果结果 总是 False 总是 False 总是 False 总是 False 总是 False 总是 True 第三类正负无穷大(小)的判断问题NaN并一定不代表这个数不是数,只是说明该数处于危险之中,接着
40、计算就很容易发生问题。对此,IEEE-754做进一步的区分,区分为:qNaN(quite NaN)和sNaN(signaling NaN)IEEE-754中用小数部分的最高位进行区分,如果是中用小数部分的最高位进行区分,如果是1,则该数是,则该数是qNaN,否则是,否则是sNaN。qNaN:不会立刻引起计算机异常,是为了计算留出余量。但又不能忽略,否则输出的数据没有意义。因此,当判断出qNaN发生时,也不能再计算了。sNaN:是NaN的特殊形态,即使对qNaN情况都做了处理。出现sNaN的情况的例子有:用sNaN数填充未初始化的内存,将会产生非法的运行异常,如果变量在初始化前就使用数据可以把s
41、NaN作为更复杂数据项的符号,用于表达,例如,1)具有下溢出的数,具有上溢出的数;2)企图表达的更高精度的数;3)复数情况。这样,在运算时,可以判断各种情况,并给出相应的处理,例如,程序直接给出非数参与运算的结果,而不做计算。3.5.3 IEEE754浮点数的范围浮点数的范围IEEE754给出了5种浮点数的格式,三个是二进制(32,64,128位)和两个十进制的(64位和128位)的编码格式。代号代号名称名称基基有效有效位位十进制十进制指数指数位位十进制十进制E max指数偏指数偏E minE maxbinary16半精度2113.3154.51 241=1514+15binary32单精度2
42、247.22838.23 271=127126+127binary64双精度25315.9511307.95 2101=10231022+1023binary128四精度211334.0215 4931.77 2141=1638316382+16383binary256八精度223771.3419 78913.2 2181=262143262142+262143decimal3210777.5896 10195+96decimal641016169.58384 398383+384decimal128103434 13.586144 61766143+6144例如,单精度数的最大值一般仅为10
43、38,而不是1038.23 在设计高级语言时,要提供判断运算结果是否一个非数的支持。否则,就会引起后续严重的错误。数据舍入问题,虽然不会产生大的安全问题,但是对于会影响计算的精度,例如,像银行、财务等计算中,会导致资金产生很大的误差。目录 3.1汇编语言汇编语言 3.2高级语言高级语言 3.3高级语言的特征高级语言的特征 3.4基本数据类型与变量运算基本数据类型与变量运算 3.5浮点数浮点数 3.6扩展的数据结构扩展的数据结构 3.7编程语言的可靠与编程语言的可靠与安全安全3.6扩展的扩展的数据类型与结构数据类型与结构 3.6.1 数组数组 3.6.2 结构体结构体 3.6.3 链表链表 3.
44、6.4 栈与栈与队列队列 3.6.5 树树 3.6.6 图图 3.6.7 对象与对象与OO语言语言3.6.1 数组数组 把多个同样类型的数据当做一个整体变量看待,称为数组。一个数组有多个元素。每个元素用下标区分。一个维度的数组的每个元素下标是一个变量,例如,定义一个整型的a1:50,表示有50个元素整型变量,分别是a1,a2,ai,a50。二维数组的每个元素有两个下标,例如,a1:501:30,有5030=1500个元素,可以代表1500个变量,分别为:a1,1,a2,1,ai,1,a50,1,a1,2,a2,2,ai,2,a50,2,ai,j,a50,30。二维数组也称为行列式。当然,也可以
45、表达N维数组。例如,三维数组a中的一个元素是ai,j,k。数组的运算 一个数组的运算,起码包括求元素的个数、所有元素的总和,每个维度(对于二维数组就是行和列)的总和。两个数组之间的运算,如果结构类型一样,可以做加法和减法,定义为相对应的单元的加减。如果不一样,无法进行加减运算。两个数组之间也可以进行乘法和除法运算,如果数组元素都是数值的话。许多高级语言中,允许数组元素是一个结构体(见3.6.2节),这种情况下,做乘除法可能会没有意义。一般高级语言中,只定义数组类型,不直接定义数组的运算。需要开发者自己定义,并编写相应的程序3.6.2 结构体结构体一个结构体是多个变量类型的组合。一个结构体中的每
46、个元素的类型可以是不同的。C语言中用Struct,Pascal语言中用Record作为保留字,例如:Typedef Struct HumanResource /*Typedef Struct是保留字,HumanResource是变量类型*/Char:Name1.8;/*姓名 */Int:age;/*年龄*/Float:Wage_month;/*月工资*/Worker,Boss;一个结构体变量自身的运算起码包括求该结构体的长度。同一个类型的结构体的两个变量,可以进行运算,解释为相对应的元素之间的直接运算。一般的高级语言不直接给出结构体之间的运算,需要程序员自己编写。3.6.3 链表链表 二维或多
47、维数组都可以看做是一维数组,只要按严格的顺序排列。如果删除数组中一行或一列或一个元素,或在某个元素前插入一个元素的话,所花费的时间太长,因为,必须移动后面的元素。对此,人们发明了链表。链表由若干个在计算机内存中不连续存放的数据结点组成。数据结点有两部分组成:一个数据区和一个指针(即内存地址编号)。链表的操作和运算A地址(a)带指针的结构体A18101000A2700810A3550700A4550A18101000A2700810A3550700A4550(b)带指针的单向链表(c)删除一个结点A18101000A2200810A3550700A4550(d)插入一个结点X700200数据区
48、指针(d)插入一个结点3.6.4 栈与栈与队列队列 设想一个一维数组或单项链表,只允许取走(删除)最后一个元素,或最后一个元素后添加一个元素。可以看出,先添加的元素要比后添加的元素后被删除。称为后出先进(LIFO,Last In First Out)。这种数据结构称为栈。现实世界中的仓库货物存取就是这样的。栈有三个运算:从栈中取走一个结点(取走意味着读取该内容X,并把内容从栈里删除),称为出栈,记为:X=Pop(S);向栈里压(添加)一个数据X),称为压栈,记为 Push(S,X)另一个是Top(S),得到栈的顶部地址,其中,S表示栈。队列 与栈相反,规定只能从一个数组或单向链表的第一个元素前
49、头插入数据单元,且只能从数组的尾取走(删除)一个数据,称为先进先出(FIFFO,First In First Out)。这种数据结构称为队列。用队列可以表达许多任务的排队问题,就像下课后到学生食堂吃饭,先来的学生先得到服务。在编程中,往往会有多个程序向某个服务程序请求(计算)服务,那么,就需要用队列安排服务程序的工作次序。3.6.5 树树 一棵树可以是一个空集合,若非空,则,树有一个根(root)结点r,以及0个或n个非空的(子)树T1,T2,,Tk组成。这些子树的中的根都被来自根r的一条有向边(edge)连接起来。子树T1rt0t0,1t0,ntkt1,1t1,n子树Tk 可以用树表示一个表
50、达式,例如,叶结点是计算的数,中间结点是计算符(例如,加减乘除等),也可以用树表达一个磁盘文件中的各种目录和文件,等等。树的运算 对于树,经常做的运算是树的遍历,即走完每个结点。可以深度优先,即走完每个子树的叶结点后再到另一个子树;或宽度优先,先遍历离根结点最近的所有结点,再向下搜索下一层的结点,等等。树的遍历是一个搜索问题尽快找到所需要的结点。例如,结点中可以存放下一步棋向哪走的数据,计算机下棋程序的关键之一就是数的搜索问题快速找到下一步棋的结点。为了加快搜索速度,可以创造出各种树。例如。如果每个结点不能有多于两个子结点,称为二叉树。3.6.6 图图一个图(Graph)G=(V,E)由顶点(