第3章 表达式和流程控制.docx
- 文档编号:27178007
- 上传时间:2023-06-27
- 格式:DOCX
- 页数:20
- 大小:140.21KB
第3章 表达式和流程控制.docx
《第3章 表达式和流程控制.docx》由会员分享,可在线阅读,更多相关《第3章 表达式和流程控制.docx(20页珍藏版)》请在冰豆网上搜索。
第3章表达式和流程控制
第三章表达式和流程控制
本模块讨论变量、运算符和算术表达式并列出不同的管理运行程序路径的控制结构。
第一节相关问题
讨论──下列问题与本模块阐述的论题相关。
什么类型的变量对程序员有用(例如,其它语言的程序员想了解Java编程语言是如何定义和处理全局变量和局部变量的)?
复合类可以有同名的变量吗?
如果可以,它们的作用域有多大?
列出用于其它语言的控制结构;一般语言都采用什么方法进行流程控制和中断流程(如在循环或开关语句中)?
第二节目标
完成本模块的学习后,你应该能够:
区分实例变量和局部变量;
描述实例变量是如何被初始化的;
确认并更正编译器错误;
辨认、描述并使用Java软件运算符;
区分合法和非法原始类型赋值;
确认boolean表达式和它们在控制构造中的要求;
辨认赋值兼容性和在基本类型中的必要计算;
使用if,switch,for,while和do句型结构和break和continue的标号形式作为程序中的流程控制结构。
第三节表达式
3.3.1变量和作用域
你已经看到了两种变量的描述方法:
原始类型变量和引用类型变量。
你也看到了变量被声明的位置:
在方法内(方法是面向对象的术语,它可引用函数或子程序,例如:
main())或在方法外但在类定义之内。
变量也可被定义为方法参数或构造函数参数。
在方法内定义的参数被称为局部(local)变量,有时也被用为自动(automatic)、临时(temporary)或栈(stack)变量。
在方法外定义的变量是在使用newXxxx()调用构造一个对象时被创建。
在构造一个对象时,可创建两种变量。
一是类变量,它是用static关键字来声明的;只要需要对象,类变量就将存在。
二是实例变量,它不需用static关键字来声明;只要对象被当作引用,实例变量就将存在。
实例变量有时也被用作成员变量,因为它们是类的成员。
方法参数变量定义在一个方法调用中传送的自变量,每次当方法被调用时,一个新的变量就被创建并且一直存在到程序的运行跳离了该方法。
当执行进入一个方法时,局部变量被创建,当执行离开该方法时,局部变量被取消。
因而,局部变量有时也被引用为“临时或自动”变量。
在成员函数内定义的变量对该成员变量是“局部的”,因而,你可以在几个成员函数中使用相同的变量名而代表不同的变量。
该方法的应用如下所示:
classOurClass{
inti;//instancevariableofclassOurClass
intfirstMethod(){
intj=0;//localvariable
//bothiandjareaccessiblefrom
//thispoint
...
return1;
}//endoffirstMethod()
intsecondMethod(floatf){//methodparameter
intj=0;//localvariable.Differentfromthe
//jdefinedinfirstMethod().
//Scopeislimitedtothebodyof
//secondMethod().
//Bothi(instancevariableofthe
//classOurClass)andj(local
//variableofthismethod)are
//accessiblefromthispoint.
....
return2;
}//endofsecondMethod()
}//endofclassOurClass
3.3.2变量初始化
在Java程序中,任何变量都必须经初始化后才能被使用。
当一个对象被创建时,实例变量在分配存储器的同时被下列值初始化:
byte
0
short
0
int
0
long
0L
float
0.0f
double
0.0d
char
'\u0000'(NULL)
boolean
false
Allreferencetypes
Null
注意──一个具有空值的引用不引用任何对象。
试图使用它引用的对象将会引起一个异常。
异常是出现在运行时的错误,这将在模块7“异常”中讨论。
在方法外定义的变量被自动初始化。
局部变量必须在使用之前做“手工”初始化。
如果编译器能够确认一个变量在初始化之前可被使用的情形,编译器将报错。
publicvoiddoComputation(){
intx=(int)(Math.random()*100);
inty;
intz;
if(x>50){
y=9;
}
z=y+x;//Possibleusebeforeinitialization
}
3.3.3运算符
Java软件运算符在风格和功能上都与C和C++极为相似。
表3-1按优先顺序列出了各种运算符(“LtoR”表示左到右结合,“RtoL”表示右到左结合)
Separator[]();,
RtoL++--+-~!
(datatype)
LtoR*/%
LtoR+-
LtoR<<>>>>>
LtoR<><=>=instanceof
LtoR==!
=
LtoR&
LtoR^
LtoR|
LtoR&&
LtoR||
RtoL?
:
RtoL=*=/=%=+=-=<<=>>=>>>=&=^=|=
注意──instanceof是Java编程语言特有的运算符,将在模块5“对象和类”中讨论
3.3.4逻辑表达式
多数Java运算符是从其它语言借取得并且和人们一般期待的功能一样。
关系和逻辑运算符返回布尔结果,int到boolean不能自动转换。
inti=1;
if(i)//generatesacompileerror
if(i!
=0)//Correct
支持的位运算符是!
、&、|、^,支持的布尔逻辑运算符是NOT、AND、XOR和OR。
每个运算都返回布尔结果。
运算符&&和||是运算符&和|的布尔等价物。
布尔逻辑运算符将在下一页中讨论。
3.3.5位运算
Java编程语言支持整数数据类型的位运算,它们的运算符~、&、^和|分别表示位运算的NOT(为求反)、位AND、位XOR和位OR。
移位运算符将稍后在本课程中讨论。
3.3.6布尔逻辑运算符
运算符&&(定义为AND)和||(定义为OR)执行布尔逻辑表达式。
请看下面的例子:
MyDated=null;
if((d!
=null)&&(d,day()>31)){
//dosomethingwithd
}
形成if()语句自变量的布尔表达式是合法且安全的。
这是因为当第一个子表达式是假时,第二个子表达式被跳过,而且当第一个子表达式是假时,整个表达式将总是假,所以不必考虑第二个子表达式的值。
类似的,如果使用||运算符,而且第一个表达式返回真,则第二个表达式不必求值,因为整个表达式已经被认为是真。
3.3.7用加号(+)进行串链接
用加号(+)进行串链接
运算符+能够:
进行String链接
生成一个新的String
例如:
Stringsalutation="Dr.";
Stringname="Jack"+"Arthur";
Stringtitle=salutation+name;
最后一行的结果是:
Dr.JackArthur
一个自变量必须是String对象
非串被自动转换为String对象
运算符+能够进行String对象的链接并生成一个新的String:
Stringsalutation="Dr.";
Stringname="Jack"+"Arthur";
Stringtitle=salutation+name;
最后一行的结果是:
Dr.JackArthur
如果+运算符中有一个自变量为String对象,则其它自变量将被转换成String。
所有对象都可被自动转换成String,尽管这样做的结果可能是意义含糊的。
不是串的对象是通过使用toString()成员函数而转换成串的等价物的。
3.3.8右移位运算符>>和>>>
Java编程语言提供了两种右移位运算符
运算符>>进行算术或符号右移位。
移位的结果是第一个操作数被2的幂来除,而指数的值是由第二个数给出的。
例如:
128>>1gives128/21=64
256>>4gives256/24=16
-256>>4gives-256/24=-16
逻辑或非符号右移位运算符>>>主要作用于位图,而不是一个值的算术意义;它总是将零置于最重要的位上。
例如:
1010...>>2gives111010...
1010...>>>2gives001010...在移位的过程中,>>运算符使符号位被拷贝。
注意──移位运算符将它们右侧的操作数模32简化为int类型左侧操作数,模64简化为long类型右侧操作数。
因而,任何intx,x>>>32都会导致不变的x值,而不是你可能预计的零。
注意------值得称赞的重要一点是:
>>>运算符仅被允许用在整数类型,并且仅对int和long值有效。
如果用在short或byte值上,则在应用>>>之前,该值将通过带符号的向上类型转换被升级为一个int。
有鉴于此,无符号移位通常已成为符号移位。
3.3.9左移位运算符(<<)
运算符<<执行一个左移位。
移位的结果是:
第一个操作数乘以2的幂,指数的值是由第二个数给出的。
例如:
128<<1gives128*21=256
<<2gives16*22=64
3.3.10类型转换
在赋值的信息可能丢失的地方,编译器需要程序员用类型转换(typecast)的方法确认赋值。
例如,它可以“挤压”一个long值到一个int变量中。
显式转型做法如下:
longbigValue=99L;
intsquashed=(int)(bigValue);
在上述程序中,期待的目标类型被放置在圆括号中,并被当作表达式的前缀,该表达式必须被更改。
一般来讲,建议用圆括号将需要转型的全部表达式封闭。
否则,转型操作的优先级可能引起问题。
注意──重温short的范围是:
-215至215-1;char的范围是:
0至215-1。
因而在short和char之间的赋值总需要一个显式转型
3.3.11升级和表达式的类型转换
升级和表达式的类型转换
变量被自动升级为一个较长的形式(如:
int至long的升级)
如果变量类型至少和表达式类型一样大(位数相同),则表达式是赋值兼容的。
当没有信息丢失时,变量可被自动升级为一个较长的形式(如:
int至long的升级)
longbigval=6;//6isaninttype,OK
intsmallval=99L;//99Lisalong,illegal
doublez=12.414F;//12.414Fisfloat,OK
floatz1=12.414;//12.414isdouble,illegal
一般来讲,如果变量类型至少和表达式类型一样大(位数相同),则你可认为表达式是赋值兼容的。
对+运算符来说,当两个操作数是原始数据类型时,其结果至少有一个int,并且有一个通过提升操作数到结果类型、或通过提升结果至一个较宽类型操作数而计算的值,这可能会导致溢出或精度丢失。
例如:
shorta,b,c
a=1;
b=2;
c=a+b;
上述程序会因为在操作short之前提升每个short至int而出错。
然而,如果c被声明为一个int,或按如下操作进行类型转换:
c=(short)(a+b);
则上述代码将会成功通过。
第四节分支语句
条件语句使部分程序可根据某些表达式的值被有选择地执行。
Java编程语言支持双路if和多路switch分支语句。
3.4.1if,else语句
if,else语句的基本句法是:
if(布尔表达式){
语句或块;
}else{
语句或块;
}
例:
intcount;
1.count=getCount();//amethoddefinedintheprogram
2.if(count<0){
3.System.out.println("Error:
countvalueisnegative.");
4.}else{
5.System.out.println("Therewillbe"+count+
6."peopleforlunchtoday.");
7.}
在Java编程语言中,if()用的是一个布尔表达式,而不是数字值,这一点与C/C++不同。
前面已经讲过,布尔类型和数字类型不能相互转换。
因而,如果出现下列情况:
if(x)//xisint
你应该使用下列语句替代:
if(x!
=0)
全部else部分是选择性的,并且当测试条件为假时如不需做任何事,else部分可被省略。
3.4.2switch语句
switch语句的句法是:
switch(expr1){
caseexpr2:
statements;
break;
caseexpr3:
statements;
break;
default:
statements;
break;
}
注意──在switch(expr1)语句中,expr1必须与int类型是赋值兼容的;byte,short或char类型可被升级;不允许使用浮点或long表达式。
当变量或表达式的值不能与任何case值相匹配时,可选缺省符(default)指出了应该执行的程序代码。
如果没有break语句作为某一个case代码段的结束句,则程序的执行将继续到下一个case,而不检查case表达式的值。
例1:
1.switch(colorNum){
2.case0:
3.setBackground(Color.red);
4.break;
5.case1:
6.setBackground(Color.green);
7.break;
8.default:
9.setBackground(Color.black);
10.break;
11.}
例2:
1.switch(colorNum){
2.case0:
3.setBackground(Color.red);
4.case1:
5.setBackground(Color.green);
6.default:
7.setBackground(Color.black);
8.break;
9.}
例2设定背景颜色为黑色,而不考虑case变量colorNum的值。
如果colorNum的值为0,背景颜色将首先被设定为红色,然后为绿色,再为黑色。
第五节循环语句
循环语句
for语句
for(init_expr;booleantestexpr;alter_expr){
statementorblock
}
循环语句使语句或块的执行得以重复进行。
Java编程语言支持三种循环构造类型:
for,while和doloops。
for和while循环是在执行循环体之前测试循环条件,而doloops是在执行完循环体之后测试循环条件。
这就意味着for和while循环可能连一次循环体都未执行,而doloops将至少执行一次循环体。
3.5.1for循环
for循环的句法是:
for(init_expr;booleantestexpr;alter_expr){
statementorblock
}
例如:
for(inti=0;i<10;i++){
System.out.println("Areyoufinishedyet?
");
}
System.out.println("Finally!
");
注意──Java编程语言允许在for()循环结构中使用逗号作为分隔符。
例如,for(i=0,j=0;j<10;i++,j++)是合法的;它将i值初始化为零,并在每执行完一次循环体后,增加一次它们的值。
3.5.2while循环
while循环的句法是:
while(布尔表达式){
语句或块
}
例如:
inti=0;
while(i<10){
System.out.println("Areyoufinishedyet?
");
i++;
}
System.out.println("Finally!
");
请确认循环控制变量在循环体被开始执行之前已被正确初始化,并确认循环控制变量是真时,循环体才开始执行。
控制变量必须被正确更新以防止死循环。
3.5.3do循环
do循环的句法是:
do{
语句或块;
}
while(布尔测试)
例如:
inti=0;
do{
System.out.println("Areyoufinishedyet?
");
i++;
}while(i<10);
System.out.println("Finally!
");
象while循环一样,请确认循环控制变量在循环体中被正确初始化和测试并被适时更新。
作为一种编程惯例,for循环一般用在那种循环次数事先可确定的情况,而while和do用在那种循环次数事先不可确定的情况。
第六节特殊循环流程控制
下列语句可被用在更深层次的控制循环语句中:
break[标注];
continue[标注];
label:
语句;//wherestatementmustbeany
//legalstatement.
break语句被用来从switch语句、loop语句和预先给定了label的块中退出。
continue语句被用来略过并跳到循环体的结尾。
label可标识控制需要转换到的任何有效语句,它被用来标识循环构造的复合语句。
例如
loop:
while(true){
for(inti=0;i<100;i++){
switch(c=System.in.read()){
case-1:
case`\n`:
//jumpsoutofwhile-looptoline#12
breakloop;
....
}
}//endfor
}//endwhile
test:
for(...){
....
while(...){
if(j>10){
//jumpstotheincrementportionof
//for-loopatline#13
continuetest;
}
}//endwhile
}//endfor
练习:
使用表达式
练习目标──你将编写、编译并运行两个使用标识符、表达式和控制结构的算法程序。
一、准备
为成功地完成本练习,你必须具备编译和运行Java程序的能力,并且熟悉流程控制构造。
二、任务
1级:
创建一个阶乘应用程序
一个数X的阶乘(通常记作X!
)等于X*(X-1)*(X-2)……*1。
例如4!
等于4×3×2×1=24。
创建一个称作Factor的应用程序,利用该应用程序可打印2,4,6和10的阶乘。
2级:
求解一个几何题程序
已知一个直角三角形,其弦(最长边)的长度由下列公式给出:
编写一个称作hypotenuse的Java软件程序,从已知直角三角形的直角边计算最长边。
提示:
从mod3/templates目录中提供的模板解决方案入手,从命令行输入;同时注意java.lang.Math类。
三、练习小结
讨论──用几分钟的时间讨论一下在以上练习中你所获得的经验、感想和发现。
经验解释总结应用
四、检查你的进度
在进入下一模块之前,请确认你已经能够:
区分实例变量和局部变量;
描述实例变量是如何被初始化的;
确认并更正“可能的赋值前的引用”的编译器错误;
辨认、描述并使用Java软件运算符;
区分合法和非法原始类型赋值;
确认boolean表达式和它们在控制构造中的要求;
辨认赋值兼容性和在基本类型中的必要转型;
使用if,switch,for,while和do句型结构和break和continue的标注形式作为程序的流程控制结构。
五、思考题
多数编程语言都使用什么数据类型来集合相似的数据元素?
你怎样对一组元素进行相同的操作(如一个数组)?
Java编程语言使用什么数据类型?
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第3章 表达式和流程控制 表达式 流程 控制