文档库 最新最全的文档下载
当前位置:文档库 › 第03章 表达式和流程控制

第03章 表达式和流程控制

第三天:
教学任务:
完成第三章内容的讲解,共23个slide(63-83)。
目标: 1. 操作符; + - * /
2. 条件语句;if
3. 循环语句;for
------------------------------------------------------------
x=1,y=2,z=3,u=false
1).y+=z--/++x;
2).u=y>z^x!=z
3).u=(z<加减乘除运算优先于移位运算
1100 >> 1 0110 12—>6
12/2^1 = 6
第一个问题是由于 byte与int进行运算时,会先将byte类型转换成int在进行运算
第二个问题是赋值运算符的优先级最低,比较运算符的优先级比异或运算符的优先级高,
u = ((y>z)^(x!=z)),这样的话,u=((2>3)^(1!=3)) ==〉u=(false^true) ==> u = true;
第三个问题u=z<向左移动表示乘以2的次数z<0011 << 2 1100 12 3*2^2
第三章: Expressions and Flow Control(63-83)
程序的基本功能是处理数据
程序用变量来表示数据;
程序中必须先定义变量才能使用;
定义变量是指设定变量的数据类型和变量的名字,Java语言要求变量遵循先定义,再初始化,然后使用的规则。
变量的使用有一个作用域的问题,作用域是指它的存在范围,只有在这个范围内,程序代码才能访问它。
其次,作用域决定了变量的生命周期。变量的生命周期是指从一个变量被创建并分配内存空间开始,到这个变
量被销毁并清除其所占用内存空间的过程。当一个变量被定义时,它的作用域就被确定了。按照作用域的不同,
变量可分为成员变量,局部变量
. 成员变量:在类中声明,它的作用域是整个类;声明周期整个类
可以被类里面的所有方法应用
成员可以不初始化,本身有默认值
默认值 成员变量位于堆空间
int:0 boolean:false double:0.0 String:null
成员构建时不允许先声明,在同一时间初始化.在声明同时本身jvm已经初始化过
如果在进行初始化会产生歧义,jvm不理解到底是哪一个初始化有意义
e.g
成员变量String name; 相当于 String name = null;
局部变量由于不会进行初始化操作,只可能产生一种
e.g
int i;
i =10 jvm理解成 int i = 10;
. 局部变量:局部必须初始化.jvm不会默认初始化 。在一个方法的内部或方法的一个代码块的内部声明。如果在一个方法内部声明,它的作用域是整个方法;其他方法不能调用该方法里面的变量.如果在一个方法的某个代码块的内部声明,它的作用域是这个代码块。
代码块是指位于一对大括号"{}"以内的代码。方法中变量的可以被代码块使用,但是代码块的变量不能被方法以及其

他方法使用.局部变量位于栈空间
局部变量可以作用域包括方法内部的代码块中,而代码块中变量
的作用域只能是当前代码块中,即使是包含这个代码块的方法
也不能使用.
. 方法参数:方法或者构造方法的参数,它的作用域是整个方法,类似于局部变量
. 异常处理参数:和方法参数很相似,差别在于前者是传递参数给异常处理代码块,而后者是传递参数给方法或者
构造方法。异常处理参数是指catch(Exception e)语句中的异常参数"e",它的作用域是紧跟着
catch(Exception e)语句后的代码块。
目的:1. 局部变量
1) 定义在方法的内部或方法的一个代码块的内部;

