第三章 选择

以下内容为博主阅读对应书籍或资料(分栏名告知)总结的笔记,由部分书内原句、部分佐证、部分博主自身理解组成,有出错处万望告知,不胜感谢。
本类文章主为巩固博主自身学习,顺带与同行互通有无,若有侵权望告知!

程序可以基于条件决定执行哪些语句

1.boolean数据类型

  • boolean数据类型声明一个具有值 true 或者 false 的变量
  • 布尔(boolean)表达式是计算结果为布尔值 true 或者 false 的表达式
  • Java提供六种关系(比较)操作符,用于两个值的比较:

小于 “<” 等同于数学符号 “<” ,如示例(radius 值为 5):radius < 0 ,结果为 false
大于 “>” 等同于数学符号 “>” ,如示例(radius 值为 5):radius > 0 ,结果为 true
等于 “==” 等同于数学符号 “=” ,如示例(radius 值为 5):radius = 0 ,结果为 false
小于等于 “<=” 等同于数学符号 “≤” ,如示例(radius 值为 5):radius <= 0 ,结果为 false
大于等于 “>=” 等同于数学符号 “≥” ,如示例(radius 值为 5):radius >= 0 ,结果为 true
不等于 “!=” 等同于数学符号 “≠” ,如示例(radius 值为 5):radius != 0 ,结果为 true

  • 关系操作符中的相等是 两个等号 “==”,单个等号 “=” 是赋值表达式!
  • 保存布尔值的变量称为布尔变量,boolean数据类型用于声明布尔型变量
  • true 和 false 都是字面值,类似于 10 这样的数字一样。它们被当做保留字一样不能用作程序中的标识符
  • 数字数据类型与布尔数据类型的转化:
	boolean b = true;
	int i = (int)b;
	System.out.print(i); // 1
	i = 0;
	b = (boolean)i;
	System.out.print(b); // false

即在数字与布尔数据类型转换时,1 视作 true,0 视作 false

2.if语句

  • if 语句是一个构造,允许程序确定执行的可选路径
  • Java中的选择语句类型有(罗列后逐个阐述):
    单分支 if 语句、
    双分支 if 语句、
    嵌套 if 语句、
    多分支 if-else 语句、
    switch 语句 和
    条件语句

2.1.单分支 if 语句

语法:

	if(布尔表达式) {
		// 语句(组);
	}

当 if 语句后的布尔表达式结果为 true 时执行 行内块语句,为 false 时则跳过该 if 语句后的行内块语句

当花括号内只有一条语句时可以省略花括号
但是这种写法会增加后续阅读和修改代码的难度,因此 不建议使用

2.2.双分支 if 语句

语法:

	if(布尔表达式) {
		// 布尔表达式结果为 true 时执行的语句(组);
	} else {
		// 布尔表达式结果为 false 时执行的语句(组);
	}

语法已经能够很好地解释双分支 if 语句的执行方式,不作赘述

2.3.嵌套 if 语句 和 多分支 if-else 语句

这两个语句的效果类似但不相同,放一块便于比较区分

  • 语法:
    嵌套 if 语句:
	if(i > k) {
		// 当 i 大于 k 时执行此处及以下的代码
		if(j > k) {
			// 当 j 大于 k 时还会执行此处的代码
			// 还可以继续嵌套更多的 if 语句:
			if(l > k) {
				// ...
			}
		}
	}

多分支 if-else 语句:

	if(i > 90) {
		// 当 i 大于 90 时执行此处及以下的代码
	} else if(i > 75) {
		// 当 i 大于 75 时还会执行此处的代码
		// 还可以继续嵌套更多的 else if 语句:
	} else if(i > 60) {
		// ...
	}

嵌套 if 语句(便于阅读简称嵌套语句) 和 多分支 if-else 语句(便于阅读简称多分支语句)同样都是对条件进行多重判断,用以处理 符合不同条件 的不同情况数据
而在实际使用中,嵌套语句更偏向于判断不同类型需求的条件、多分支语句更偏向于判断相同类型需求的条件
例如根据学生的成绩进行排挡处理,由于区分条件只有一种(成绩),因此使用多分支语句更佳
而例如社交网站,需要根据性别、年龄、籍贯、兴趣爱好等不同方面的各个条件进行划分,此时使用嵌套语句来进行判断效果则更好

