使用的教材是java核心技术卷1,我将跟着这本书的章节同时配合视频资源来进行学习基础java知识。
day008 控制流程(块作用域、条件语句、循环、确定循环、多重循环、中断流程)
与任何程序设计语言一样,Java使用条件语句和循环结构确定控制流程。
1.块作用域
块(即复合语句)是指由一对大括号括起来的若干条简单的Java语句。块确定了变量的作用域。一个块可以嵌套在另一个块中。下面就是在main方法块中嵌套另一个语句块的示例。
public class He
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
//第一次输入
System.out.print("what is your name?");
String name = in.nextLine();
//第二次输入
System.out.println("Hello old are you?");
int age = in.nextInt();
//输出
System.out.println("Hello,"+name+"。Next year,you'll be "+(age+1));
}
}
但是,不能在嵌套的两个块中声明同名的变量。例如,下面的代码就有错误,而无法通过编译:
{
int n;
......
{
int k;
int n;
}
}
2.条件语句
在Java中,条件语句的格式为:if (condition) statement 这里的条件必须用括号括起来。
与绝大多数程序设计语言一样,Java常常希望在某个条件为真时执行多条语句。在这种情况下,应该使用块语句。
例如:
if (yourSales >= target)
{
performance = "Satisfactory";
bonus = 100;
}
当yourSales大于或等于target时,将执行括号中的所有语句。
在Java中,更一般的条件语句格式如下所示:
if (yourSales>= target)
{
performance= "Satisfactory";
bonus = 100+0.01*(yourSales - target);
}
else
{
performance= "Unsatisfactory";
bonus=0;
}
其中else部分是可选的。else子句与最邻近的if构成一组。
重复地交替出现if...else if...是一种很常见的情况。
if (your Sales>= 2*target)
{
performance = "Excellent";
bonus=1000;
}
else if (yourSales>= 1.5*target)
{
performance= "Fine";
bonus = 500;
}
else if (yourSales>= target)
{
performance= "Satisfactory";
bonus = 100;
}
else
{
System.out.println("You're fired");
}
3.循环
当条件为true时,while循环执行一条语句(也可以是一个语句块)。一般格式为:while (condition) statement
如果开始循环条件的值就为false,则while循环体一次也不执行。
下面的程序将计算需要多长时间才能够存储一定数量的退休金,假定每年存人相同数量的金额,而且利率是固定的。
import java.util.Scanner;
public class He
{
public static void main(String[] args)
{
//read inputs
Scanner in = new Scanner(System.in);
System.out.print("How much money do you need to retire? ");
double goal = in.nextDouble();
System.out.print("How much money will you contribute every year? ");
double payment = in.nextDouble();
System.out.print("Interest rate in %: ");
double interestRate = in.nextDouble();
double balance = 0;
int years = 0;
//update account balance while goal isn't reached
while (balance < goal)
{
//add this year's payment and interest
balance += payment;
double interest = balance * interestRate/100;
balance+= interest;
years++;
}
System.out.println("You can retire in " +years+" years.");
}
}
运行的结果是:
while循环语句首先检测循环条件。因此,循环体中的代码有可能不被执行。如果希望循环体至少执行一次,则应该将检测条件放在最后。使用do/while循环语句可以实现这种操作方式。
它的语法格式为:do statement while (condition);
这种循环语句先执行语句(通常是一个语句块),再检测循环条件;然后重复语句再检测循环条件,以此类推。
在上面的程序中,首先计算退休账户中的余额’然后再询问是否打算退休:
do
{
balance+= payment;
double interest = balance*interestRate /100;
balance += interest;
year++;
//print current balance
......
//ask if ready to retire and get input
....
}
while (input.equals("N"));
只要用户回答“N”,循环就重复执行。这是一个需要至少执行一次的循环的很好示例,因为用户必须先看到余额才能知道是否满足退休所用。
完整的代码:
import java.util.Scanner;
public class He
{
public static void main(String[] args)
{
//read inputs
Scanner in = new Scanner(System.in);
System.out.print("How much money do you need to retire? ");
double goal = in.nextDouble();
System.out.print("How much money will you contribute every year? ");
double payment = in.nextDouble();
System.out.print("Interest rate in %: ");
double interestRate = in.nextDouble();
double balance = 0;
int year = 0;
String input;
//update account balance while goal isn't reached
do
{
//add this year's payment and interest
balance += payment;
double interest = balance * interestRate/100;
balance+= interest;
year++;
//print current balance
System.out.printf("After year %d, your balance is %,.2f%n",year, balance);
//ask if ready to retire and get input
System.out.print("Ready to retire? (Y/N) ");
input = in.next();
}
while (input.equals("N"));
}
}
4.确定循环
for循环语句是支持迭代的一种通用结构,利用每次迭代之后更新的计数器或类似的变量来控制迭代次数。
//将数字1~10输出到屏幕上。
for (int i = 1; i<=10; i++)
System.out.println(i);
for语句的第1部分通常用于对计数器初始化;第2部分给出每次新一轮循环执行前要检测的循环条件;第3部分指示如何更新计数器。
当在for语句的第1部分中声明了一个变量之后,这个变量的作用域就为for循环的整个循环体。如果在for语句内部定义一个变量,这个变量就不能在循环体之外使用。因此,如果希望在for循环体之外使用循环计数器的最终值,就要确保这个变量在循环语句的前面且在外部声明!另一方面,可以在各自独立的不同for循环中定义同名的变量。
使用for循环语句计算这个公式
int lotteryOdds = 1 ;
for (int i =1;i <= k;i++)
lotteryOdds = lotteryOdds*(n -i+1 )/i;
5.多重选择:switch语句
如果建立一个包含4个选项的菜单系统,可以使用下列代码:
Scanner in = new Scanner(System.in);
System.out.print("Select an option (1, 2, 3, 4) ");
int choice = in.nextlnt();
switch (choice)
{
case 1:
//...
break;
case 2:
//...
break;
case 3:
//...
break;
case 4:
//...
break;
default:
//bad input
//...
break;
}
switch语句将从与选项值相匹配的case标签处开始执行直到遇到break语句,或者执行到switchi吾句的结束处为止。如果没有相匹配的case标签,而有default子句,就执行这个子句。
需要注意的是:有可能触发多个case分支。如果在case分支语句的末尾没有break语句,那么就会接着执行下一个case分支语句。这种情况相当危险,常常会引发错误。
case标签可以是:
•类型为char、byte、short或int的常量表达式。
•枚举常量。
•从JavaSE7开始,case标签还可以是字符串字面量。
当在switch语句中使用枚举常量时,不必在每个标签中指明枚举名,可以由switch的表达式值确定。
6.中断控制流程语句
break语句。与用于退出switch语句的break语句一样,它也可以用于退出循环语句。
while (years<=100)
{
//add this year's payment and interest
balance += payment;
double interest = balance * interestRate/100;
balance+= interest;
if (balance >= goal)
break;
years++;
}
在循环开始时,如果years>100,或者在循环体中balance>=goal,则退出循环语句。
Java还提供了一种带标签的break语句,用于跳出多重嵌套的循环语句。有时候,在嵌套很深的循环语句中会发生一些不可预料的事情。此时可能更加希望跳到嵌套的所有循环语句之外。通过添加一些额外的条件判断实现各层循环的检测很不方便。
read_data
while (years<=100)
{
//add this year's payment and interest
balance += payment;
double interest = balance * interestRate/100;
balance+= interest;
if (balance >= goal)
break read_data;
years++;
}
上面的程序说明了break语句的工作状态。请注意,标签必须放在希望跳出的最外层循环之前,并且必须紧跟一个冒号。如果输入有误,通过执行带标签的break跳转到带标签的语句块末尾。对于任何使用break语句的代码都需要检测循环是正常结束,还是由break跳出。
最后,还有一个continue语句。与break语句一样,它将中断正常的控制流程。continue语句将控制转移到最内层循环的首部。
Scanner in = new Scanner(System.in);
while (sum < goal)
{
System.out.print("Enter a number: ");
n = in.nextlntO ;
if (n < 0)
continue;
sum += n; // not executed if n < 0
}
如果n<0,则continue语句越过了当前循环体的剩余部分,立刻跳到循环首部。
如果将continue语句用于for循环中,就可以跳到for循环的“更新”部分。
还有一种带标签的continue语句,将跳到与标签匹配的循环首部。
许多人容易混淆break和continue语句。选择的时候应分析具体用途再选。