public void method1() {
int a = 0; //局部变量,作用域为整个method01方法;
{
int b = 0; //局部变量,作用域为所处的代码块;
b = a;
}
b = 20; //编译出错,b不能被访问;
}
栈中的数据一但不需要被使用,就会被内存删除.使用有,不使用没有,效率高
堆中的数据一旦被构建,就不能随便删除.效率比较低,它的删除依赖垃圾回收机制
jvm判断删除,用户没办法控制.
2) 局部变量没有默认值,使用之前必须先初始化;
按照课件上讲解的内容进行介绍;
3) 生命周期(创建分配内存空间到销毁清除内存空间的过程)
public class Sample {
public int add() {
int addResult = 1;
addResult = addResult+2;
return addResult;
}
public int subtract() {
int subResult = 1;
subResult = subResult-2;
return subResult;
}
public static void main(String[] args) {
main是整个程序的路口
Sample s = new Sample();
s.add();//开始局部变量addResult的生命周期,位于Java栈区;
结束局部变量addResult的生命周期,退回到main方法;
s.add();//开始局部变量addResult的生命周期,位于Java栈区;
结束局部变量addResult的生命周

期,退回到main方法;
}
}
调用Sample实例的add方法,开始局部变量addResult的生命周期,addResult位于Java栈区。
执行完毕Sample实例的add方法,结束局部变量addResult的生命周期,退回到main方法;
2. 实例变量
1) 在类中声明,它的作用域是整个类;
class Test {
private int n1=0;
private int n2=0;
public int add() {
int result = n1 + n2;
return result;
}
}
2) 实例变量有默认值,使用之前可无须初始化;
按照课件上讲解的内容进行介绍;
3) 生命周期(创建分配内存空间到销毁清除内存空间的过程)
class Test {
private int n1=0;
private int n2=0;
public int add() {
int result = n1 + n2;
n1 = n1+1;
n2 = n2+2;
return result;
}
public static void main(String[] args) {
Test t1 = new Test();
Test t2 = new Test();

t1.add();
t1.add();
t2.add();
}
}
创建Test实例,开始实例变量n1,n2的生命周期,n1,n2位于堆区。
执行完毕Test类的main方法,结束Test实例及它的实例变量n1,n2的生命周期,卸载Sample类,Java虚拟机运行结束。
jvm是否关闭也决定不了堆中的数据的消失,只有等到gc(垃圾回收器)处理完毕才结束生命周期
这里我们主要关心栈,堆和常量池
对于基础类型的变量和常量,变量和引用存储在栈中,常量存储在常量池中
栈中的数据大小和生命周期是可以确定的,当没有引用指向数据时,这个数据就会消失。
堆中的对象的由垃圾回收器负责回收,因此大小和生命周期不需要确定,具有很大的灵活性。
对于字符串:其对象的引用都是存储在栈中的,如果是编译期已经创建好(直接用双引号定义的)的就存储在常量池中,如果是运行期(new出来的)才能确定的就存储在堆中。
String类型使用equals比较的是对象的内容
==:比较地址
如以下代码:
Java代码 收藏代码
St

ring s1 = "china";
String s2 = "china";
String s3 = "china";
String ss1 = new String("china");
String ss2 = new String("china");
String ss3 = new String("china");
ss1==ss2: false
ss1.equals(ss2):true
常量池位于堆区间:主要存放基本数据类型的变量值,String类型的变量值
final和static修饰变量值,所有对象在常量池构建时
先不构建,先查看当前池是否有对应值.如果有直接指向
如果没有先创建后指向
对于基础类型的变量和常量:变量和引用存储在栈中,常量存储在常量池中,
创建的对象位于堆区间
如以下代码:
Java代码 局部变量保存在栈中 常量保留在常量池
int i1 = 9;
int i2 = 9;
int i3 = 9;
public static final int INT1 = 9;
public static final int INT2 = 9;
public static final int INT3 = 9;
栈有一个很重要的特殊性,就是存在栈中的数据可以共享
编译器先处理int i1 = 9;首先它会在栈中查找栈否有9这个值,如果没找到,就将9存放进来,
然后将i1指向9,接着处理int i2 = 9;因为在栈中已经有9这个值,不会再创建9.直接
使用已经存在的变量9.
对于成员变量和局部变量:成员变量就是方法外部,类的内部定义的变量;局部变量就是方法或语句块内部定义的变量。局部变量必须初始化。
形式参数是局部变量,局部变量的数据存在于栈内存中。栈内存中的局部变量随着方法的消失而消失。
成员变量存储在堆中的对象里面,由垃圾回收器负责回收。
注意:栈里只有一个9 ,i1,i2,i3 都指向9 。
3. 操作符
程序的基本功能就是处理数据,程序用变量来表示数据。任何编程语言都有自己的操作符,Java语言也不例外。操作符
能与相应类型的数据组成表达式,来完成相应的运算。