2.4.switch 语句

语法:

	switch(switch表达式) {
		case1: 语句(组)1;
			break;
		case2:语句(组)2;
			break;
		...
		case 值N:语句(组)Nv;
			break;
		default:默认情况下(一般为条件都不符合时)执行的语句(组)
	}

而 break 并不要求出现在每个 case(情况)后的执行语句中,它的效果是提前结束运行之后的语句……直到符合下一个条件(不常见)或相当于结束该 switch 语句
若 switch 语句中漏写了应当存在的 break 语句可能会导致条件判断后的执行结果异常(比如任意条件满足就会一直执行完之后的所有结果)
以下例子为便于理解 break 用和不用的情况:

345月视为春季
	switch(moon) {
		case 3:
		case 4:
		case 5: 
			System.out.println(moon +"月是春季"); 
			// 由于对3、4、5月份的季节判定相同,因此不区分处理,即不论是满足哪个条件最终都是得到“春季”这个结论
			// 以下几个季节同理
			break;
		case 6:
		case 7:
		case 8: 
			System.out.println(moon +"月是夏季");
			break;
		case 9:
		case 10:
		case 11: 
			System.out.println(moon +"月是秋季");
			break;
		case 12:
		case 1:
		case 2: 
			System.out.println(moon +"月是冬季");
			break;
		default : 
			// 当用户输入值不满足所有情况——即不是1~12时:
			System.out.println("请输入正确的月份");
	}

switch 语句 与 多分支语句类似,而多分支语句更多的是针对条件为 范围值 时使用,switch 语句啧更多的偏向于条件为可能的 具体值 时使用
例如:
关于季节的判断:

	if(moon >= 3 && moon <= 5) {
		System.out.println(moon + "月是春季");
	} else if(moon >= 6 && moon <= 8) {
		System.out.println(moon + "月是夏季");
	} else if(moon >= 9 && moon <= 11) {
		System.out.println(moon + "月是秋季");
	} else if(moon == 12 || moon <= 2 && moon >=1) {
		System.out.println(moon + "月是冬季");
	} else {
		System.out.println("请输入正确的月份");
	}

此处附上一则代码简化写法(稍微)

	// print不换行,println换行
	System.out.print(moon +"月是");
	switch(moon) {
		case 3:
		case 4:
		case 5: 
			System.out.print("春");
			// 由于对3、4、5月份的季节判定相同,因此不区分处理,即不论是满足哪个条件最终都是得到“春季”这个结论
			// 以下几个季节同理
			break;
		case 6:
		case 7:
		case 8: 
			System.out.print("夏");
			break;
		case 9:
		case 10:
		case 11: 
			System.out.print("秋");
			break;
		case 12:
		case 1:
		case 2: 
			System.out.print("冬");
			break;
		default : 
			// 当用户输入值不满足所有情况——即不是1~12时:
			System.out.println("请输入正确的月份");
	}
	System.out.println("季");
	// 不过在这里这种写法反而有可能导致输出值异常,比如 moon 值为 13 时:
	/* displays:
		13月是
		请输入正确的月份季
	**/
	// 因此这块代码主要是提供一种编程思路,当重复代码过多时可考虑这种写法简化

相较而言:看起来 else if 的方式更为简洁(行数少),而事实上编写起来的难度较之于 switch 的方式更为繁复
由于值确定且数量较少(12种),switch 方式显得更为直观
而当条件的可能性增多或比如值为浮点型数据时,情况数量就会大大增加甚至是无穷的,即在实际使用时 else if 这种方式的判断语法使用频率会更高

