Java中怎么求相邻数教案递减的数的和?

一.初识高速缓存和连接池 & 设想这样一种情形:你突然口渴,需要一杯水来缓解,从心情上来讲,当然是越快越好 了。通常,一杯水的产生包括从水源(井水、河水或江水、甚至海水等)抽取,通过管 道传输和设备净化,才到达你饮水的容器中。上述过程是必须的,但并不是每一杯水的 产生都必须把上述过程重复一次。你可以用一个大一点的容器(例如缸或罐等)来盛大 量的水,喝水之前分到杯子小部分中即可,你的代价只是把水从缸转移到杯子;你还可 以在大量用水(例如洗澡或洗衣服等)时,只需打开水阀,而不必临时铺设通往水源的 管道和购买净化水的设备。因为水是人们生活不可缺少的东西,每时每刻都在被大量地 使用,而且本质也完全相同,所以政府会铺设管道和建设水处理站,完成那些比较 困难的工作,达到资源共享的目的,而你也可针对自己的需求,用容器来盛那些具有特 定用途的水。本文将要和你讨论的高速缓存和连接池与上述特定容器和传输管道有很多 相似之处,它们都达到了同一个目的:在满足用户意愿的前提下,尽可能地共享资源, 以提高整个系统的性能。 高速缓存和连接池是数据访问中的重要技术,某些情况下的应用对访问数据库的性能有 巨大的提高,而且都得到了数据库业界的普遍支持。前者由DBMS厂商针对自己的数据库 实现,提供可供用户配置的方案;后者是JDBC的一个标准接口,由支持J2EE技术的应用 服务器厂商提供具体的实现,而你的Java程序代码无需更改。本文将向你简单介绍高速 缓存和连接池的概念和机制,并以PointBase数据库为例向你展示高速缓存的应用,而一 个简单的连接池应用场景将向你描述应用的条件和提高的性能。 & 二.Cache(高速缓存)和Connection Pool(连接池)的概念和机制 & 它们不是数据库独有的技术,但却得到数据库业界的普遍支持,并在其它数据存取和对 象复用领域有很多类似的应用。 & 1.Cache(高速缓存) & 作为个人计算机的日常使用者,你肯定听说过这些名词:Cache(高速缓存)、Memory( 内存)、Hard disk(硬盘)。它们都是数据存取单元,但存取速度却有很大差异,呈依 次递减的顺序。对于CPU来说,它可以从距离自己最近的Cache高速地存取数据,而不是 从内存和硬盘以低几个数量级的速度来存取数据。而Cache中所存储的数据,往往是CPU 要反复存取的数据,有特定的机制(或程序)来保证Cache内数据的命中率(Hit Rate) 。因此,CPU存取数据的速度在应用高速缓存后得到了巨大的提高。 对于数据库来说,厂商的做法往往是在内存中开辟相应的区域来存储可能被多次存取的 数据和可能被多次执行的语句,以使这些数据在下次被访问时不必再次提交对DBMS的请 求和那些语句在下次执行时不必再次编译。 因为将数据写入高速缓存的任务由Cache Manager负责,所以对用户来说高速缓存的内容 肯定是只读的。需要你做的工作很少,程序中的SQL语句和直接访问DBMS时没有分别,返 回的结果也看不出有什么差别。而数据库厂商往往会在DB Server的配置文件中提供与C ache相关的参数,通过修改它们,可针对我们的应用优化Cache的管理。下图是在Win2K 中配置MS Access数据源的界面,在"驱动程序"部分你可设置的页超时和缓冲区大小就是 和Cache有关的参数。在后面的讨论中,我将展示一个更复杂的数据库,向你解释Cache 对访问数据库性能的影响和如何寻找最优的配置方案。 & 2.Connection Pool(连接池) & 池是一个很普遍的概念,和缓冲存储有机制相近的地方,都是缩减了访问的环节,但它 更注重于资源的共享。下图展示了建立"调制解调器池"以共享调制解调器资源的VPN拨号 方案: 对于访问数据库来说,建立连接的代价比较昂贵,因此,我们有必要建立"连接池"以提 高访问的性能。我们可以把连接当作对象或者设备,池中又有许多已经建立的连接,访 问本来需要与数据库的连接的地方,都改为和池相连,池临时分配连接供访问使用,结 果返回后,访问将连接交还。 JDBC 1.0标准及其扩展中没有定义连接池,而在JDBC 2.0标准的扩展中定义了与连接池 相关的接口。与接口对应的类由应用服务器厂商实现,你可在对服务器的管理过程中调 节某个数据库连接池的参数。下图简略地描述了连接池的运行机制: & 三.Case & 1.高速缓存的参数设定 & 在PointBase数据库DB Server的配置参数列表中,我们可以找到这几个参数:cache.ch eckpointinterval、cache.size、SQLCaching.size等。下表是对各个参数的描述: & ---------------------------------------------------- 参数名&&&&&&&&&&&&&&&&&&&&&&&&& 参数描述 ---------------------------------------------------- cache.checkpointinterval&&&&&&& 检查点的时间间隔 cache.size&&&&&&&&&&&&&&&&&&&&& 高速缓存的最大页数(素数时,性能最好) SQLCaching.size&&&&&&&&&&&&&&&& 高速缓存中SQL语句的个数 ----------------------------------------------------- & 对于cache.checkpointinterval来说,和前面Access界面中的页超时是一个概念,它指 定了页面内容更新的时间间隔,这取决于你的应用对时效性的要求程度。 对于cache.size来说,指定了页面的个数,一般应设定为符合你查询结果的需求。至于 为何是素数,我也纳闷,不过还是遵照厂商的指示吧。 对于SQLCaching.size来说,指定了存储的经过编译的SQL语句的个数,你可以把它设定 为0,从而取消这个选项。 使用Cache后,性能到底有多大提高?我打开PointBase的Console通过JDBC驱动访问Ser ver,将SQL菜单下的Timing Mode选上,以显示各个步骤的耗费时间。执行语句是: SELECT * FROM PRODUCT_TBL 第一次访问,总计耗时1082毫秒,而编译耗时771毫秒。 紧接着的第二次访问,总计耗时仅为160毫秒,而编译耗时为0。 再接着的第三次访问,总计耗时仅为91毫秒,编译耗时也为0。 关闭Console,等待超过30秒之后,重新开启Console,执行相同的语句,总计耗时210毫 秒,编译耗时为20毫秒。 自等待超过30秒之后,执行语句,总计耗时101毫秒,编译耗时为0。 <BR[1]&&&
上一篇文章:
下一篇文章:
GOOGLE推介
未经授权禁止复制或建立镜像Copyright
& 中国教师站 All Rights Reserved.您已经赞过此文了。
语句类型 4.1—4.4
原作者:Eric S. Roberts
发表时间:浏览量:3427评论数:0挑错数:0
《Java语言的科学与艺术》 第四章
本章主要介绍了语句类型,重点讲述了控制语句
第四章 语句类型 言语有趣但却生硬 — 马克吐温, 哈克贝利芬历险记, 1884
乔治&布尔(1815—1864)
尽管很大程度上依靠自学且从未取得过正式的大学学位,乔治&布尔而然取得的足够突出的成就从而被任命为爱尔兰科克郡女王学院的数学教授,并被选为皇家社会科学院的院士。他最具影响的著作是1854年出版的《建立在数学理论的逻辑和概率上的思想方法研究》。本书介绍了一套新的逻辑系统即今天为人所熟知的布尔代数,它也成为了现代编程语言中实现运算控制的基础。
&& 在第二章中,你见到了一些展现了程序结构的Java程序范例。这些程序通过执行包含在run方法中的语句来运行。本章涵盖了Java中一些不同的语句类型,在此过程中扩展了解决问题可以使用的工具集合。 &
如同在大多数程序语言中一样,Java语言中的语句总是脱不出两种分类原则:一种是简单语句,执行动作。一种是控制语句,影响到其他语句执行的方式。你已经见到了各种类型的简单语句,例如赋值语句以及调用println方法。当然,在使用Karel来工作的时候你也遇到了许多类型的控制语句。for语句控制重复的次数,while语句允许你指定在某一情况发生前重复执行的次数,if语句使你可以通过某些条件检测来选择程序不同的执行路径。然而到目前为止,你所都是以非正式和惯性的方式学习了这些语句。要发挥出这些语句的全部能力,你需要对每种不同类型的语句是如何工作及如何在解决问题的过程中运用有更为细致的了解。 && 4.1&简单语句
在第二、三章中,你看到了许多完成各种任务的简单语句。例如,在最开始的程序文本中有在GraphicsProgram中调用add方法: add(new GLabel("hello, world"), 100, 75);
同样的,你也了解了赋值语句,其简写形式如下: balance +=
以及用于显示的语句: println("The total is " + total + ".");
在不那么正式的情况下,将这些语句类型看做独立的工具并根据习惯性来使用它们是有道理的。如果你需要读取以个整数,你需要做的就是记住一个完成这个目的习惯性用法,然后就可以写下来。如果你需要显示一个数值,你就需要使用println方法。但是,从正式的方式来看,这些简单语句都有一个统一的结构使Java编译器能够容易的在程序中识别出合法语句。在Java中,一个简单语句,无论其功能如何,都符合如下规则: &&
&&&&&&&& (简单语句规:一个简单语句由后跟分号的表达式组成) 因此,一个简单语句的模板简写如下:
表达式之后的分号使表达式成为一个合法语句。 && 尽管在Java中任何后跟分号的表达式都是一个合法语句,但这并不意味着每个这样的组合都是有效的语句。一个有效的语句必须有明显的可辨别的效果。语句 n1 + n2; 由表达式n1+n2和后跟分号组成,因此是一个合法语句。然而这却是一个完全无效的语句,这个语句将变量n1和n2相加,但它没有做任何事也得不到任何答案。Java中典型的简单语句是赋值语句(包括一般赋值和递增/递减操作)或者调用方法等有效操作,例如println。 根据简单语句规则很容易就可以看出如下列程序是一个合法语句。 println("The total is " + total + "."); 在第二章中提到的表达式定义中,方法的调用是合法表达式,因此上列中的方法调用部分——除了分号之外——都是合法表达式。行末的分号使这个表达式称为一个简单语句。 那么赋值语句又是怎样的呢?如果下行的 total = 0;
符合简单语句规则,那么 &&total = 0
则必是一个表达式。
在Java中,赋值所使用的等式简单来说是一个二进制操作符,就像加号+或除号/。等号(=)操作符有两个操作数。一个在左一个在右。以当前的目标为例,左边的操作数必须是一个变量名。当赋值运算执行时,右边的表达式被估值,然后其结果被储存在右边的变量中。因为赋值中的等式是一个操作符, &&total = 0
毫无疑问是一个表达式,而 total = 0;
因此是一个简单语句 && 程序段
简单语句允许程序员们指定动作。然而,除了第二章中的HelloProgram这个例子,其他的程序的要求都远远不是一个简单语句能搞定的。对大多数程序来说,解决问题的策略要求由一系列顺序步骤组成的协调动作。例如在Add2Integers这个程序中,先要取得第一个数,然后第二个数,然后两者相加,最后显示结果。将这一连串动作转换成实际程序步骤所需的独立语句都成为了整个主程序的一部分。 为了将这些顺序语句指定为一个连贯整体的一部分,你可以将这些语句集合与一个段内。如下所示,将语句和声明集合在一对闭合的花括号之间: {
statement1 statement2 statement3 &. . . statementn
其中任何一个语句都可以被一个声明代替,把声明看做是另一种形式的语句可能比较容易理解。 && 你已经在前面章节中不少程序示例中看到了段的使用。每一个方法的主体都是一个段,就像将在本章后面将介绍的控制语句的主体一样。 && 在一个段内的语句通常于该封闭的文本会有相对缩进。编译器会忽略这些缩进,但是对于程序的阅读者来说这样的视觉效果是很有用的,因为它将程序结构通过这样格式清晰的展现出来。实证研究表明,在每层级上使用三到四个空格会使程序结构最为清晰。本文中的程序将会用四个空格来缩进。缩进是好的编程风格的关键,所以你应当在自己的程序中努力发展出前后一致的缩进风格。 && 当Java编译器遇到一个段的时候,它会把整个段当做一个单独的语句。因此,当一个语句符号出现在一个语法模板或惯用模板中的时候,你可以将其替换为一条单独的语句或者是一个段。为了强调对编译器来说它们是语句,段也常常被称为复合语句。 &&&& 4.2&控制语句
在没有任何相反的指令的情况下,Java程序中的语句通畅只在该指令出现的地方执行一次。然而,对大多数程序而言,这样严格的自上而下的执行时不够的。解决现实世界的问题常常涉及到诸如重复执行一组步骤或在可替代的动作中进行选择这样的操作。影响其他语句执行方式的语句被称为控制语句。 && Java中的控制语句分为两类:
1.条件语句。为了解决问题,你常会需要根据某种条件判断的结果在程序中两种或者更多的独立执行路径中选择。例如,你可能会被要求写一个程序,在一个值为负的情况下以一种方式运行,而在其他情况时以另外的方式运行。这种需要做决定的控制语句叫做条件语句。在Java中,有两种控制语句的模式:if语句和switch语句。 && 1.迭代(循环)语句。特别是你的工作开始涉及超过几个数据项的时候,你的程序往往需要重复一个操作指定的次数,或者只要某项条件成立时就不断进行下去。在程序设计中,这种重复称为迭代,重复执行的部分代码陪称为一个循环。在Java中,作为迭代的基本控制语句使用的是while语句和for语句。 &&&& Java中的任何一个控制语句都是由两部分组成:控制行,指定了重复或条件。控制语句体,由控制行所影响的语句组成。以条件语句为例,语句体可能被分成独立的部分,一组语句在某一情况下执行,另一组则在其他情况下执行。 && 控制语句的语句体由其他语句组成。控制语句本身的效果——无论其指定的是重复或是条件执行——是由语句体中的语句来实现的。更进一步的说,这些语句,可以由任何类型的语句组成。可以是简单语句;可以是复合语句;或者其本身也是包含了其他语句的控制语句。当一个控制语句包含在另一个控制语句之中时,叫做嵌套。控制语句的嵌套是现代编程语言一个最为重要的特质之一。 && 4.3&布尔数据
在解决问题的过程中,通常有必要由一个程序来判断某个影响程序后续行为的特定条件。if语句,同许多其他控制程序执行的功能一样,使用那些值为真(true)或假(false)的表达式。这一类型的数据——值域只有真或假——叫做布尔型数据。数学家乔治布尔发展出一套代数方法来处理这一类型的数值。 Java对布尔类型的数值定义了一些操作符,布尔型数值是第三章中介绍过的基本数值类型中的一种。这些操作符分为两大类——关系运算符和逻辑运算符——将在接下来的两节中进行讨论。
关系运算符 关系运算符被用于比较两个数值。Java定义了6种关系运算符,根据优先级又可分为两类。测试两个量间的关系的运算符是 >&大于 <&小于 >=&&小于等于 <=&&大于等于 这些运算符在优先级上低于算术运算符,反过来又高于下列判断等于和非等于的运算符: ==&&等于 !=&非等于
当你编写程序判断相等时,要非常小心的使用这个由两个等号(==)组成的运算符。单个的等号是赋值操作符。两个等号组成的符号不是标准的数学符号,将其替换为单个等号是个十分常见的错误。幸运的是编译器在编译程序时通常能找出这样的错误,因为这种误写为赋值的语句在上下文中出现时通常都是不合语法规则的。
关系运算符只能被用于比较元数据类型的数值——即不由其他更小的部分组成的数据类型。例如,整数、浮点数、布尔型数值及字符构成了元数据,因为这些类型的数据不能再分解为更小的部分。另一方面,字符串不能算是元数据类型,因为字符串是由单独的字符组成的。因此,可以使用关系运算符比较的数值类型有整型(int)、双字节型(double)、字符型(char),甚至布尔型(boolean)本身,但是不能用关系运算符比较两个字符串类型的值。你会在第八章中学习到如何来比较字符串型数据。 && 逻辑运算符 除了关系运算符使用任何类型的元数据得到布尔值结果之外,Java还定义了三种运算符使用布尔类型的操作数并将它们结合起来产生布尔数值结果的操作符: !逻辑非&&&&&&(如果后跟操作数为真时,结果为假) &&&逻辑与&&&(如果两个操作数都为真时,结果为真) ||&&&逻辑或&&&(如果至少一个操作数为真时,结果为真) 这些运算符符叫做逻辑运算符,并按照优先级递减的顺序列出。 运算符&&、|&|、&!接近于与、或、非这几个词。尽管如此,需要记住的是英语在谈论逻辑的时候有时会不太准确。为了避免不准确,将这些操作符看做是更为正式的数学方式通常是由益的。逻辑学家们使用真值表定义了这些运算符,显示了在操作数的值发生变化时布尔表达式的值如何改变。例如,给定布尔值p和q,与运算(&&)的真值表如下:
表中最后一列显示了在前两列中给定的布尔变量p和q给定不同的值时,布尔表达式p&&q的值。因此,表中第一行显示了当p为假,q为假时,表达式p&&q的值也为假。
或运算的真值表如下:
&& 要注意到的是或运算并不像在英语中那样表示“一个或另一个”,而是以数学含义表示了“一个或两者都是”。 &&非运算符的真值表很简单: &&
如果你需要确定一个更为复杂的逻辑表达式的运算,你可以将它分解为这些基本操作然后建立其这个表达式各个部分真值表。
在大多是情况下,逻辑表达式没有复杂到需要你用真值表来得到其结果。只有当!或者!=同&&或者||在一起使用的时候常常会造成混乱。当讨论非真的时候(即使用!和!=运算符时),习惯用语中的概念有时会和数学逻辑的概念发生分歧,你需要十二分小心来避免错误。例如,假设你想在程序中表达这样一个意思“x不等于2或3”。只从字面上来看这个条件判断,编程新手很可能会将程序写为: if(x!=2&||&x!=3)......... 如果从数学的角度来审视这个条件判断,你会发现如果“x不等于2”或者“x不等于3”这两个判断的中任何一个为真,那么这个if判断语句中的表达式的值就为真。无论x的值为多少,这两个语句中的一条都会为真,因为,如果x等于2,那么它肯定不等于3,反之亦然。因此,上面的这个if判断语句总是成立的。
为了修正这个问题,你需要改进对英语表达的理解使表述的情况更精确。那就是你想使if判断语句在“x既不等于2也不等于3”的时候成立。你可以将这个表述写成Java的形式: if(!(x==2&||&x==3))......... &&但是这个写法显得有些笨拙。你想问的问题答案其实是下列两种情况是否都成立: x&不等于2,以及 x不等于3。 如果你以这种方式理解这个问题,那么条件判断可以写成: if(x!=&2&&&&x!=&3)............. &&这种简化是如下所示的数学逻辑中一种普遍规律的具体表现: 对任何逻辑表达式p和q有 !(p&||q)&等价于&&!p&&&&!q 这个变换规则还有一条与之对称的对应 !(p&&&&q)&等价于&&!p&&||&!q 称之为德摩根法则。忘记这一规则的运用反而依靠英语中的语言逻辑是编程错误的普遍来源。 另一个常见的错误是在将几个相关判断组合在一起时没有使用合适的逻辑连接。 0<10 这个表达式在数学中是有意义的,但并不意味着在Java中也是一样。为了判断变量x即大于0又小于10,你需要像如下所示那样明确的表明这两种情况: 0<10
短路求值 Java解释&&和||运算符的方式和其他程序语言的方式有所不同。例如在Pascal中,对这些运算符求值的时候(在Pascal中写做AND和OR)要将两边的条件都得出来,即使结果只需要一边的值就可以确定。Java的设计者采用了一种不同的方法,对程序员们来说也更方便的方式。 当Java程序在对形如 exp1&&exp2 或者 exp1&||&exp2 的表达式求值时,独立的子表达式总是从左向右求值,且在答案可以确定的时候停止。 例如,如果exp1在与运算中为假,那么就没有必要再求出exp2的值因为最终答案总是假。类似的,在或运算中如果第一个操作数为真,就没有必要求出第二个操作数的值。这种一旦得到答案便停止的求值方式,叫做短路求值。 && 短路求值最主要的优势在于其允许一个条件控制运行。在许多情况下,复合判断中的第二个条件只有在第一个条件确定时才有意义。例如,假设你要表述的复合判断为(1)整数x的值不等于0,(2)x可以被y整除。你可以在Java将这个条件判断表述为 (x&!=&0)&&&(y&%x==0) 因为表达式y%x只有在x不等于0时才能被求值。Pascal中相应的表达式不能产生预期的结果,因为在Pascal中两个条件判断总是都被求值。因此,如果x等于0,尽管存在一个这种情况下的条件判断检查,包含这个表达式的Pascal程序最终仍会以0来作为被除数。为了防止后面的部分出现这种求值错误的条件判断如下 (x&!=&0) 在后续的例子中,这个机制被叫做保护。 && 标记 布尔类型的变量是如此重要以至于它们有一个特别的名称:标记。例如,假如你声明一个布尔变量 boolean&&done; 变量done就是一个标记,以记录你在程序中的某个运行是否完成。像其他任何类型的变量一样,你可以为标记赋一个新值。例如, done&=&true; 或者 done&=false; 更重要的是,你可以将任何具有布尔类型值的表达式赋值给一个布尔变量。例如,假设你的程序在变量&itemsRemaining&为0时指示你某个阶段的运行已完成。为了给done设置合适的值,你可以将程序写为: done&=&(&itemsRemaining&==&0); 这个表达式中的括号是非必需的,但通常都会用它来强调你是将这个条件判断的结果赋值给一个变量。上面这个语句是说:“计算(itemsRemaining&==&0)的值,不论为真或为假,将结果储存在变量done中。” &&在布尔表达式中避免冗余 尽管语句 done&=(itemesRemaining&==&0); 完全能将正确的布尔值储存在变量done中,但这个类型的语句对人们来说很不好理解。新手们常常更愿意用如下的if语句来达到同样的效果: if&(itemsRemaining&==&0)&{ &&&&done&=& }&else&{ &&&&done&=& } 尽管上面几行程序也达到了同样效果,但却失去了你应当努力在程序中体现的效率和优雅的原则。这段程序使用了五行代码来完成一个任务,远超过了程序实际需要的长度。当你在和布尔型数据打交道的时候,一定要记住你可以像其它任何类型的值一样用布尔值来赋值而不需要明确的判断。 当使用一个标记作为条件判断的一部分的时候有相似的问题。为判断done是否为真,一个有经验的程序员会这样写 if(done)......... 而不是 if(done&==&true)......... 尽管第二个表达式也同样能工作,但这个等价判断是多余的。变量done的值已经保证了不是真就是假,正是if语句所需要的那个类型的值。不需要再问done是否为真,多余的判断并没有提供任何新的信息。 && 布尔计算的一个例子 正如天文学家们在几个世纪前就已经知道的,地球围绕太阳的公转需要365天多一点点。因为地球需要365又四分之一天的时间来完成一个年周转,每隔四年便需要在日历上添加这出一天,成为一个闰年。这一调整保证了历法和太阳运行轨道的同步,但这一方法仍有少许偏差。为了保证每一年的开始不会因这个微小量的积累而在季节中漂移,实际的闰年规则要稍微复杂一些。闰年每四年一个,除了以00结尾的年份,而这其中又不包括能够被400整除的年份。因此,1900年不是一个闰年,尽管1900能被4整除。而另一方面,2000年因为能被400整除所以是一个闰年。 &&假设你需要写一个程序来判断一个年份是否是闰年。你会怎么写能回答这一问题的布尔表达式呢?为了确保闰年,必须符合以下条件之一: 这个年份能被4整除,但不能被100整除,或者 这个年份能被400整除。 如果年份以变量y表示,以下这个布尔表达式就可以得到正确的结果: ((y%4&==&0)&&&(y%100&!=&0))&||(y%400&==&0) 根据Java的优先规则,表达式中的括号都是非必需的,但括号的使用使长布尔表达式能够便于阅读。如果将这个表达式的结果储存在isLeapYear这个标记中,你就可以通过在程序的其他地方判断这个标记来确定isLeapYear是否为真。一个计算是否为闰年的程序如图4-1所示。
4.4&&if语句 在Java中最简单的表述条件运行的方式是使用if语句。其两种形式如下所示: if(condition)statement if(condition)statement&&else&&statement 这个模板中的condition部分是一个布尔值的表达式。而语句可以是简单语句也可以是段(复合语句)。 FIGURE&4-1&&&&确定闰年的程序 /* &*&File:&LeapYear.java &*&------------------- &*&This&program&reads&in&a&year&and&determines&whether&it&is&a &*&leap&year.&&A&year&is&a&leap&year&if&it&is&divisible&by&four, &*&unless&it&is&divisible&by&100.&&Years&divisible&by&100&are &*&leap&years&only&if&divisible&by&400. &*/ import&acm.program.*; public&class&LeapYear&extends&ConsoleProgram&{ public&void&run()&{ println("This&program&checks&for&leap&years."); int&year&=&readInt("Enter&year:&"); boolean&isLeapYear&=&((year&%&4&==&0)&&&&(year&%&100&!=&0)) &&&&&&&&&&&&&&&&&&&&&||&(year&%&400&==&0); if&(isLeapYear)&{ println(year&+&"&is&a&leap&year."); }&else&{ println(year&+&"&is&not&a&leap&year."); } } } && 当你的解题策略只需要在一种特定的条件产生时执行一个语句集合的时候,你可以使用第一个模式。如果这种情况没有产生,作为if语句主体的内容将会被跳过。当需要根据判断结果的不同情况在两种独立的动作集合中选择时,你需要使用第二种模式。这需要根据问题的不同来做决定。如果对问题的描述中有“否则”这样的字眼,那么这就是一个使用else模式的好机会。如果描述中没有传达这样的概念,那么if语句的简单形式也许就够用了。 &&在图4-1的闰年程序中展示了带有else的if语句,程序在闰年时输出一条信息,在非闰年的情况下输出相反的信息。如果问题的结构改变,只需要在闰年时输出信息,你可以用简单if语句来代替,如下所示: if&(isLeapYear)&{ println(year&+&"&is&a&leap&year."); } 在一个if语句中,当条件表达式的值为真时执行的语句段称为then子句。当判断条件为假时执行的语句段——如果有的话——被称为else子句。 &&事实上,if语句中可选的else自己有时会造成歧义,即所谓的else悬荡问题。如果你写了程序有几个if语句嵌套,有一些有else子句,另一些没有else子句,那么就很难分辨哪个else子句是属于哪个if语句的。当遇到这种情况的时候,Java编译器会简单的将靠的最近的if和else子句组合到一起成为一对,但对程序的阅读者来说很快的分辨出每个else子句的归属仍是比较难的。通过采用比Java所要求的更为严谨的编程风格,是可以避免这样的问题的。下面这个关于如何在if语句中使用段的规则就消除了这种问题: If/Else复合语句规则
(1)要求至少超过一行 (2)要求if语句控制下的else子句总是在由花括号封闭的单独的一个程序段内。
&&根据If/Else复合语句规则 的要求,if语句表现为以下四种形式中的一种: 1.对短条件判断的if语句使用单独的一行 2.对多行的if语句要求在一个封闭的程序段内 3.一个if-else语句必须总是由一个封闭的程序段构成,即使它只包含一条单独的语句 4.层叠的if语句用于表述一个连串的条件判断 &&在后面的段落中将详细讨论每个形式的细节。
单行if语句&&&&&&&&&&&&&&&&&&&&&&&&&&&
右边的语法盒子里显示了没有else子句并且 语句长短在一行范围内的简单if语句单行格式。在这种情况下,使用括号把if语句扩展到三行只会增加程程序的长度并使其缺乏可读性。
&& 多行if句&&&&&&&&&&&&&&&&&&&&&&&& & 当if语句的主体有多个语句构成或者在一 行中不足以容纳很长的一个单句,如右图 所示,就要将语句放在一个封闭的段中。 在这种情况下,语句在条件判断为真的情 况后执行。如果条件判断为假,程序则不 做任何动作并接着从if语句之后的语句执行。
&& If-else语句&&&&&&&&&&&&&&&&&&&&&
为了避免else悬荡问题,有else子句的if语句的主体总是被包括在一个封闭的段内,其形式如右图所示。从技术上来说,包裹着段的花括号只在语句多于一条时使用。但是,通过系统的使用这些花括号,你可以最大程度的避免混淆并使程序更易于维护。 &&
层叠if语句&&&&&&&&&&&&&&&&&&&&&&&
右图中展示了一种重要的特殊情况,即当 所要处理的可能情况大于两种以上时,if语 句的一种很有用的应用。这个形式的特点 是条件的else部分由另一个检查其他条件的 判断构成。这样的语句叫做&层叠if语句, 且可能涉及任何数量的else&if行。例如,在 图4-2中的SignTest程序使用了层叠if语句来 报告一个数是正值、0、或负值。注意,没 有必要来准确检查n<0的情况。如果程序运 行到了最后一个else子句,那么就没有其他 可能性了,因为之前的判断已经排除了负 值和0的情况。 图4-2&&&&&&&&&&&& 根据整数正负分类
FIGURE 4-2&&& Program to classify an integer according to its sign /* &* File: SignTest.java &* ------------------- &* This program reads in an integer and classifies it as negative, &* zero, or positive depending on its sign. &*/ import acm.program.*; public class SignTest extends ConsoleProgram { public void run() { println("This program classifies an integer by its sign."); int n = readInt("Enter n: "); if (n > 0) {
println("That number is positive.");
} else if (n == 0) { println("That number is zero.");
} else { println("That number is negative.");
} 在大多数情况下,处理许多不同选择情况时可以选择更有效率的switch语句,这将在后面以一个单独的段落来描述。 ?:运算符 Java编程语言为表述选择执行提供了另一种特定机制下极为有用的更简洁的机制:?:运算符。(这个运算符由问号和冒号组成,尽管在实际中这两个符号不会相邻出现。)与Java中其他的运算符不同的是,?:写做两部分,需要三个操作数。这个操作的通用形式是 condition&?&expression1&:expression2 &&当一个Java程序遇到?:运算符的时候,首先会对条件(condition)求值。如果条件为真,表达式1(expression1)会被求值并当做整个表达式的值;如果条件为假,表达式的值则会取表达式2(expression2)的值。?:运算符因此可算是如下这个if语句的简化形式 if&(condition)&{ &&&value&=&expression1; }&else&{ &&&value&=&expression2; } 例如,如下所示,你可以用?:运算符来将x或y中较大的那个赋给max: max&=&(x&>&y)&?&x&:&y; 从技术上讲,在这个表达式中的括号不是必需的,但多数Java程序员倾向于使用括号以加强程序文本的可读性。 &&一个使用?:运算符最为常见的情况是在调用println方法根据情况而使输出稍有不同时。例如,假设你写了一个程序来计算某种物品的数量,在完成所有计数后将数值储存在变量nItems中。你会怎样向用户报告这个值呢?最明显的方式是使用如下的语句调用println方法 println(nItems&+&"&items&found."); 但是假如你是个有语法洁癖的人,当nItems恰好是1的时候你读到这条输出时可能会有些微懊恼。
然而你可以通过将println方法嵌入如下if语句来改正这个英语语法上的错误; if&(nItems&==&1)&{ println(nItems&+&"&item&found."); }&else&{ println(nItems&+&"&items&found."); }
&& 这个解决策略唯一的问题是它需要5行语句来表达这个相对简单的意思。你可以使用如下?:运算符作为另一个选择: println(nItems&+&"&item"&+&(nItems&==&1&?&""&:&"s")&+&"&found."); &&输出中的字符串item将在nItems的值等于1时后跟空字符串,否则的话会后跟s。需要注意的是在这个表达式中,括号是必需的 (nItems&==&1&?&""&:&"s") ?:运算符相对于+具有较低的优先级,这意味着Java首先会做并列操作。 && 在Java中,?:运算符可能会被过度使用。如果程序中一部分重要的关键性结构隐藏在?:运算符中,那么这个结构可能会在剩下的代码中不那么容易被看出来。另一方面,如果能通过?:运算符来处理一些小细节而不是用复杂的if语句,程序结构就能被被处理的相当简洁。
相关译文来自无觅插件
还没有人赞过这篇文章
Copyright & 2014 yeeyan.org&&|&&&&|&&
北京译言协力传媒科技有限公司
京ICP证号&&京公网安备99号
&&|&&&&|&&
&&|&&&&|&&&&|&&}

我要回帖

更多关于 相邻数教案 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信