一般情况下,不用去刻意记住操作符的优先级,当不能确定操作符的执行顺序时,可以使用圆括号来显示指定运算顺序。
1) 赋值操作符:
= : int x=0,i=1,j=1;
a *= b : 这里的”*=“由操作符”*”和”=“复合而成,它等价于 a=a*b; 这种复合操作符能使程序变得更加简洁。
a = a*b;
/= : a/=b 等价于 a=a/b;
%= : a%=b 等价于 a=a%b;
a +=b a=a+b
...
首先来看下面两行代码:
x=(x的类型)(x+1) 和 x+=1相等
x+=1 ==> x= x+1
short s1 = 1;
s1 = s1 + 1; short+1 超过short类型的范围
需要转换成 short = (short)(s1+1)
0111 1111 1111 1111(short

最大值)
short最大值+1
1000 0000 0000 0000(有符号位 符号位为1表示负数)
符号位不变,执行取反+1
1000 0000 0000 0000 2^15(有符号位 -32768)
对于稍微有点Java经验的人来说,这个是非常简单的问题,他们肯定会说 这样是无法通过编译的。首先,因为short类型是16位的,而int类型是32位的,在进行(s1+1) 运算时,自动将s1提升到32位,然后与1相加,得到的结果是32位的,而此时s1=s1+1; 必然报错,因为这样会丢失2个字节的精度,这是不容许的。但是你可以执行强转:
s1=(short)(s1+1); 这样就没问题了.
现在我们再看下面这两行代码:
short s1 = 1;
s1 +=1;
许多程序员都会认为这里的表达式(s1 +=1)只是上面表达式(s1 = s1 + 1)的简写方式,但是这并不十分准确。实际是(如果左右两边类型不相同 s1 = (s1对应的类型)(s1+1)
如果左右两边类型相同 换言之没有越界现象 可以简写成 s1 = s1+1)
这两个表达式都被称为赋值表达式。开头那条语句使用的是简单赋值操作符(=),而这里这条语句使用的是复合赋值操作(+=)。
换句话说,复合赋值表达式自动地将它们所执行的计算的结果转型为其左侧变量的类型。如果结果的类型与该变量的类型相同,那么这个转型不会造成任何影响。
然而,如果结果的类型比该变量的类型要宽,那么复合赋值操作符将悄悄地执行一个窄化原始类型转换。
但是我们让JVM自动的为我们进行窄化转换这样好吗?我们来看下下面这个问题
short s1=Short.MAX_VALUE;//32767
s1+=1;
System.out.println(s1);
你可能会认为结果是32768,但是你一运行就会发现它会打印出:-32768,此时你也许幡然醒悟,原来我们丢失了精度,所以我们在用复合赋值操作(+=)的时候要特别注意,这时它会窄化原始类型转换(即使会丢失精度)
s+=1 ========>s=(s对应的类型)
2) 比较操作符
> : 大于
>= : 大于等于
< : 小于
<= : 小于等于
以上操作符只适用于整数类型和浮点数类型;
int a=1,b=1;
double d=1.0;
boolean result1 = a>b; //result1的值为false;
boolean result2 = a 当小范围与大范围进行比较时,jvm会先将小范围类型
转换成大范围类型在进行比较.
boolean result3 = a>=d; //result3的值为true;
boolean result4 = a<=b; //result4的值为true;
instanceof: 判断一个引用类型所引用的对象是否是一个类的实例。该操作符左边是一

个引用类型,右边是一个类
名或接口名。形式如下:
Student stu = new Student();
obj instanceof ClassName
stu instanceof Student;
stu instanceof Object;
stu instanceof Teacher;
类型在转换之前,只有instanceof比较的对象返回为ture才能
进行类型转换。否则报错类型转换异常
或者
obj instanceof InterfaceName

例如:
instanceof:判断引用属于那种类型
(默认都属于object类型)
String a = "zs";

System.out.println(a instanceof String); //输出true;
3) 相等操作符
== : 等于
基本类型比较 == 比较内容
引用类型比较 == 比较地址
!= : 不等于
基本类型比较(==比较内容),先将小范围数据类型
转换成大范围数据类型再进行比较
既可以是基本类型,也可以是引用类型:
a. 基本类型:
int a=1,b=1;
float c=1.0f;
double d=1.0;
System.out.println(a==b); //输出true;
System.out.println(a==c); //输出true;
System.out.println(a==d); //输出true;
System.out.println(c==d); //输出true;

