控制语句
控制语句分为三类:顺序、选择和循环
1.条件判断结构
用于判断给定的条件,然后根据判断的结果来控制程序的流程。
1.1 if单分支结构
语法结构:
if(布尔表达式){
语句块
}
【示例】if单分支结构(掷骰子游戏)
public class Main{
public static void main(String[] args){
//double d = Math.random(); //Math.random()生成一个[0,1)的随机数
int a = 1+(int) (Math.random()*6); //生成了[1,6]的随机整数
int b = 1+(int) (Math.random()*6);
int c = 1+(int) (Math.random()*6);
int count = a + b + c;
System.out.println("总计得分:"+count);
if(count>15){
System.out.println("今天手气不错!");
}
if(count>=10&&count<=15){
System.out.println("今天手气一般,喝口水,换换风水!");
}
if(count<10){
System.out.println("今天手气不怎么样,回家吧");
}
}
}
1.2 if-else双分支结构
语法结构:
if(布尔表达式){
语句块1
}else{
语句块2
}
【示例】if-else双分支结构(比较随机一个圆的周长和面积)
public class Main{
public static void main(String[] args){
//随机产生一个[0.0, 4.0)区间的半径,并根据半径求圆的面积和周长
double r = 4*Math.random();
double area = Math.PI * Math.pow(r,2);
double circle = 2 * Math.PI * r;
System.out.println("圆的半径:"+r); //Math.pow(r, 2)求半径r的平方
System.out.println("圆的面积:"+area);
System.out.println("圆的周长:"+circle);
if(area>=circle){
System.out.println("圆的面积大于等于周长!");
}else{
System.out.println("圆的周长大于面积!");
}
}
}
1.3 if-else if-else 多分支结构
语法结构:
if(布尔表达式){
语句块1
}else if(布尔表达式2) {
语句块2;
}……
else if(布尔表达式n){
语句块n;
} else {
语句块n+1;
}
【示例】if-else if-else 多分支结构
public class Main{
public static void main(String[] args){
int age = (int)(100*Math.random());
System.out.print("年龄:"+age+" 属于");
if(age<15){
System.out.println("儿童");
}else if(age<30){
System.out.println("青年");
}else if(age<45){
System.out.println("中年");
}else if(age<70){
System.out.println("老年");
}else{
System.out.println("老寿星");
}
}
}
1.4 switch 多分支结构
switch语句会根据表达式的值从相匹配的case标签处开始执行,一直执行到break语句处或者是switch语句的末尾。如果表达式的值与任一case值不匹配,则进入default语句(如果存在default语句的情况)。
ps:根据表达式值的不同可以执行许多不同的操作。switch语句中case标签在JDK1.5之前必须是整数(long类型除外)或者枚举,不能是字符串,在JDK1.7之后允许使用字符串(String)。
语法结构:
switch (表达式) {
case 值1:
语句序列;
[break];
case 值2:
语句序列;
[break];
… … … … …
[default:
默认语句;]
}
【示例】
public class Main{
public static void main(String[] args){
int grade = 3;
switch(grade){
case 1:
System.out.println("大学一年级");
break;
case 2:
System.out.println("大学二年级");
break;
case 3:
System.out.println("大学三年级");
break;
default:
System.out.println("大学四年级");
break;
}
}
}
2.循环结构
当型:
当布尔表达式条件为true时,反复执行某语句,当布尔表达式的值为false时才停止循环,比如:while与for循环。
直到型:
先执行某语句, 再判断布尔表达式,如果为true,再执行某语句,如此反复,直到布尔表达式条件为false时才停止循环,比如do-while循环。
2.1 while 循环
语法结构:
while (布尔表达式) {
循环体;
}
【示例】while循环结构:求1到100之间的累加和
public class Main{
public static void main(String[] args){
int i = 0;
int sum = 0;
while(i<=100){
sum += i; // sum = sum + i;
i++;
}
System.out.println("Sum= "+sum);
}
}
2.2 do while 循环(了解)
语法结构:
do {
循环体;
} while(布尔表达式) ;
【示例】do while循环结构:求1到100之间的累加和
public class Main{
public static void main(String[] args){
int i = 0;
int sum = 0;
do{
sum += i; // sum = sum + i;
i++;
}while(i<=100);
System.out.println("Sum= "+sum);
}
}
do-while总是保证循环体至少会被执行一次!
2.3 for 循环
语法结构:
for (初始表达式; 布尔表达式; 迭代因子) {
循环体;
}
【示例】for循环
public class Main {
public static void main(String args[]) {
int sum = 0;
//1.求1-100之间的累加和
for (int i = 0; i <= 100; i++) {
sum += i;
}
System.out.println("Sum= " + sum);
//2.循环输出9-1之间的数
for(int i=9;i>0;i--){
System.out.print(i+"、");
}
System.out.println();
//3.输出90-1之间能被3整除的数
for(int i=90;i>0;i-=3){
System.out.print(i+"、");
}
System.out.println();
}
}
【示例】无限循环
public class Main {
public static void main(String[] args) {
for ( ; ; ) { // 无限循环: 相当于while(true)
}
}
}
在for语句的初始化部分声明的变量,其作用域为整个for循环体,不能在循环外部使用该变量。
2.4 嵌套循环
在一个循环语句内部再嵌套一个或多个循环,称为嵌套循环。while、do-while与for循环可以任意嵌套多层。
【示例】使用嵌套循环实现九九乘法表
public class Main{
public static void main(String[] args){
for(int i=1;i<=9;i++){
for(int j=1;j<=i;j++){
System.out.print(j+"*"+i+"="+i*j+"\t");
}
System.out.println();
}
}
}
2.5 break语句和continue语句
在任何循环语句的主体部分,均可用break控制循环的流程。break用于强行退出循环,不执行循环中剩余的语句。
【示例】break语句——100以内的随机数,到88时终止
//产生100以内的随机数,直到随机数为88时终止循环
public class Main{
public static void main(String[] args){
int total = 0; //定义计数器
System.out.println("Begin");
while(true){
total++; //每循环一次计数器加1
int i = (int)Math.round(100*Math.random());
if(i==88){
break; //当i等于88时,退出循环
}
}
//输出循环的次数
System.out.println("Game over, used " + total + " times.");
}
}
【示例】continue语句:把100~150之间不能被3整除的数输出,并且每行输出5个
//把100~150之间不能被3整除的数输出,并且每行输出5个
public class Main{
public static void main(String[] args){
int w = 0; //定义计数器
for(int i=100;i<=150;i++){
//如果是3的倍数,则跳过本次循环,继续进行下一次循环
if (i % 3 == 0){
continue;
}
//否则(不是3的倍数),输出该数
System.out.print(i+"\t");
//根据计数器判断每行是否已经输出了5个数
w++;
if(w%5==0){
System.out.println();
}
}
}
}
2.6 带标签的break和continue(了解)
【示例】带标签的break和continue:控制嵌套循环跳转(打印101-150之间所有的质数)
//控制嵌套循环跳转(打印101-150之间所有的质数)
public class Main {
public static void main(String args[]) {
label: for (int i = 101; i < 150; i++) {
for (int j = 2; j < i / 2; j++) {
if (i % j == 0){
continue label;
}
}
System.out.print(i + " ");
}
}
}
3.方法
3.1 语句块
语句块(有时叫做复合语句),是用花括号扩起的任意数量的简单Java语句。块确定了局部变量的作用域。块中的程序代码,作为一个整体,是要被一起执行的。块可以被嵌套在另一个块中,但是不能在两个嵌套的块内声明同名的变量。语句块可以使用外部的变量,而外部不能使用语句块中定义的变量,因为语句块中定义的变量作用域只限于语句块。
3.2 方法
方法就是一段用来完成特定功能的代码片段,类似于其它语言的函数。
方法的声明格式:
[修饰符1 修饰符2 …] 返回值类型 方法名(形式参数列表){
Java语句;… … …
}
方法的调用方式:
对象名.方法名(实参列表)
【示例】
public class Main {
/** main方法:程序的入口 */
public static void main(String[] args) {
int num1 = 10;
int num2 = 20;
//调用求和的方法:将num1与num2的值传给add方法中的n1与n2
// 求完和后将结果返回,用sum接收结果
int sum = add(num1, num2);
System.out.println("sum = " + sum);//输出:sum = 30
}
/** 求和的方法 */
public static int add(int n1, int n2) {
int sum = n1 + n2;
return sum;//使用return返回计算的结果
}
}
注意:
1. 实参的数目、数据类型和次序必须和所调用的方法声明的形式参数列表匹配。
2. return 语句终止方法的运行并指定要返回的数据。
3. Java中进行方法调用中传递参数时,遵循值传递的原则(传递的都是数据的副本):
4. 基本类型传递的是该数据值的copy值。
5. 引用类型传递的是该对象引用的copy值,但指向的是同一个对象。
3.3 方法的重载(overload)
方法的重载是指一个类中可以定义多个方法名相同,但参数不同的方法。 调用时,会根据不同的参数自动匹配对应的方法。
重载的方法,实际是完全不同的方法,只是名称相同而已!
构成方法重载的条件:
1.不同的含义:形参类型、形参个数、形参顺序不同
2.只有返回值不同不构成方法的重载
如:int a(String str){}与 void a(String str){}
3.只有形参的名称不同,不构成方法的重载
如:int a(String str){}与int a(String s){}
3.4 递归结构
递归的基本思想就是“自己调用自己”,一个使用递归技术的方法将会直接或者间接的调用自己。
利用递归可以用简单的程序来解决一些复杂的问题。
比如:斐波那契数列的计算、汉诺塔、快排等问题。
递归结构包括两个部分:
1.定义递归头。解答:什么时候不调用自身方法。如果没有头,将陷入死循环,也就是递归的结束条件。
2.递归体。解答:什么时候需要调用自身方法。
【示例】递归:计算n!
public class Test {
public static void main(String[] args) {
long d1 = System.currentTimeMillis();
long result = factorial(10);
long d2 = System.currentTimeMillis();
System.out.println(10+"阶乘的结果是"+result);
System.out.println("递归费时:"+(d2-d1));
}
/*求阶乘的方法*/
static long factorial(int n){
if(n==1){ //递归头
return 1;
}else { //递归体
return n*factorial(n-1);
}
}
}
递归的缺陷:
简单的程序是递归的优点之一。但是递归调用会占用大量的系统堆栈,内存耗用多,在递归调用层次多时速度要比循环慢的多,所以在使用递归时要慎重。在要求高性能的情况下尽量避免使用递归,递归调用既花时间又耗内存。