2.5.条件语句(即 三元运算符

语法:

	// 将 num1 和 num2 中较大的数赋值给 max
	max = (num1 > num2) ? num1 : num2;
	// “?” 前的语句判断为 true 时赋值 “:” 前的数据,为 false 时赋值 “:” 后的数据
	// 可以理解为:
	if(num1 > num2) {
		max = num1;
	} else {
		max = num2;
	}

三元运算符 的有效利用可以明显简化代码的繁复性(多行代码一行搞定),许多语言都有使用三元运算符

3.逻辑操作符

逻辑操作符 ! 、&& 、|| 、 ^ 可以用于产生复合布尔表达式:

  • !:逻辑非,改变原本的判断结构 -> true 变 false , false 变 true
  • && :逻辑与,其两边的布尔表达式判断结果都为 true 总的才为 true
  • || :逻辑或,其两边的布尔表达式判断结果只要有一个为 true 则为 true ,否则 false
  • ^ :逻辑异或,效果等同于 != 即不等于,两边判断结果不同时为 true ,否则 false

逻辑非和逻辑与有个共同点:
即左边的布尔表达式结果有时会跳过后面的语句
&& 左边为 false 时提前结束,返回 false
|| 左边为 true 时提前结束,返回 true

4.注意事项、常见错误异常及陷阱

  • if 语句的布尔表达式需要 写在括号中
  • if 行不能出现== 分号 ==
  • 对布尔值的冗余测试
    以下代码示例:
	if(even == true)
		System.out.println("It is even.");
	// 此处 if 中的 even 即冗余测试,括号内会默认判定布尔值,无需主动增加 == true 的判断
	// 不算错误,但没有必要,也会降低可读性(与大众习惯不符)
	// 这样即可:
	if(even)
		System.out.println("It is even.");
  • 悬空 else 出现歧义:
	int i = 1, j = 2, k = 3;
	if(i > j)
		if(i > k)
			System.out.println("A");
	else
			System.out.println("B");
	// 你以为这个 else 是跟第一个 if 匹配?实际上在程序看来它是这样的:
	int i = 1, j = 2, k = 3;
	if(i > j)
		if(i > k)
			System.out.println("A");
		else // 就近原则进行匹配,而 else 的缩进并不会影响程序的识别!
			System.out.println("B");
			
	// 而如果一定要 else 与第一个 if 匹配:
	int i = 1, j = 2, k = 3;
	if(i > j) {
		if(i > k)
			System.out.println("A");
	} else
			System.out.println("B");
			
	// 而事实上,用这种语法习惯写 if 语句属于吃力不讨好的行为,最好的方式还是每个 if 语句都加上花括号
	int i = 1, j = 2, k = 3;
	if(i > j) {
		if(i > k) {
			System.out.println("A");
		}
	} else {
		System.out.println("B");
	}
  • 两个浮点数值的相等测试:
	double x = 1.0 - 0.1 - 0.1 - 0.1 - 0.1 -0.1;
	System.out.println(x == 0.5); // 以为是 true ,而实际上是 false
	// 因为在此处 x 的值并不精确等于 0.5,而是 0.5000000000000001
	
	// 可以使用近似比较(误差极小的情况下)
	final double EPSILON = 1E-14; // 比较 double 数据时使用 1E-14,比较 float 数据时使用 1E-7(精度原因)
	double x = 1.0 - 0.1 - 0.1 - 0.1 - 0.1 -0.1;
	if (Math.abs(x - 0.5) < EPSILON) {
		System.out.println(x + "is approximately 0.5");
	}
  • 简化布尔变量赋值:
	if(number % 2 == 0) {
		even = true;
	} else {
		even = false;
	}
	// 这样相当于通过 if 判断后再赋值,可以这样写来简化:
	boolean even
		= number % 2 == 0;
  • 避免不同情形中的重复代码:
	if(inState) {
		tuition = 5000;
		System.out.println("The tuition is " + tuition);
	} else {
		tuition = 15000;
		System.out.println("The tuition is " + tuition);
	}
	// 这种重复代码的情况在比较 switch 和 else if 时就有提到,这样来简化:
	if(inState) {
		tuition = 5000;
	} else {
		tuition = 15000;
	}
	System.out.println("The tuition is " + tuition);

5.调试

调试是在程序中找到和修改错误的过程

  • 首先回顾错误类型:
    语法错误:编译器可以明确指出错误的位置以及错误的原因,因此最容易解决;
    运行时错误:程序异常终止时会在控制台显示出错误的位置及原因,稍微麻烦但也算很难解决;
    逻辑错误:被称为臭虫(即 bug),最难找出出错位置和原因,常常需要耗费大量精力时间
  • 而这里所说的调试,主要就是指的调制逻辑错误,查找和改正错误的过程被称为调试(debugging)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值