b. 引用类型:
这两个引用变量必须都引用同一个对象,结果才为true.
String s1 = new String(“zs");
String s2 = new String(“zs");
String s3 = s1;
System.out.println(s1 == s2); //输出false;
System.out.println(s1 == s3); //输出true;
System.out.println(s2 == s3); //输出false;
4) 数学运算操作符

+ : 数据类型值相加或字符串连接;
a. 数据类型值相加;
int a=1+2; //a值为3;
先进行运算 后进行类型转换
double b=1+2; //b值为3.0;
先进行转换 后进行运算
double b=1+2.0; //c值为3.0;
先进行转换 后进行运算 再进行转换
int b = (int)(1+2.0); //b值为3.0
b. 字符串连接;
所有与字符串相加的类型最后转换成字符串
System.out.println(“3”+”1”); //输出31
System.out.pr

intln(1+2.0+"a"); //输出3.0a
System.out.println(1+2.0+"a"+true); //输出3.0atrue
System.out.println(“a1”+2); //输出a12
System.out.println(1+"a"+2); //输出1a2
System.out.println(1+”1”+2) 112
/ : 整除, 如操作数均为整数,运算结果为商的整数部分
int a1=12/5; //a1变量的取值为2
int a2=13/5; //a2变量的取值为2
int a3=-12/5; //a3变量的取值为-2
int a4=-13/5; //a4变量的取值为-2
int a5=1/5; //a5变量的取值为0
double a6=12/5; //a6变量的取值为-2.0
x/y=12.5/5.0=2.5
int(x/y)=int(2.5)=2
(int)x/y=12/5.0=2.4
% : 取模操作符, 如操作数均为整数,运算结果为商的整数部分
int a1=1%5; //a1变量的取值为1
int a2=13%5; //a2变量的取值为3
double a3=1%5; //a3变量的取值为1.0

5) 移位操作符
>> : 算术右移位运算,也称做带符号右移位运算。
1100 (12) ->1 0110 (6)
1000 0000 (128) ->2 0010 0000 (32)
1000 0010 (130) ->2 0010 0000 32
移动位数n 如果n>32 使用n-32做为移动的位数
int a1 = 12 >> 1; //a1变量的取值为6;
int a2 = 128 >> 2; //a2变量的取值为32;
int a3 = 130 >> 2; //a3变量的取值为32;
int a3 = 12 >> 33 ; //a3变量的取值为6;
算数右移动的公式: 数字(正数)/2^n(n表示移动位数).
即使除不尽也不要紧,商就是最后需要保留数(计算的数)
注:a. 对12右移一位的过程为:舍弃二进制数的最后一位,在二进制数的开头增加一位符号位,由于12是正整数,因此增加的符号位为0;
b. 对-12右移二位的过程为:舍弃二进制数的最后二位,在二进制数的开头增加二位符号位,由于-12是负整数,因此增加的符号位为1;
int a4 = -13 >> 2 == -4
-10 = 1000 1010(源码—>补吗) ==>1111 0101+1
==>11110110>>2 ==>1111 1101(补吗—>源码) 取反+1
1000 0010+1==>1000 0011==-3
如果能除尽可以使用公式:数字/2^n(n表示移动位数) 前面加个-
如果不能除尽使用取反原始方法求值(e.g -13 先获取

-13在内存中
补吗,再进行>>2运算得到新的补吗,再反退回源码获取最后的值)
-13 1000 1101(源码—>补吗) 取反+1
1111 0011(补吗)>>2
1111 1100(新补吗—>源码) 取反+1
1000 0100(-4)
-12>>1 ==1000 1100 取反 1111 0011+1==>1111 0100(补吗)==>1111 1010
取反+1==>1000 0110==-6
-14>>1=-7
c. 表达式" a>>b " 等价于: a/(2^b)
右移33位相当于右移1位。
右移n位相当于除以2的n次方,大于32则相当于n-32位
12 /2 =6
>>> : 逻辑右移位运算,也称为不带符号右移位运算。高位补0
int a1 = 12 >>> 1; //a1变量的取值为6;
右移运算,将">>"符号左边的操作数向右移动,移动的位数为">>"符号右边的操作数,如果是正数,在左边空位上补"0",如果为负数,则在左边的空位中补1,例:016 >> 3,将八进制数016转换成二进制结果为"001 110"(八进制的一位对应二进制中的三位),将其右移3位,低位"110"被移出,因为是正数,在高位中补三个“0“,结果为"000 001"转换成八进制结果为"1",其十进制的结果也为"1".
负数右移运算,例:-18 >> 2,十进制负数的二进制,就是该十进制数的补码,补码的计算是先将正数转换成二进制为"10010",将其取反后的结果为"01101",然后将取反后的值加1结果为"01110","01110"就是"-18"的二 进制,将其右移两位,把低位"10"移出,在高位补1(负数补1)结果为"11011",将负数二进制转换成十进制,将"11011"减1结果为"11010",然后取反得到值为"00101","101"的十进制为5,因为符号位为1,所以结果为-5
<< : 左移位运算,也称为不带符号左移位运算。
左移:由于没有符号位,对于负数而言,也不需要求负数的源码.可以直接使用负数对应的正数的补吗来进行移位运行
不需要分情况,可以直接使用公式:数字(不区分正负数)*2^n(n表示移动位数)
0000 1100—> 0001 1000 |
0000 1100-> 0011 0000
1000 0000-> 0010 0000 0000
1000 0001-> 0010 0000 0100
int a1 = 12 << 1; //a1变量的取值为24;
int a2 = -12 << 2; //a2变量的取值为-48;
int a3 = 128 << 2; //a3变量的取值为512;
int a4 = 129 << 2; //a4变量的取值为516;
注:a. 对12左移一位的过程为:舍弃二进制数的开头一位,在二进制数的尾部增加一个0;
b. 对-12左移二位的过程为:舍弃二进制数的开头二位,在二进制数的尾部增加二个0;
6) 位运算操作符
10000&01111 = 00000

