逻辑控制
1. 顺序结构
顺序结构比较简单. 像我们之前写过的代码就是顺序结构的, 按照代码书写的顺序一行一行执行.
System.out.println("aaa");//运行结果aaa System.out.println("bbb");//运行结果bbb System.out.println("ccc");//运行结果ccc
如果调整代码的书写顺序, 则执行顺序也发生变化
System.out.println("aaa");// 运行结果aaa System.out.println("ccc");// 运行结果ccc System.out.println("bbb");// 运行结果bbb
2. 分支结构
2.1 if 语句
基本语法形式1
if(布尔表达式){ //条件满足时执行代码 }
基本语法形式2
if(布尔表达式){ //条件满足时执行代码 }else{ //条件不满足时执行代码 }
基本语法形式3:多分支的情况
if(布尔表达式){ //条件满足时执行代码 }else if(布尔表达式){ //条件满足时执行代码 }else{ //条件都不满足时执行代码 }
代码示例1:判定一个数字是奇数还是偶数
int num = 10; if (num % 2 == 0) { System.out.println("num 是偶数"); } else { System.out.println("num 是奇数"); }
代码示例2: 判定一个数字是正数还是负数
int num = 10; if (num > 0) { System.out.println("num 是正数"); } else if (num < 0) { System.out.println("num 是负数"); } else { System.out.println("num 是 0"); }
代码示例3: 判定某一年份是否是闰年
Scanner scanner = new Scanner(System.in); int year = scanner.nextInt(); if (year % 4 == 0 && year % 100 != 0 ||year % 400 == 0) { System.out.println(year + " 是闰年"); } else { System.out.println(year + " 不是闰年"); }
注意事项1 悬垂 else 问题
int x = 10; int y = 10; if (x == 10) if (y == 10) System.out.println("aaa"); else System.out.println("bbb");
if / else 语句中可以不加 大括号 . 但是也可以写语句(只能写一条语句). 此时 else 是和最接近的 if 匹配. 但是实际开发中我们不建议这么写. 最好加上大括号.
注意事项2 代码风格问题
// 风格1 int x = 10; if (x == 10) { // 满足条件 } else { // 不满足条件 } // 风格2 int x = 10; if (x == 10) { // 满足条件 } else { // 不满足条件 }
虽然两种方式都是合法的, 但是 Java 中更推荐使用风格1, { 放在 if / else 同一行.
注意事项3 分号问题
int x = 20; if (x == 10); { System.out.println("hehe"); } // 运行结果hehe,原因是多了一个分号后,语句遇到分号意味着结束,那么不管x是否等于10,输出语句都会执行。
2.2 switch 语句
switch (整数 | 枚举 | 字符 | 字符串) { case 内容1: { 内容满足时执行语句; [break;] } case 内容2: { 内容满足时执行语句; [break;] } ... default: { 内容都不满足时执行语句; [break;] } }
代码示例: 根据 day 的值输出星期
int day = 1; switch (day) { case 1: System.out.println("星期一"); break; case 2: System.out.println("星期二"); break; case 3: System.out.println("星期三"); break; case 4: System.out.println("星期四"); break; case 5: System.out.println("星期五"); break; case 6: System.out.println("星期六"); break; case 7: System.out.println("星期日"); break; default: System.out.println("输入有误"); break; }
根据 switch 中值的不同, 会执行对应的 case 语句. 遇到 break 就会结束该 case 语句.
如果 switch 中的值没有匹配的 case, 就会执行 default 中的语句. 我们建议一个 switch 语句最好都要带上 default.
注意事项1 break 不要遗漏, 否则会失去 "多分支选择" 的效果
int day = 1; switch(day) { case 1: System.out.println("星期一"); // break; case 2: System.out.println("星期二"); break; }
//运行结果 星期一 星期二
我们发现, 不写 break 的时候, case 语句会依次向下执行, 从而失去了多分支的效果.
注意事项2 switch 中的值只能是 整数|枚举|字符|字符串(char, byte, short, int, Character, Byte, Short, Integer, String, or an enum)
面试问题:不能做switch的参数的数据类型 有哪些? 答:long float double boolean
double num = 1.0; switch(num) { case 1.0: System.out.println("hehe"); break; case 2.0: System.out.println("haha"); break; }
//编译出错 Test.java:4: 错误: 不兼容的类型: 从double转换到int可能会有损失
注意事项3 switch 不能表达复杂的条件
// 例如: 如果 num 的值在 10 到 20 之间, 就打印 hehe // 这样的代码使用 if 很容易表达, 但是使用 switch 就无法表示. if (num > 10 && num < 20) { System.out.println("hehe"); }
注意事项4 switch 虽然支持嵌套, 但是很丑
int x = 1; int y = 1; switch(x) { case 1: switch(y) { case 1: System.out.println("hehe"); break; } break; case 2: System.out.println("haha"); break; }
代码的美观程度也是一个重要的标准.
综上, 我们发现, switch 的使用局限性是比较大的
3. 循环结构
3.1 while 循环
基本语法格式:
while(循环条件){ 循环语句; } 当表达式为真,则执行循环语句;语句执行完之后再判断表达式是否为真,如果为真,再次执行循环语句;然后再判断表达式是否为真……就这样一直循环下去,直到表达式为假,跳出循环。这个就是 while 的执行顺序。
循环条件为 true, 则执行循环语句; 否则结束循环.
代码示例1: 打印 1 - 10 的数字
int num = 1; while (num <= 10) { System.out.println(num); num++; }
代码示例2: 计算 1 - 100 的和
int n = 1; int result = 0; while (n <= 100) { result += n; n++; } System.out.println(num); //执行结果为5050
代码示例3: 计算 5 的阶乘
int n = 1; int result = 1; while (n <= 5) { result *= n; n++; } System.out.println(result);//执行结果为120
代码示例4: 计算 1! + 2! + 3! + 4! + 5!
int num = 1; int sum = 0; // 外层循环负责求阶乘的和 while (num <= 5) { int factorResult = 1; int tmp = 1; // 里层循环负责完成求阶乘的细节. while (tmp <= num) { factorResult *= tmp; tmp++; } sum += factorResult; num++; } System.out.println("sum = " + sum);
这里我们发现, 当一个代码中带有多重循环的时候, 代码的复杂程度就大大提高了. 而比较复杂的代码就更容易出错. 后面我们会采用更简单的办法来解决这个问题.
注意事项
1. 和 if 类似, while 下面的语句可以不写 { } , 但是不写的时候只能支持一条语句. 建议还是加上 { }
2. 和 if 类似, while 后面的 { 建议和 while 写在同一行.
3. 和 if 类似, while 后面不要多写 分号, 否则可能导致循环不能正确执行.
int num = 1; while (num <= 10); { System.out.println(num); num++; }
此时实际的 { } 部分和循环无关. 此时循环条件 num <= 10 恒成立, 导致代码死循环了.
3.2 break
break 的功能是让循环提前结束.
其实只要在循环中遇到break,就停止后期的所有循环,直接终止所有循环,所以while中的break是用于永久终止循环的
注意:while循环中0break语句除了会出现在switch语句,剩余的都要出现在while循环语句中。
代码示例: 找到 100 - 200 中第一个 3 的倍数
int num = 100; while (num <= 200) { if (num % 3 == 0) { System.out.println("找到了 3 的倍数, 为:" + num); break; //注意此时可以使用break,因为break此时在while循环中,虽然也在if条件句中 } num++; } //执行结果为102
3.3 continue
continue 的功能是结束本趟循环, 立即进入下一次循环.且continue后的程序不会再被执行。
代码示例: 找到 100 - 200 中所有 3 的倍数
int num = 100; while (num <= 200) { if (num % 3 != 0) { num++; // 这里的 ++ 不要忘记! 否则会死循环. continue; } System.out.println("找到了 3 的倍数, 为:" + num); num++; }
执行到 continue 语句的时候, 就会立刻进入下次循环(判定循环条件), 从而不会执行到下方的打印语句.
3.4 for 循环
基本语法
for(表达式1;表达式2;表达式3){
循环体;
}
表达式1: 用于初始化循环变量.,注意表达式1只在循环开始的时候执行1次
表达式2: 循环条件
表达式3: 更新循环变量.
注意:for循环的执行顺序为表达式1->表达式2->循环体->表达式3->表达式2->循环体->表达式3->表达式2->循环体->表达式3如此往下循环下去。
相比于 while 循环, for 循环将这三个部分合并在一起, 写代码时不容易遗漏.
代码示例1: 打印 1 - 10 的数字
for (int i = 1; i <= 10; i++) { System.out.println(i); }
代码示例2: 计算 1 - 100 的和
int sum = 0; for (int i = 1; i <= 100; i++) { sum += i; } System.out.println("sum = " + sum);//运算结果为5050
代码示例3: 计算 5 的阶乘
int result = 0; for (int i = 1; i <= 5; i++) { result *= i; }
代码示例4: 计算 1! + 2! + 3! + 4! + 5!
int sum = 0; for (int i = 1; i <= 5; i++) { int tmp = 1; for (int j = 1; j <= i; j++) { tmp *= j; } sum += tmp; } System.out.println("sum = " + sum);
注意事项 (和while循环类似)
1. 和 if 类似, for 下面的语句可以不写 { } , 但是不写的时候只能支持一条语句. 建议还是加上 { }
2. 和 if 类似, for 后面的 { 建议和 while 写在同一行.
3. 和 if 类似, for 后面不要多写分号, 否则可能导致循环不能正确执行.
3.5 do while 循环
基本语法
do{ 循环语句; }while(循环条件); 先执行循环语句, 再判定循环条件. 注意:do-while循环与while循环的不同在于:它会先执行一次“循环语句”,然后再判断表达式是否为真,如果为真则继续往复执行循环语句;如果为假,则终止循环。因此,do-while 循环至少要执行一次“循环语句”。
代码示例: 打印 1 - 10
int num = 1; do { System.out.println(num); num++; } while (num <= 10);
注意事项
1. do while 循环最后的分号不要忘记
2. 一般 do while 很少用到, 更推荐使用 for 和 while.
4.输入输出
4.1 输出到控制台
基本语法
System.out.println(msg); // 输出一个字符串, 带换行 System.out.print(msg); // 输出一个字符串, 不带换行 System.out.printf(format, msg); // 格式化输出 println 输出的内容自带 \n, print 不带 \n printf 的格式化输出方式和 C 语言的 printf 是基本一致的.
代码示例
System.out.println("hello world"); int x = 10; System.out.printf("x = %d\n", x)
格式化字符串
用到此表格时来查即可。
4.2 从键盘输入
使用 Scanner 读取字符串/整数/浮点数
import java.util.Scanner; // 需要导入 util 包 Scanner sc = new Scanner(System.in); System.out.println("请输入你的姓名:"); String name = sc.nextLine(); System.out.println("请输入你的年龄:"); int age = sc.nextInt(); System.out.println("请输入你的工资:"); float salary = sc.nextFloat(); System.out.println("你的信息如下:"); System.out.println("姓名: "+name+"\n"+"年龄:"+age+"\n"+"工资:"+salary); sc.close(); // 注意, 要记得调用关闭方法
执行结果如下:
请输入你的姓名: 宋彪 请输入你的年龄: 29 请输入你的工资: 19.9 你的信息如下: 姓名: 宋彪 年龄:29 工资:19.9
思考1:nextLine方法与next方 法都是可以在命令框中输入字符串,那么这两者有何区别呢?
答: nextline方法与next方法都是的区别在于使用next方法时在命令框输入时若有空格,那么空格后面我们所输入的字符串最终在输出的时候便不会再显示,而nextLine方法并不会,即在nextLin方法中,即使你带上了空格,最终并不会影响整个字符串的输出。
举例:假如我们使用nextLine方法的话,就算有空格也不会影响最终的输出。
假设我们使用了next方法的话,如果有空格,空格后面的内容是不会输出的,如下图所示:
此时我们会发现只输出了abc,def没有输出。
思考2:假设此时nextInt方法写在nextLine方法前,这样当我们在命令框中输入一个整数后,还会让我们有机会输入字符串
答:当然不能还用问哈哈,来看代码: public class chushi { public static void main(String[] args) { Scanner scanner=new Scanner(System.in); int a=scanner.nextInt(); String abc=scanner.nextLine(); System.out.println(a); System.out.println(abc); } }
此时我们的nextLine方法写在了nextInt方法后面,来看测试:
我们会发现当我们输入1后,并没有机会让我们再输入字符串了。
总结:一般在程序中nextInt方法不要写在nextLine方法前,这样当我们在命令框中输入一个整数后便会结束,根本不会有字符串的输入,nextInt方法写在nextLine方法后面此时就没问题了。
使用 Scanner 循环读取 N 个数字
Scanner sc = new Scanner(System.in); double sum = 0.0; int num = 0; while (sc.hasNextDouble()) { double tmp = sc.nextDouble(); sum += tmp; num++; } System.out.println("sum = " + sum); System.out.println("avg = " + sum / num); sc.close();
// 执行结果 10 40.0 50.5 ^Z sum = 150.5 avg = 30.1 注意事项: 当循环输入多个数据的时候, 使用 ^Z来结束输入 (Windows 上使用 ctrl + z, Linux / Mac 上使用 ctrl +d).