流程控制
顺序结构
程序最基本的结构,若无特殊情况则一句一句执行,这个没什么好多介绍的
选择结构
if
语句
//格式1
if(布尔表达式){
//表达式为true就执行
}
//格式2
if(布尔表达式){
//表达式为true就执行
}else{
//表达式为false就执行
}
//格式3
if(布尔表达式1){
}else if(布尔表达式2){
}else if(布尔表达式N){
}else{
//上面可以有无限个分支,满足哪个就执行哪个
//都不满足才会走else语句
}
请按照如下要求写一个if
结构的语句
分数在 [90, 100] 之间的,为优秀
分数在 [80, 90) 之前的,为良好
分数在 [70, 80) 之间的,为中等
分数在 [60, 70) 之间的,为及格
分数在 [ 0, 60) 之间的,为不及格
在范围以外的都是错误数据
public class Test {
public static void main(String[] args) {
int score = 90;
if (score >= 90 && score <= 100) {
System.out.println("优秀");
} else if (score >= 80 && score < 90) {
System.out.println("良好");
} else if (score >= 70 && score < 80) {
System.out.println("中等");
} else if (score >= 60 && score < 70) {
System.out.println("及格");
} else if (score >= 0 && score < 60) {
System.out.println("不及格");
} else {
System.out.println("错误数据");
}
}
}
练习
判断一个年份是否是闰年
闰年:年份能被4整除且不能被100整除,或者能被400整除
public class Test {
public static void main(String[] args) {
int year = 2012;
//加好括号保证运算正常运行
if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) {
System.out.println("是闰年");
} else {
System.out.println("不是闰年");
}
}
}
这里就提一嘴代码格式,就以上面的代码为例子
public class Test {
public static void main(String[] args) {
int year=2012;
if((year%4==0&&year%100!=0)||(year%400==0)){
System.out.println("是闰年");
}else{
System.out.println("不是闰年");
}
}
}
可以看到,上面的代码挤成一坨,非常丑,即不好看代码可读性也很低
虽然IDEA支持快捷键格式化Ctrl+Alt+L
,但是还是建议养成良好的书写习惯,平常也可以多用用这个快捷键来看看格式化后的代码和自己的代码有什么区别,学习一下规范的写法
switch
语句
switch (表达式) {
case 常量值1: {
//语句1;
break;
}
case 常量值2: {
//语句2;
break;
}
default: {
//内容都不满足时执行语句;
break;
}
}
当表达式的值等于常量N的时候,就执行那个分支的语句,如果全都不符合就执行default
的语句
这个语句有一些注意点:
- 常量值表达式不能为
boolean long float double
类型 break
不能漏,否则会发生case
穿透
public class Test {
public static void main(String[] args) {
int day = 1;
switch (day) {
case 1:
System.out.println("星期一");
// break;
case 2:
System.out.println("星期二");
break;
}
//这里执行的结果就是
//星期一
//星期二
}
}
循环结构
while
循环
while(布尔表达式){
//表达式为true就进入循环
循环语句;
}
在使用循环结构的时候,我们一般要在循环语句里面对布尔表达式涉及到的量进行调整,从而控制循环执行的次数
下面写一个计算0-100的和的代码
public class Test {
public static void main(String[] args) {
int i = 0;
int sum = 0;
while (i <= 100) {
sum += i;
//对表达式涉及的量进行调整从而控制循环次数
i++;
}
System.out.println(sum);
}
}
break
和continue
break
用于跳出循环,continue
用于跳过循环中位于continue
后面的语句
举两个例子说明
public class Test {
public static void main(String[] args) {
int a = 0;
while (a < 10) {
a++;
System.out.println(a);
if (a == 5) {
break;
}
//a为5的时候跳出循环,相当于直接硬性结束循环
//结果为1 2 3 4 5
}
}
}
public class Test {
public static void main(String[] args) {
int a = 0;
while (a < 10) {
a++;
if (a == 5) {
continue;
}
//a为5的时候跳过后面的语句,直接进入下一次循环
System.out.println(a);
//结果为1 2 3 4 6 7 8 9 10
}
}
}
for
循环
for循环和while循环没有本质区别,但是写的更为简便,写两个等效的循环助于理解
public class Test {
public static void main(String[] args) {
for (int i = 1; i <= 100; i = i + 1) {
System.out.print(i+" ");
}
System.out.println();
int a = 1;
while (a <= 100) {
System.out.print(a+" ");
a = a + 1;
}
}
}
但是有几个注意点
- 代码调整部分并不是完全和while一样位于大括号内的最下方,而是在一个独立的区域,在大括号内代码运行完后执行
public class Test {
public static void main(String[] args) {
for (int a = 1; a <= 10; a++) {
if (5 == a) {
continue;
}
System.out.print(a + " ");
//这样只会跳过5,而不会死循环
}
//下面这个则是死循环写法
int b = 1;
while (b <= 10) {
if (5 == b) {
continue;
}
System.out.print(b + " ");
b++;
}
}
}
for循环的运行更像如下图所示
- 尽量不要在for循环内部修改循环变量,容易使for循环失控
- 建议for语句的循环控制变量的取值采用前闭后开区间写法
public class Test {
public static void main(String[] args) {
//前闭区间 指int a = 0; 后开区间 指a < 10;
for (int a = 0; a < 10; a++) {
System.out.println(a + " ");
}
System.out.println();
for (int a = 0; a <= 9; a++) {
System.out.println(a + " ");
}
//上下两个循环输出结果完全相同
//但是上面为前闭后开区间写法,下面为前闭后闭区间写法
//当我们使用前闭后开区间写法时,可以直观的看出循环了10次,而下面的写法不能
}
}
do while
循环
先执行一次然后才判断是否循环的语句,也就是说无论条件是否符合,至少都能运行一次
public class Test {
public static void main(String[] args) {
int a = 0;
do {
System.out.println(a + " ");
} while (a >= 1);
//while后面有个分号别忘了
//会输出个 0
}
}
输入与输出
学过了选择结构和循环结构后,我们往往就会遇到一些需要接收数据和输出数据的题目,所以这里简单介绍一下Java中的输入和输出如何操作
输出
基本语法
System.out.println(msg);
System.out.print(msg);
System.out.printf(format, msg);
前面两个我们已经有使用过,第一个和第二个的区别就是第一个自带\n
(也就是换行)
有关于printf
的格式化输出,这里就通过一个例子来帮助理解
public class Test {
public static void main(String[] args) {
int a = 0;
System.out.printf("a = %d",a);
//相当于定好一个格式,然后中间插入一些指示符,指示符依次对应着后面的变量
}
}
一些常见的指示符如下
数据类型 | 指示符 |
---|---|
int | %d |
double | %lf |
float | %f |
字符串 | %s |
字符 | %c |
long | %ld |
实际上如果学过C语言,就当作printf
但是Java中也不常使用这种打印格式,所以了解即可
输入
在Java中,我们要读取键盘的输入数据,需要用到一个类,这个类叫做Scanner
但是详细的我们会在类和对象章节了解,这里我们只需要记住怎么调用这个类就行
import java.util.Scanner;
//首先是导包,因为是调用事先定义好的代码所以要导入
public class Test {
public static void main(String[] args) {
//然后是创建一个Scanner类,下面例子中sc是名字,随便起,其他的都是固定的
Scanner sc = new Scanner(System.in);
//中间就可以使用这个类了
//使用完要关闭,格式固定
sc.close();
}
}
那么我们要怎么使用这个类来接收键盘输入的信息呢?延续上面的例子,我们有如下格式可以接收数据
sc.next();//接收数据直到遇到空格或回车为止,通常用于接收单个字符
sc.nextLine();//接收下一行整行的数据,通常用于接收字符串
sc.nextInt();//接收int整型
sc.nextFloat();//接收float类型数据
//其他的各个类型都是差不多的不写了
另外Scanner
中还提供了判断是否有输入的语句
sc.hasNext();//判断是否有输入,有就返回true
//其他的都是类型格式就不写了
在一些多组数据输入的题目中,这个还是很好用的
Scanner的使用和注意点
写一个接收姓名、年龄、电话这三个数据的代码,并进行输出
public class Test {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入姓名");
String name = sc.nextLine();
System.out.println("请输入年龄");
int age = sc.nextInt();
System.out.println("请输入电话号码");
String tele = sc.nextLine();
System.out.println("姓名:" + name + " 年龄:" + age + " 电话:" + tele);
sc.close();
}
}
上面的代码看似没有问题,但是倘若我们输入zhangsan 18
并按下回车后,会发现代码直接结束了
那么是为什么呢?
实际上我们不妨回忆一下,我们上面输入数据的时候是不是按照下面这样的格式输入的
zhangsan \n
18 \n
那么读取又是怎么读的呢?
首先是读取一整行的数据,直到读到\n
直接结束(这里会把换行拿走但是不存)。那么这个时候第一行被拿走了,剩下第二行的18\n
,那么由于nextInt()
只会读取int
那么拿走了18
剩下了\n
。所以在我们下一次读取的时候,nextLine()
会因为读到了这个\n
直接结束,而不会让我们输入数据了
那么我们要怎么解决这个问题呢?
在我们每一次调用读取类型的方法的时候,假如我们后面还要读取数据,就在读取类型的那一次读取后面加一次空读取,把换行拿走
修改后的代码如下
public class Test {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入姓名");
String name = sc.nextLine();
System.out.println("请输入年龄");
int age = sc.nextInt();
//加一个空读取
sc.nextLine();
System.out.println("请输入电话号码");
String tele = sc.nextLine();
System.out.println("姓名:" + name + " 年龄:" + age + " 电话:" + tele);
sc.close();
}
}
那么上面的这个代码就可以正常运行了
使用Scanner循环读取N
个数字,并求取其平均值
这里主要就是涉及到Scanner
判断输入方法的使用,但是实际上没什么大变化,直接上代码
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
//创建计数器和总和
int count = 0;
int sum = 0;
//创建Scanner
Scanner sc = new Scanner(System.in);
System.out.println("请输入第一个数字");
//循环接收
while(sc.hasNextInt()){
sum += sc.nextInt();
count++;
System.out.println("请输入第"+(count+1)+"个数字");
}
//打印
System.out.println((double)sum/count);
//关闭Scanner
sc.close();
}
}
在我们自己编译的时候,可以通过按Ctrl+D
来停止输入
有些地方说Windows按Ctrl+Z
,Linux按Ctrl+D
,但是笔者这里实测IDEA我只能Ctrl+D
,原因未知
(反正一个不行就试试另一个就好了)
练习
猜数字游戏
要求:随机生成0~100的数字,在每一次输入后判断输入的数是大于,小于,还是等于随机数。
大于则输出猜大了
,并让玩家重新输入。小于则输出猜小了
,并让玩家重新输入。等于则输出恭喜你,猜对了
随机数的生成
这里也要用到Java中的一个类,Random
类,和Scanner
的用法上有些类似
import java.util.Random;
//导入包 你new Random的时候点击Tab键会自动导入
public class Test {
public static void main(String[] args) {
//新建一个Random,固定格式暂时不用理解
Random r = new Random();
}
}
然后我们就可以用我们刚刚新建的r
去随机一个数字
public class Test {
public static void main(String[] args) {
Random r = new Random();
int num = r.nextInt(101);
//这个代码的意思是 随机生成一个大于等于0,小于101的数字 [0,101)
}
}
起点只能为0
,那么假如我们想要生成50~100
的随机数,那就可以利用加法运算
Random r = new Random();
int num = r.nextInt(51) + 50;
生成完了数字,接下来就是接收玩家输入的数字,并且做出判断
由于我们不知道玩家要猜多少次,所以用一个死循环。然后分别建立三个分支,对应三种情况。在等于的情况输出胜利语句,并且使用break
直接跳出循环
while(true){
System.out.println("请输入猜测数");
int guess = sc.nextInt();
if (guess == num) {
System.out.println("恭喜你猜对了");
System.out.println("游戏结束");
break;
} else if (guess < num) {
System.out.println("猜小了");
} else {
System.out.println("猜大了");
}
}
代码总览
import java.util.Random;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Random r = new Random();
int num = r.nextInt(101);
while(true){
System.out.println("请输入猜测数");
int guess = sc.nextInt();
if (guess == num) {
System.out.println("恭喜你猜对了");
System.out.println("游戏结束");
break;
} else if (guess < num) {
System.out.println("猜小了");
} else {
System.out.println("猜大了");
}
}
sc.close();
}
}