& : 与运算,对两个操作元的每个二进制位进行与运算,运算规则为:1&1->1, 1&0->0, 0&1->0, 0&0->0;
全1为1,有0为0
10000|01111 = 11111
| : 或运算,对两个操作元的每个二进制位进行或运算,运算规则为:1|1->1, 1|0->1, 0|1->1, 0|0->0;
全0为0,有1为1
正数127(0111 1111) 高4不变 底4位置零 &
^ : 异或运算,对两个操作元的每个二进制位进行或运算,运算规则为:1^1->0, 1^0->1, 0^1->1, 0^0->0;
10^1 1010 ^ 0001 = 1011 = 11
两个值相同,为0, 不同为1;
~ : 取反运算, ~1->0, ~0->1;
10 ~10
0000 1010(源码 补吗)
1111 0101(补吗—>源码) 取反+1 1000 1010+1 1000 1011
1000 1011 (-11)
7) 逻辑操作符

短路操作符,如果能根据操作左边的布尔表达式就能推算出整个表达式的布尔值,将不执行操作符右边
的布尔表达式;
&&:左右两边都为true,整个表达式为true
||:左右两边一边为true,整个表达式为true
8) 条件操作符(三目运算符)
布尔表达式 ? 表达式1 : 表达式2
如果布尔表达式的值为true, 就返回表达式1的值, 否则返回表达式2的值。
int score = 61;
String result = score>60?”及格":"不及格";
注意:
String类型控制部分来自于?后面给定的对象类型
如果此时不是”及格”和”不及格” 而是 true和false
只能用boolean
boolean result = score>=90?true:false
4. 类型转换
1) 使用在基本数据类型和实例对象之间的转换。
2) 隐式转换和显式转换
3) 隐式转换是在运行期间转换,从子类转换到父类。第五章会详细讲解。
4) 显式转换,缩小变化。强制类型转换
自动类型转换,也称隐式类型转换,是指不需要书写代码,由系统自动完成的类型转换。由于实际开发中这样的类型转换很多,所以Java语言在设计时,没有为该操作设计语法,而是由JVM自动完成。
转换规则
从存储范围小的类型到存储范围大的类型。
具体规则为:
byte→short(char)→int→long→float→double
也就是说byte类型的变量可以自动转换为short类型,示例代码:
byte b = 10; int b = 128;
int i = b; byte i = (byte)128; -128
这里在赋值时,JVM首先将b的值转换为short类型,然后再赋值给sh。
在类型转换时可以跳跃。示例代码:
byte b1 = 100;
int n = b1;
注意问题
在整数之间进行类型转换时,数值不发生改变,而将整数类型,特

