2.顺序控制在程序中,程序运行的流程控制决定程序是如何执行的,是我们必须掌握的,主要 有三大流程控制语句。
温馨提示:Scala语言中控制结构和Java语言中的控制结构基本相同,在不考虑特 殊应用场景的情况下,代码书写方式以及理解方式都没有太大的区别
1) 顺序控制
2) 分支控制
3) 循环控制
3.分支控制if-else 3.1 分支控制if-else介绍顺序控制介绍
程序从上到下逐行地执行,中间没有任何判断和跳转。
顺序控制举例和注意事项
Scala中定义变量时采用合法的前向引用。如:
def main(args : Array[String]) : Unit = { var num1 = 12 var num2 = num1 + 2 }
错误形式:
def main(args : Array[String]) : Unit = { var num2 = num1 + 2 var num1 = 12 }
3.2 单分支让程序有选择的的执行,分支控制有三种:
1) 单分支
2) 双分支
3) 多分支
3.3 双分支基本语法
if (条件表达式) {
执行代码块
}
说明:当条件表达式为ture 时,就会执行 { } 的代码。
案例说明
//import scala.io.StdIn //单独的引入一个StdIn import scala.io._ // _表示将 scala.io 包的所有内容一起引入 object Demo01 { def main(args: Array[String]): Unit = { println("输入年龄") val age = StdIn.readInt() if (age > 18) { println("age > 18") } //小的技巧,如何查看某个包下包含的内容 //1.比如我们想看 scala.io 包有什么内容 //2.将光标放在 io上即可,输入ctrl +b //3.将光标放在 StdIn上即可,输入ctrl +b,看的是StdIn源码 scala.io.StdIn } }
单分支对应的流程图
3.4 多分支基本语法
if (条件表达式) {
执行代码块1
} else {
执行代码块2
}
说明:当条件表达式成立,即执行代码块1,否则执行代码块2.
案例说明
object Demo02 { def main(args: Array[String]): Unit = { val age = 6 if (age > 18) { println("age > 18") } else { println("age <= 18") } } }
双分支对应的流程图
3.5 分支控制if-else 注意事项基本语法
if (条件表达式1) {
执行代码块1
}
else if (条件表达式2) {
执行代码块2
}
……
else {
执行代码块n
}
多分支的流程图
说明:当条件表达式1成立时, 即执行代码块1,如果表达式1 不成立,才去判断表达式2是否 成立,如果表达式2成立,就执 行代码块2,以此类推,如果所 有的表达式都不成立,则执行 else 的代码块,注意, 只能有一个执行入口。
案例说明
import scala.io.StdIn object ifelsesDemo03 { def main(args: Array[String]): Unit = { /* 岳小鹏参加scala考试,他和父亲岳不群达成承诺: 如果: 成绩为100分时,奖励一辆BMW; 成绩为(80,99]时,奖励一台iphone7plus; 当成绩为[60,80]时,奖励一个 iPad; 其它时,什么奖励也没有。 成绩是从控制台输入 */ println("请输入成绩") val score = StdIn.readDouble() if (score == 100) { println("成绩为100分时,奖励一辆BMW") } else if (score > 80 && score <= 99) { //写法1使用范围,写法2就是严格的判断 println("成绩为(80,99]时,奖励一台iphone7plus") } else if (score >= 60 && score <= 80) { println("奖励一个 iPad") } else { println("没有任何奖励") } } }
4.嵌套分支 4.1 基本介绍1) 如果大括号{}内的逻辑代码只有一行,大括号可以省略, 这点和java 的规定一样。
2) Scala中任意表达式都是有返回值的,也就意味着if else表达式其实是有返回结果 的,具体返回结果的值取决于满足条件的代码体的最后一行内容.
案例演示
object Demo03 { def main(args: Array[String]): Unit = { //如果大括号{}内的逻辑代码只有一行,大括号可以省略, 这点和java 的规定一样 if (5 > 4) { println("5>4") } //Scala中任意表达式都是有返回值的,也就意味着if else表达式其实是有返回结果的,具体返回结果的值取决于满足条件的代码体的最后一行内容 val age = 7 val res = if (age > 20) { println("hello age > 20") 9 + 10 "yes ok" } else { 7 } println("res=" + res) // yes ok } }
3) Scala中是没有三元运算符,因为可以这样简写
// Java int result = flg ? 1 : 0
// Scala val result = if (flg) 1 else 0 // 因为 scala 的if-else 是有返回值的,因此,本身这个语 言也不需要三元运算符了,并且可以写在同一行,类似 三元运
4.2 基本语法在一个分支结构中又完整的嵌套了另一个完整的分支结构,里面的分支的结构称为 内层分支外面的分支结构称为外层分支。嵌套分支不要超过3层
4.3 应用案例if(){
if(){
}else{
}
}
5.switch分支结构参加百米运动会,如果用时8秒以内进入决赛,否则提示淘汰。并且根据性别提示 进入男子组或女子组。【可以让学员先练习下5min】, 输入成绩和性别,进行判断。
import scala.io.StdIn object Exercise04 { def main(args: Array[String]): Unit = { println("请输入运动员的成绩") val speed =StdIn.readDouble() if (speed <= 8){ println("请输入性别") val gender = StdIn.readChar() if(gender == '男'){ println("进入男子组") } else { println("进入女子组") }else { println("你被淘汰...") } }
6.for循环控制 6.1 基本介绍在scala中没有switch,而是使用模式匹配来处理。
模式匹配涉及到的知识点较为综合,因此我们放在后面讲解。
match-case
6.2 范围数据循环方式1Scala 也为for 循环这一常见的控制结构提供了非常多的特性,这些for 循环的 特性被称为for 推导式(for comprehension)或for 表达式(for expression)
6.3 范围数据循环方式2基本案例
for(i <- 1 to 3){ print(i + " ") } println()
说明
1) i 表示循环的变量, <- 规定好 to 规定
2) i 将会从 1-3 循环, 前后闭合
输出10句 "hello,尚硅谷!"
object ForDemo01 { def main(args: Array[String]): Unit = { //输出10句 "hello,尚硅谷!" val start = 1 val end = 10 //说明 //1. start 从哪个数开始循环 //2. to 是关键字 //3. end 循环结束的值 //4. start to end 表示前后闭合 for (i <- start to end) { println("你好,尚硅谷" + i) } //说明for 这种推导时,也可以直接对集合进行遍历 var list = List("hello", 10, 30, "tom") for (item <- list) { println("item=" + item) } } }
6.4 循环守卫基本案例
for(i <- 1 until 3) { print(i + " ") } println()
说明:
1) 这种方式和前面的区别在于 i 是从1 到 3-1
2) 前闭合后开的范围,和java的arr.length() 类似 for (int i = 0; i <
输出10句 "hello,尚硅谷!"
object ForUntilDemo02 { def main(args: Array[String]): Unit = { //输出10句 "hello,尚硅谷!" val start = 1 val end = 11 //循环的范围是 start --- (end-1) for (i <- start until end) { println("hello, 尚硅谷" + i) } } }
6.5 引入变量基本案例
for(i <- 1 to 3 if i != 2) { print(i + " ") } println()
1) 循环守卫,即循环保护式(也称条件判断式,守卫)。保护式为true则进入 循环体内部,为false则跳过,类似于continue
2) 上面的代码等价
for (i <- 1 to 3) { if (i != 2) { println(i+"") } }
代码演示
object ForGuard { def main(args: Array[String]): Unit = { for(i <- 1 to 3 if i != 2) { print(i + " ") //1 3 } println() } }
6.6 嵌套循环基本案例
for(i <- 1 to 3; j = 4 - i) { print(j + " ") }
1) 没有关键字,所以范围后一定要加;来隔断逻辑
2) 上面的代码等价
for ( i <- 1 to 3) { val j = 4 –i print(j+"") }
代码演示
object ForVar { def main(args: Array[String]): Unit = { for(i <- 1 to 3; j = 4 - i) { print(j + " ") // 3,2,1 } } }
6.7 循环返回值基本案例
for(i <- 1 to 3; j <- 1 to 3) { println(" i = " + i + " j = " + j) }
1) 没有关键字,所以范围后一定要加;来隔断逻辑
2) 上面的代码等价
for ( i <- 1 to 3) { for ( j <- 1to 3){ println(i + " " + j + " ") } }
代码演示
object MultiFor { def main(args: Array[String]): Unit = { for(i <- 1 to 3; j <- 1 to 3) { println(" i =" + i + " j = " + j) //输出即句 9 } //上面的写法,可以写成 println("--------------------------") for(i <- 1 to 3) { for (j <- 1 to 3) { println(" i =" + i + " j = " + j) //输出即句 9 } } } }
6.8 使用花括号{}代替小括号()基本案例
val res = for(i <- 1 to 10) yield i println(res)
1) 将遍历过程中处理的结果返回到一个新Vector集合中,使用yield关键字
代码演示
object yieldFor { def main(args: Array[String]): Unit = { //说明 val res = for(i <- 1 to 10) yield i 含义 //1. 对1 to 10 进行遍历 //2. yield i 将每次循环得到i 放入到集合Vector中,并返回给res //3. i 这里是一个代码块,这就意味我们可以对i进行处理 //4. 下面的这个方式,就体现出scala一个重要的语法特点,就是将一个集合中个各个数据 // 进行处理,并返回给新的集合 val res = for(i <- 1 to 10) yield { if (i % 2 == 0) { i }else { "不是偶数" } } println(res) } }
6.9 注意事项和细节说明基本案例
for(i <- 1 to 3; j = i * 2) { println(" i= " + i + " j= " + j) } //可以写成 for{ i <- 1 to 3 j = i * 2} { println(" i= " + i + " j= " + j) }
1) {}和()对于for表达式来说都可以
2) for 推导式有一个不成文的约定:当for 推导式仅包含单一表达式时使用圆括号,当其 包含多个表达式时使用大括号
3) 当使用{} 来换行写表达式时,分号就不用写了
代码演示
object usefor2 { def main(args: Array[String]): Unit = { for (i <- 1 to 3; j = i * 2) { println(" i= " + i + " j= " + j) } //等价 println("------------------------") for { i <- 1 to 3 j = i * 2} { println(" i= " + i + " j= " + j) } } }
7.while循环控制 7.1 基本语法1) scala 的for循环形式和java是较大差异,这点请同学们注意,但是基本的原 理还是一样的。
2) scala 的for循环的步长如何控制! [for(i <- Range(1,3,2)]
3) 思考题:如何使用循环守卫控制步长
代码演示
object stepfor { def main(args: Array[String]): Unit = { for (i <- 1 to 10) { println("i=" + i) } //步长控制为2 println("-------------") //Range(1,10,2)的对应的构建方法是 //def apply(start: Int, end: Int, step: Int): Range = new Range(start, end, step) for (i <- Range(1, 10, 2)) { println("i=" + i) } //控制步长的第二种方式-for循环守卫 println("**************************") for (i <- 1 to 10 if i % 2 == 1) { println("i=" + i) } } }
7.2 while循环应用实例循环变量初始化
while (循环条件) {
循环体(语句)
循环变量迭代
}
7.3 注意事项和细节说明输出10句"你好,尚硅谷"
object WhileDemo01 { def main(args: Array[String]): Unit = { //输出10句 hello,尚硅谷 //1. 定义循环变量 var i = 0 //2. i < 10 条件 while (i < 10){ println("hello,尚硅谷" + i) //循环体 //循环变量迭代 i += 1 } } }
8.do..while循环控制 8.1 基本语法1) 循环条件是返回一个布尔值的表达式
2) while循环是先判断再执行语句
3) 与If语句不同,While语句本身没有值,即整个While语句的结果是Unit类型 的()
4) 因为while中没有返回值,所以当要用该语句来计算并返回结果时,就不可避免 的使用变量 ,而变量需要声明在while循环的外部,那么就等同于循环的内 部对外部的变量造成了影响,所以不推荐使用,而是推荐使用for循环。
8.3 do...while循环应用实例循环变量初始化;
do{
循环体(语句)
循环变量迭代
} while(循环条件)
8.4 注意事项和细节说明输入10 "你好, 尚硅谷"
object Demo01 { def main(args: Array[String]): Unit = { var i = 0 // for do { printf(i + "hello,尚硅谷\n" ) i += 1 } while (i < 10) } }
9.多重循环控制 9.1 介绍1) 循环条件是返回一个布尔值的表达式
2) do..while循环是先执行,再判断
3) 和while 一样,因为do…while中没有返回值,所以当要用该语句来计算并返回 结果时,就不可避免的使用变量 ,而变量需要声明在do...while循环的外部, 那么就等同于循环的内部对外部的变量造成了影响,所以不推荐使用,而 是推荐使用for循环
9.2 应用实例1) 将一个循环放在另一个循环体内,就形成了嵌套循环。其中, for ,while ,do…while均可以作为外层循环和内层循环。【建议一般使用两层, 最多不要超过3层】
2) 实质上,嵌套循环就是把内层循环当成外层循环的循环体。当只有内层循 环的循环条件为false时,才会完全跳出内层循环,才可结束外层的当次循环, 开始下一次的循环。
3) 设外层循环次数为m次,内层为n次, 则内层循环体实际上需要执行 m*n=mn次
10.while循环的中断 10.1 基本说明1) 统计三个班成绩情况,每个班有5名同学,求出各个班的平均分和所有班级 的平均分[学生的成绩从键盘输入]
import scala.io.StdIn object Exercise { /* 应用实例: 1.统计三个班成绩情况,每个班有5名同学,求出各个班的平均分和所有班级的平均分[学生的成绩从键 盘输入]。 分析思路 (1) classNum 表示 班级个数 , stuNum 表示学生个数 (2) classScore 表示各个班级总分 totalScore 表示所有班级总分 (3) score 表示各个学生成绩 (4) 使用循环的方式输入成绩 2.统计三个班及格人数,每个班有5名同学。 3.打印出九九乘法表 */ def main(args: Array[String]): Unit = { val classNum = 3 val stuNum = 5 var score = 0.0 //分数 var classScore = 0.0 //班级的总分 var totalScore = 0.0 //所有班级总分 for (i <- 1 to classNum) { //先将 classScore 清0 classScore = 0.0 for (j <- 1 to stuNum) { printf("请输入第%d班级的第%d个学生的成绩\n", i, j) score = StdIn.readDouble() classScore += score } //累计 totalScore totalScore += classScore printf("第%d班级的平均分为%.2f\n", i, classScore / stuNum) } printf("所有班级的平均分为%.2f", totalScore / (stuNum * classNum)) } }
2) 统计三个班及格人数,每个班有5名同学。
import scala.io._ object Exercise02 { def main(args: Array[String]): Unit = { //2.统计三个班及格人数,每个班有5名同学。 val classNum = 3 val stuNum = 5 var score = 0.0 //分数 var classScore = 0.0 //班级的总分 var totalScore = 0.0 //所有班级总分 var passNum = 0 //统计及格人数 for (i <- 1 to classNum) { //先将 classScore 清0 classScore = 0.0 for (j <- 1 to stuNum) { printf("请输入第%d班级的第%d个学生的成绩\n", i, j) score = StdIn.readDouble() if (score >= 60) { passNum += 1 } classScore += score } //累计 totalScore totalScore += classScore printf("第%d班级的平均分为%.2f\n", i, classScore / stuNum) } printf("所有班级的平均分为%.2f", totalScore / (stuNum * classNum)) printf("所有班级的及格人数为%d", passNum) } }
3) 打印出九九乘法表
object Exercise03 { def main(args: Array[String]): Unit = { //3.打印出九九乘法表 //思路分析 //(1) 使用两层循环, 有9行, 每1行的列数在增加 //(2) 根据逻辑,我们可以编写代码 val num = 9 for (i <- 1 to num) { //确定行数 for (j <- 1 to i) {//确定列数 printf("%d * %d = %d\t" , j , i , i * j) } println() } } }
10.2 案例演示Scala内置控制结构特地去掉了break和continue,是为了更好的适应函数化 编程,推荐使用函数式的风格解决break和contine的功能,而不是一个关键字
11.课后练习题1.Break
import util.control.Breaks._ object WhileBreak { def main(args: Array[String]): Unit = { var n = 1 //breakable()函数 //说明 //1. breakable 是一个高阶函数:可以接收函数的函数就是高阶函数(后面详解) //2. def breakable(op: => Unit) { // try { // op // } catch { // case ex: BreakControl => // if (ex ne breakException) throw ex // } // } // (1) op: => Unit 表示接收的参数是一个没有输入,也没有返回值的函数 // (2) 即可以简单理解可以接收一段代码块 // 3. breakable 对break()抛出的异常做了处理,代码就继续执行 // 4. 当我们传入的是代码块,scala程序员会将() 改成{} breakable { while (n <= 20) { n += 1 println("n=" + n) if (n == 18) { //中断while //说明 //1. 在scala中使用函数式的break函数中断循环 //2. def break(): Nothing = { throw breakException } break() } } } println("ok~~") //注意break函数,可以使用在for或者do..while breakable { for (i <- 1 to 100) { println("i=" + i) if (i == 20) { break() } } } println("ok2~~~~") } }
2.Continue
object ContinueDemo { def main(args: Array[String]): Unit = { //说明 //1. 1 to 10 //2. 循环守卫 if (i != 2 && i != 3) 这个条件为ture,才执行循环体 // 即当i ==2 或者 i == 3时,就跳过 for (i <- 1 to 10 if (i != 2 && i != 3)) { println("i=" + i) } //也可以写成如下的形式 println("============================") for (i <- 1 to 10) { if (i != 2 && i != 3){ println("i=" + i) } } } }
12.代码说明 12.1 if-else100以内的数求和,求出当和 第一次大于20的当前数【for】
import util.control.Breaks._ object Homework01 { def main(args: Array[String]): Unit = { /* 100以内的数求和,求出当和 第一次大于20的当前数 */ var sum = 0 breakable { for (i <- 1 to 100) { sum += i if (sum > 20) { println("第一次大于20的当前数=" + i) break() } } } //除了上面的break机制来中断,我们也可以使用循环守卫实现中断 println("===========================") //见多识广 var loop = true var sum2 = 0 for (i <- 1 to 100 if loop == true) { sum2 += i if (sum2 > 20) { println("循环守卫实现中断 第一次大于20的当前数=" + i) loop = false } println("i=" + i) } } }
12.2 for1.Exercise01
object Exercise01 { def main(args: Array[String]): Unit = { /* 【选作】定义两个变量Int,判断二者的和,是否既能被3又能被5整除,打印提示信息 */ val num1 = 10 val num2 = 5 val sum = num1 + num2 if (sum % 3 == 0 && sum % 5 == 0) { println("能被3又能被5整除") } else { println("能被3又能被5整除 不成立~") } /* 判断一个年份是否是闰年,闰年的条件是符合下面二者之一:(1)年份能被4整除,但不能被100整除;(2)能被400整除 */ //定义一个变量保存年份 val year = 2018 if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) { println(s"${year} 是闰年...") } else { println(s"${year} 不是闰年") } } }
2.Exercise02
import scala.math._ // _ 表示将scala.math 的所有内容导入 object Exercise02 { def main(args: Array[String]): Unit = { /* 求ax2+bx+c=0方程的根。a,b,c分别为函数的参数,如果:b2-4ac>0,则有两个解; b2-4ac=0,则有一个解;b2-4ac<0,则无解; [a=3 b=100 c=6] 提示1:x1=(-b+sqrt(b2-4ac))/2a X2=(-b-sqrt(b2-4ac))/2a 提示2:sqrt(num) 在 scala 包中(默认引入的) 的math 的包对象有很多方法直接可用. 思路的分析 1. 定义三个变量a,b,c 2. 使用多分支完成 3. 因为 b2-4ac会多次使用,因此我们可以先计算,并保持到变量中 4. 判断,写逻辑 */ val a = 3 val b = 100 val c = 6 val m = b * b - 4 * a * c var x1 = 0.0 var x2 = 0.0 if (m > 0) { x1 = (-b + sqrt(m)) / 2 * a x2 = (-b - sqrt(m)) / 2 * a println("有两个解 x1=" + x1.formatted("%.2f") + "x2=" + x2.formatted("%.2f")) } else if (m == 0) { x1 = (-b + sqrt(m)) / 2 * a println("有一个解 x1=" + x1) } else { println("无解..") } } }
3.Exercise03
object Exercise03 { def main(args: Array[String]): Unit = { var sumVal = 90 val result = if(sumVal > 20){ "结果大于20"//() } println("res=" + result) //返回的是() 即 Unit } }
4.Exercise04
import scala.io.StdIn object Exercise04 { def main(args: Array[String]): Unit = { /* 参加百米运动会,如果用时8秒以内进入决赛,否则提示淘汰。并且根据性别提示进入男子组或女子组。【可以让学员先练习下5min】, 输入成绩和性别,进行判断。 */ println("请输入运动员的成绩") val speed = StdIn.readDouble() if (speed <= 8) { println("请输入性别") val gender = StdIn.readChar() if (gender == '男') { println("进入男子组") } else { println("进入女子组") } } else { println("你被淘汰...") } } }
5.Exercise05
import scala.io.StdIn object Exercise05 { def main(args: Array[String]): Unit = { /* 应用案例2 出票系统:根据淡旺季的月份和年龄,打印票价 [考虑学生先做5min] 4_10 旺季: 成人(18-60):60 儿童(<18):半价 老人(>60):1/3 淡季: 成人:40 其他:20 思路分析 1. 定义至少三个变量 month , age, ticket 2. 逻辑上有月份和年龄的判断因此,会使用嵌套分支 3. 根据对应的业务逻辑完成代码 走代码 */ println("输入月份") val month = StdIn.readInt() println("输入年龄") val age = StdIn.readInt() val tikcet = 60 if (month >= 4 && month <= 10) { if (age >= 18 && age <= 60) { println("你的票价是" + tikcet) } else if (age < 18) { println("你的票价是" + tikcet / 2) } else { println("你的票价是" + tikcet / 3) } } else { if (age >= 18 && age <= 60) { println("你的票价是" + 40) } else { println("你的票价是" + 20) } } } }
object ForExercise01 { def main(args: Array[String]): Unit = { /* 打印1~100之间所有是9的倍数的整数的个数及总和. 完成下面的表达式输出 */ val start = 1 val end = 100 var count = 0 var sum = 0 for (i <- start to end) { if (i % 9 == 0) { count += 1 sum += i } } printf("count=%d, sum=%d\n", count, sum) //输出加法的循环表达式 val num = 6 for (i <- 0 to num) { printf("%d + %d = %d\n", i, (num - i), num) } var list = List(1,2) } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)