别是比较大的整数类型转换成小数类型时,由于存储方式不同,有可能存在数据精度的损失。
强制类型转换,也称显式类型转换,是指必须书写代码才能完成的类型转换。该类类型转换很可能存在精度的损失,所以必须书写相应的代码,并且能够忍受该种损失时才进行该类型的转换。
转换规则
从存储范围大的类型到存储范围小的类型。
具体规则为:
double→float→long→int→short(char)→byte
语法格式为:
(转换到的类型)需要转换的值
示例代码:
double d = 3.10;
int n = (int)d;
这里将double类型的变量d强制转换成int类型,然后赋值给变量n。需要说明的是小数强制转换为整数,采用的是“去1法”,也就是无条件的舍弃小数点的所有数字,则以上转换出的结果是3。
整数强制转换为整数时取数字的低位,例如int类型的变量转换为byte类型时,则只取int类型的低8位(也就是最后一个字节)的值。
示例代码:
int n = 123;
byte b = (byte)n;
int m = 128;
byte b1 = (byte)m;-128 10101110
则b的值还是123,而b1的值为-128。b1的计算方法如下:
l 注意问题
强制类型转换通常都会存储精度的损失,所以使用时需要谨慎
5. 条件语句
有些程序代码只有满足特定条件的情况下才会被执行,Java语言支持两种条件处理语句:

i 1) if ... else
照书上讲的内容先讲if...else的语法。
a. if后面的表达式必须是布尔表达式,而不能为数字类型,例如下面的if(x)是非法的。

if和else if是并列关系,一次只能有一种情况被执行到.即使有多条语句
都满足条件,也不可能执行多种情况.
int x=0;
if(x) { //编译出错
System.out.println("x不等于0");
} else {
System.out.println("x等于0");
}
b. 假如if语句或else语句的程序代码块中包括多条语句,则必须放在大括号{}内。若程序代码块只有一条语句则可以不用大括号{}。流程控制语句(如if...else语句)可作为一条语句看待。
最好都适用{}语句
e.g
if(true)
Test test = new Test();
这个程序虽然只有一句话,但是产生两个执行步骤,
1.Test test;
2.new Test();
对于内存理解也是2句话.所以必须添加{}才能编译通过.
if(true)
Test test = new Test();
此时代码会报错
1.Test test = new Test();实际是两句话
Test test; test = new Test();
2.if后面如果不跟大括号只能省略一句
3.省略的第一句中声明的变量test
再第二句中不存

在,test的生命周期只在
if的语句中,不在if的外围
Integer.parseInt(args[0]):args[0]接受终端传入的值,该值时字符串类型
如果需要将字符串转换成整形.args[0] 表示接受第一个值,可以有多个值
ArrayIndexOutOfBoundsException:数组越界 0 表示第一个值
课堂练习:1) 写一个方法实现分时问侯, 如是8点至12点,返回"上午好", 12点至14点,返回"中午好",
14点至18点,返回"下午好", 其它时间返回"晚上好"
public String sayHello(int hour) {
String msg;
if(hour >=8 && hour < 12)
msg = "上午好";
else if(hour>=12 && hour <14)
msg = "中午好";
else if(hour>=14 && hour <18)
msg = "下午好";
else
msg = "晚上好";

return msg;
}
2) 写一个方法判断某一年是否为闰年。
标准:1) 能被4整除,但不能被100整除;

2) 能被400整除;

public String isLeapYear(int year) {
if((year%4==0 && year%100!=0) || (year%400==0))
return “LeapYear”;
else
return “Year”;
}


2) switch
语法:switch(expr) {
case value1:{
statements;
break;
…}
case valueN
statments;
break;
default:
statements;
break;
}
a. expr的类型必须是byte, short, char或者int;
b. valuesN类型必须是byte, short, char或者int, 该值必须是常量。各个case子句的valueN值不同;
c. 当switch表达式的值不与任何case子句匹配时,程序执行default子句,假如没有default子句,则程序直接
退出switch语句。default子句可以位于switch语句

中的任何位置。永远都是最后被匹配
d. 如果switch表达式与某个case表达式匹配,或者与default情况匹配,就从这个case子句或default子句开始执行。假如遇到break,就退出整个switch语句,否则依次执行switch语句中后续的case子句,不再检查case表达式的值。
e. switch语句的功能也可以用if...else语句来实现。但switch语句会使程序更简洁,可读性更强。而if...else功能更为强大。
课堂练习:1) 写一个方法,能实现数值星期和英文星期的转换,如0会转换为Sunday, 1会转换为Monday。
public String switchWeekLabel(int week) {
String result;

switch(week) {
case 0:
result = “Sunday”;
break;
case 1:
result = “Monday”;
break;
case 2:
result = “Tuesday”;
break;
case 3:
result = “….”;
break;
case 4:
result = "星期四";
break;
case 5:
result = "星期五";
break;
case 6:
result = "星期六";
break;
default:
result = “error”;
}
return result;
}

6. 循环语句
循环语句的作用是反复执行一段代码,直到不满足循环条件为止。循环语句一般应包括如下四部分内容:
. 初始化部分:用来设置循环的一些初始条件,比如循环控制变量的初始值;
. 循环条件: 这是一个布尔表达式,每一次循环都要对该表达式求值,以判断到底继续循环还是终止循环。
. 循环体: 这是循环操作的主体内容,可以是一条语句,也可以是多条语句;
. 迭代部分: 用来改

变循环控制变量的值,从而改变循环条件表达式的值;
Java语言提供三种循环语句:for语句、while语句和do...while语句。for语句、while语句在执行循环体之前
测试循环条件,而do...while语句在执行循环体之后测试循环条件。因此for语句、while语句有可能连一次循
环都未执行,而do...while至少执行一次循环体。

while和do.....while的循环体中,如果先写i++
最后求出的count值偏大,先写count+=i,后写i++
最后求出的count值偏小.
1) for循环
初始化部分—>循环条件—>循环体—>迭代部分—>循环条件—>循环体.....
语法:for(初始化部分;循环条件;迭代部分) {
循环体
}
int i=10,count=0;
do {
count+=i;
i++;
}while(i<10);
for(int i=1;i<10;i++) {
System.out.println(i);
}
int i=10,count=0;
while(i<10) {
i++;
count += i;
}
System.out.println(count);
在执行for语句时,先执行初始化部分,这部分只会被执行一次;
接下来计算作为循环条件的布尔表达式,如果为true,就执行循环体;
接着执行迭代部分,然后再计算作为循环条件的布尔表达式,如此反复;
课堂练习:1) 写一方法,完成计算从1加到100的和;
public int sum() {
int result = 0;
for(int i=1;i<=100;i++) {
result = result + i;
}
return result;
}
2) 在练习一基础上,完成计算从1加到指定数值的和;

public int sum(int n) {
int result = 0;
for(int i=1;i<=n;i++) {
result = result + i;
}
return result;
}

2) while循环
语法:[初始化部分]
while(循环条件) {
循环体,包括迭代部分
}
当循环条件为true时,就重复执行循环,否则终止循环;
课堂练习:1) 用while循环完成计算从1加到指定数值的和;

public int sum(int n) {

int result = 0,i=1;
while(i<=n) {
result = result + i;
i=i+1;
}
return result;
}
3) do ... while循环
和while非常类似,只不过先执行循环体,然后再判断循环条件。

语法:[初始化部分]
do {
循环体,包括迭代部分
} while(循环条件);
while和do。。。while都有可能会多产生一个数据(大数据),for循环不会多产生数据
当迭代部分位于循环之上,换言之.先执行迭代部分在执行循环部分会产生多一条
的数据.do...while先执行再判断 while 先判断再执行
课堂练习:1) 用do...while循环完成计算从1加到指定数值的和;

public int sum(int n) {
int result = 0,i=1;
do {
result = result + i;
i=i+1;
} while(i<=n)
return result;
}

6. 循环语句中流程跳转
1) break: 终止当前或指定循环;
如果break是在if语句,会直接跳出if和前一个循环.
不能跳出多个循环.如果跳出制定的循环,可以在
循环方法前+ loop:
break后面不允许添加语句,添加语句会报错
break跳出制定的for循环后不会再进入到该for内部,即使
满足比较条件.
e.g
loop:for(…) {
for(…){
break loop:跳出第一个for循环
}
}
public int sum(int n) {
int result = 0,i=1;
while(i<=n) {
result = result + i;
i=i+1;
if(i>10)
break;
}
return result;
}

实现1加到10;
2) continue: 跳过本次循环,执行下一次循环和break不相同.break跳出
循环后不会再进入循环.而continue当前循环的跳出不影响下一次
循环的进入,或执行标号标识的循环体。
如果跳出制定的循环,可以在循环方法前+ loop:
public int sum(int n) {
int result = 0;
for(int i=1;i<=100;i++) {
if(i%2==0)
continue;
result = resul

t + i;
}
return result;
}
实现指定范围内奇数的和;
3) label: 标号用来标识程序中的语句,标号的名字可以是任意的合法标识符。
continue语句中的标识必须定义在while、do...while和for循环语句前面;
break语句中的标识必须定义在while、do...while和for循环语句或switch语句前面;
仔细讲解课件上例子。
课堂练习:1) 往控制台上输出以下内容:

*
**
***
****
*****
******
*******
public class Test {
public static void main(String[] args) {
int n=7;
for(int i=1;i<=n;i++) {
for(int j=1;j<=n-i;j++) {
System.out.print(" ");
}
for(int j=1;j<=i;j++) {
System.out.print("*");
}
System.out.println();
}
}
}
2) 往控制台上输出以下内容:

*
***
*****
*******
*********
***********
*************
public class Test {
public static void main(String[] args) {
int n=7;
for(int i=1;i<=n;i++) {
for(int j=1;j<=n-i;j++) {
System.out.print(" ");
}
for(int j=1;j<=2*i-1;j++) {
System.out.print("*");
}
System.out.println();
}
}

}

课后练习:1.(Level 1) What is the difference between instance variables and local variables?
答:1) 作用范围不同: 实例变量作用范围为整个类,局部变量为某个方法或方法内代码块;
2) 实例变量有默认值,可不能初始化便可使用;局部变量没有默认值,必须初始化后才能使用;
2.(Level 1) What is the difference between && and &?
答:&符号左右两边的表达式每次都必须执行,&&操作符左边表达式如返回值为false,右边表达式将不
进行处理;
3.(Level 2) What is the difference between switch/case and if/else?
答:switch语句的功能也可以用if...else语句来实现。假如流程分支的条件表达式类型为byte、short、
int, long,使用switch语句会使程序更简洁,可读性更强。而if...else 功能更为强大。
4.(Level 2) What is the difference between while and do loop?
答:while进入循环体之前必须符号循环条件,do第一次进入循环体之前无须满足循环条件;
5.(Level 2) After execution of the following code fragment, what are the values of the
variables x, a, and b?
1. Int X,a=6,b=7;
2. X=a++ + b++;
A. X=15,a=7,b=8;
B. X=15,a=6,b=7;
C. X=13,a=7,b=8;
D. X=13,a=6,b=7;
答:c
6. (Level 2) Which of the following expressions are legal?(choose all that apply)
A. int x=6; x=!x; //!不适用于int值
B. int x=6; if(!(x>3)) {} //
C. int x=6; x=~x
答:A, B
7. (Level 3) What results after compile and run the following code?
1. public class Conditional {
2. public static void main(String argd[]){
3. int x=4;
4 System.out.println(“value is: “+((x>4)?99.9:9));
5. }
6.}
A. value is 99.9
B. value is 9
C. value is 9.0
D. A compiler error at line 5
答:c


相关文档
相关文档 最新文档