Scala编程学习之四-流程控制语句

1.程序流程控制介绍

在程序中,程序运行的流程控制决定程序是如何执行的,是我们必须掌握的,主要有三大流程控制语句。
温馨提示: Scala语言中控制结构和Java语言中的控制结构基本相同,在不考虑特殊应用场景的情况下,代码书写方式以及理解方式都没有太大的区别 [知道-》不会说 ]
1)顺序控制
2)分支控制(单分支, 双分支,多分支)
3)循环控制

2顺序控制

2.1顺序控制介绍

程序从上到下逐行地执行,中间没有任何判断和跳转。

2.2顺序控制举例和注意事项

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.分支控制的if-else

3.1分支控制if-else介绍

让程序有选择的的执行,分支控制有三种:
1)单分支
2)双分支
3)多分支

3.2单分支
在这里插入图片描述
3.3双分支
在这里插入图片描述
3.4双分支小案例:
判断一个年份是否是闰年,闰年的条件是符合下面二者之一:(1)年份能被4整除,但不能被100整除;(2)能被400整除

object IfElseDemo {
  def main(args: Array[String]): Unit = {
    /*
    判断一个年份是否是闰年,闰年的条件是符合下面二者之一:(1)年份能被4整除,但不能被100整除;(2)能被400整除
    分析
    1. 有一个变量,保存year
    2. 分支控制
    3. (1) 和 (2) 条件是 或的关系
    4. (1) 中的两个条件是 与的关系
    代码
     */

    var year = 2020
    if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
      println("year=" + year + "是闰年")
    } else {
      println("year=" + year + "不是闰年")
    }

  }
}

3.5多分支小案例
岳小鹏参加scala考试,他和父亲岳不群达成承诺:
如果:
成绩为100分时,奖励一辆BMW;
成绩为(80,99]时,奖励一台iphone7plus;
当成绩为[60,80]时,奖励一个 iPad;
其它时,什么奖励也没有。

说明: 成绩在控制台输入!
代码:

 import scala.io.StdIn
    
    object IfElseIf {
      def main(args: Array[String]): Unit = {
        /*
        岳小鹏参加scala考试,他和父亲岳不群达成承诺:
    如果:
    成绩为100分时,奖励一辆BMW;
    成绩为(80,99]时,奖励一台iphone7plus;
    当成绩为[60,80]时,奖励一个 iPad;
    其它时,什么奖励也没有。
    
    说明: 成绩在控制台输入!
        分支
        1. 有一个变量 score 保存我们的成绩
        2. 使用多分支来控制流程
        3. 根据不同的情况,来输出结果
         */
        println("请输入岳小鹏考试成绩")
        val score = StdIn.readFloat() //大数据
        if (score >= 100) {
          println("成绩为100分时,奖励一辆BMW")
        } else if (score > 80 ) {
          println("奖励一台iphone7plus")
        } else if (score >= 60) {
          println("奖励一个 iPad")
        } else {
          println("其它时,什么奖励也没有")
        }
      }
    }

求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 的包对象有很多方法直接可用.

代码实现和分析:

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. 因为 b2-4ac 的值被使用多次(3次),就应该保存到变量m,如果是一段功能代码用了3次以上,就封装到类或者方法中()
    3. 多分支
    4. 定义两个值,保存结果(x1,x2)
     */
    //一次性定义三个变量
    val (a, b, c) = (3, 100, 6)
    var (x1, x2) = (0.0, 0.0)
    val m = b * b - 4 * a * c //常用的
    //math是scala包下的一个包对象(简单说包对象指的是,针对给包 scala.math这个包对应对象)
    //1. 即 scala.math 是一个包(package scala.math 等价 package scala package math),同时还提供了这个scala.math这个包对应的包对象[package object math {]
    if (m > 0) {
      //math.sqrt 这个math就是一个包对象
      x1 = (-b + math.sqrt(m)) / (2 * a)
      x2 = (-b - math.sqrt(m)) / (2 * a)
      println("x1=" + x1.formatted("%.2f"))
      println("x2=" + x2)

    } else if (m == 0) {
      x1 = (-b + math.sqrt(m)) / (2 * a)
      println("x1=" + x1.formatted("%.2f"))

    } else {
      println("没有结果")
    }
  }
}

3.6分支控制if-else 注意事项
1)如果大括号{}内的逻辑代码只有一行,大括号可以省略, 这点和java 的规定一样。
2)Scala中任意表达式都是有返回值的,也就意味着if else表达式其实是有返回结果的,具体返回结果的值取决于满足条件的代码体的最后一行内容.[案例演示]
3)Scala中是没有三元运算符,因为可以这样简写,使用 if – else

object IfElseIfDemo02 {
  def main(args: Array[String]): Unit = {

    //Scala中任意表达式都是有返回值的,也就意味着if else表达式其实是有返回结果的,具体返回结果的值取决于满足条件的代码体的最后一行内容
    //什么是表达式:任何有值的都可以认为是表达式

    val res = if (5 < 3) {
      println("abc") //()
//      "hello"
//      "ok"
    } else {
//      190
//      200
      getSum(10,30) //方法会返回 10 + 30 = 40

    }

    println("res=" + res)
  }

  def getSum(n1:Int,n2:Int): Int = {
    n1 + n2 //返回一个 n1 + n2的值
  }
}

4.嵌套分支

4.1基本介绍

在一个分支结构中又完整的嵌套了另一个完整的分支结构,里面的分支的结构称为内层分支外面的分支结构称为外层分支。嵌套分支不要超过3层

4.2基本语法
if(){
if(){
}else{
}
}

4.3应用案例

参加百米运动会,如果用时8秒以内进入决赛,否则提示淘汰。并且根据性别提示进入男子组或女子组。【可以让学员先练习下5min】, 输入成绩和性别,进行判断。1分钟思考思路
double second; char gender;
代码

import scala.io.StdIn

object Exercise03 {
  def main(args: Array[String]): Unit = {
    /*
    参加百米运动会,如果用时8秒以内进入决赛,否则提示淘汰。并且根据性别提示进入男子组或女子组。【可以让学员先练习下5min】, 输入成绩和性别,进行判断
    分析
    1. 有两个变量
    2. 使用到嵌套分支
     */
    println("请输入成绩")
    val second = StdIn.readFloat()
    if (second <= 8 ) {

      println("请输入性别")
      val gender = StdIn.readChar()
      if (gender == '男') {
        println("进入男子组决赛")
      }else {
        println("进入女子组决赛..")
      }

    }else {
      println("你被淘汰...")
    }
  }
}

出票系统:根据淡旺季的月份和年龄,打印票价 [考虑学生先做5min]
scala 没有switch
4_10 旺季:
成人(18-60):60
儿童(<18):半价
老人(>60):1/3

淡季:
成人:40
其他:20
代码

object Exercise04 {
  def main(args: Array[String]): Unit = {
    /*
  分析
  1. 定义月份,年龄,票价
  2. 使用嵌套分支业务处理
     */
    val (month, age, ticket) = (8, 20, 60.0)
    var buyPrice = 0.0
    if (month >= 4 && month <= 10) {
      if (age >= 18 && age <= 60) {
        buyPrice = ticket
      } else if (age < 18) {
        buyPrice = ticket / 2
      } else {
        buyPrice = ticket / 3
      }
    } else {
      if (age >= 18 && age <= 60) {
        buyPrice = 40.0
      } else {
        buyPrice = 20.0
      }
    }
    println("应付" + buyPrice)
  }
}

**

5.switch分支结构

**

在scala中没有switch,而是使用模式匹配(match-case )来处理。后面再写

6.for循环控制

6.1基本介绍
Scala 也为for 循环这一常见的控制结构提供了非常多的特性,这些for 循环的特性被称为for 推导式(for comprehension)或for 表达式(for expression)

6.2范围数据循环方式
基本案例
for(i <- 1 to 3){ // 这里的 1 to 3 也可以是一个集合
print(i + " ")
}
println()
说明
1)i 表示循环的变量, <- 规定好 to 规定
2)i 将会从 1-3 循环, 前后闭合 (包括1 和 3)
输出10句 “hello!”

object ForDemo01 {
  def main(args: Array[String]): Unit = {
    /*
    输出10句 "hello!"

     */
    val n = 10
    for (i <- 1 to n) {
      println("你好" + i) //i 在不断的变化
    }

    //这里 1 to n 也可以直接是一个集合对象
    val list = List("北京", "广州", "深圳")

    for (item <- list) {
      println("item=" + item)
    }
  }
}

6.3范围数据循环方式
基本案例
for(i <- 1 until 3) {
print(i + " ")
}
println()
说明:
1)这种方式和前面的区别在于 i 是从1 到 (3-1)
2)前闭合后开的范围,和java的arr.length() 类似
for (int i =0; i < arr.lenght(); i++ ){}
输出10句 “hello!”

def main(args: Array[String]): Unit = {

    val n = 11
    for (i <- 1 until n ) {
      println("你好" + i)
    }
  }

6.4循环守卫
基本案例
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 = {

    //说明
    //i 变量名不是固定,是程序员指定
    //但是前后要一致
    for (i <- 1 to 3 if i != 2) {
      println("i=" + i) // 1 3
    }

    //集合进行遍历,使用循环守卫
    val list = List("bj", "tj", "sz")
    for (item <- list if item.startsWith("b")) {
      println("item=" + item)
    }
  }

6.5引入变量
基本案例
for(i <- 1 to 3; j = 4 - i) {
print(j + " ")
}

对基本案例说明
1)没有关键字,所以范围后一定要加;来隔断逻辑
2)上面的代码等价
for (i <- 1 to 4) {
val j = 4 - i
println(s"i= i j = {i} j= ij={j}")
}
代码案例

object ForImportVar {
  def main(args: Array[String]): Unit = {

    //说明
    //1.; 不能去掉

    for (i <- 1 to 4; j = 4 - i) {
      println(s"i=${i} j=${j}")
    }

    println("================")
    //等价
    for (i <- 1 to 4) {
      val j = 4 - i
      println(s"i=${i} j=${j}")
    }

  }
}

6.6嵌套循环
基本案例
for(i <- 1 to 3; j <- 1 to 3) {
println(" i =" + i + " j = " + j)
}

对基本案例说明
1)没有关键字,所以范围后一定要加;来隔断逻辑
2)上面的代码等价(处理比较复杂的业务时,使用这个)
for (i <- 1 to 3) {
for (j <-1 to 3) {
println(“ok”)
}
}
代码

object MutiFor {
  def main(args: Array[String]): Unit = {

    for (i <- 1 to 3; j <- 1 to 3) {
      println(s"i=$i  j=$j")
    }
    //等价的写法
    println("================")
    for (i <- 1 to 3) {
      for (j <- 1 to 3) {
        println(s"i=$i  j=$j")
      }

    }
  }

6.7循环返回值
基本案例
val res = for(i <- 1 to 10) yield i * 2
println(res)

对基本案例说明
将遍历过程中处理的结果返回到一个新Vector集合中,使用yield关键字,yield 可以写代码块.
代码

object ForYieldDemo {
  def main(args: Array[String]): Unit = {

    val res = for (i <- 1 to 10) yield  (i * 2)
    println("res=" + res)

    //将1到10数中的奇数放入到新的集合

    val res2 = for (i <- 1 to 10) yield  {
      if (i % 2 == 1) {
        i
      }else {
        ()
      }
    }

    println("res2=" + res2)

  }

6.8使用花括号{}代替小括号()
基本案例
for(i <- 1 to 3; j = i * 2) {
println(" i= " + i + " j= " + j)
}
可以写成:

对基本案例说明
1){}和()对于for表达式来说都可以
2)for 推导式有一个不成文的约定:当for 推导式仅包含单一表达式时使用圆括号,当其包含多个表达式时使用大括号
3)当使用{} 来换行写表达式时,分号就不用写了
4)代码:

object ForDemo03 {
  def main(args: Array[String]): Unit = {
    for {i <- 1 to 3
         j = i * 2} {
      println(" i= " + i + " j= " + j)
    }

  }

6.9注意事项和细节说明[控制步长]

1)scala 的for循环形式和java是较大差异,这点请同学们注意,但是基本的原理还是一样的。
2)scala 的for循环的步长如何控制! [for(i <- Range(1,3,2)]
3)思考题:如何使用循环守卫控制步长
4)代码实现

object ForStep {
  def main(args: Array[String]): Unit = {
    //遍历 1-10, 步长为 3
    //方式1 使用Range, 他是一个集合
    //说明 1: start
    //     10: end 遍历到(end -1)
    //      3: 表示step
    for (i <- Range(1,10,3)) { //until
      println("i=" + i)
    }

    //灵活的使用守卫 [推荐]
    println("==========使用守卫控制步长==============")
    for (i <- 1 to 10 if i % 3 == 1 ) {
      println("i=" + i)
    }
  }

6.10for循环小练习

object Exercise05 {
  def main(args: Array[String]): Unit = {
    //打印1~100之间所有是9的倍数的整数的个数及总和
    val start = 1
    val end = 100
    var sum = 0
    var count = 0
    for (i <- start to end) {
      if (i % 9 == 0) {
        count += 1
        sum += i
      }
    }
    printf("count=%d sum=%d\n", count, sum)

    //完成下面的表达式输出

    val n = 6
    for (i <- 0 to n) {
      printf("%d + %d = %d\n", i, (n - i), n)
    }

  }

7.while循环

7.1基本语法
循环变量初始化 //循环的四个要素
while (循环条件) {
循环体(语句)
循环变量迭代
}

7.2while循环应用实例

画出流程图
输出10句"你好,世界"
代码:

object WhileDemo01 {
  def main(args: Array[String]): Unit = {

    //输出10 hello
    var n = 1
    while (n <= 10) {
      println("hello,world" + n)
      n += 1 //循环遍历的迭代
    }
  }

7.3注意事项和细节说明

1)循环条件是返回一个布尔值的表达式
2)while循环是先判断再执行语句
3)与If语句不同,While语句本身没有值,即整个While语句的结果是Unit类型的()
4)因为while中没有返回值,所以当要用该语句来计算并返回结果时,就不可避免的使用变量 ,而变量需要声明在while循环的外部,那么就等同于循环的内部对外部的变量造成了影响,所以不推荐使用,而是推荐使用for循环。(scala设计者理念:能使用for循环,就先考虑使用.)

8.do…while循环控制

8.1基本语法
循环变量初始化;
do{
循环体(语句)
循环变量迭代
} while(循环条件)

8.2do…while循环应用实例

画出流程图
输入10 “你好,世界”

object DoWhile {
  def main(args: Array[String]): Unit = {
    //统计1——200之间能被5整除但不能被3整除的个数
    //do..while 循环的四要素
    var n = 1
    var max = 200
    var count = 0
    do {
      if (n % 5 == 0 && n % 3 != 0) {
        count += 1
      }
      n += 1
    }while(n <= max)
    println("count=" + count)
  }

8.3实例:

1)统计三个班成绩情况,每个班有5名同学,求出各个班的平均分和所有班级的平均分[学生的成绩从键盘输入]。
2)统计三个班及格人数,每个班有5名同学。
3)代码

import scala.io.StdIn

object Exercise06 {
  def main(args: Array[String]): Unit = {
    /*
    1统计三个班成绩情况,每个班有5名同学,求出各个班的平均分和所有班级的平均    分[学生的成绩从键盘输入]。
    2.统计三个班及格人数,每个班有5名同学。

   思路分析
   1. 定义变量 classNum , stuNum ,  classTotalScore, totalScore, passStuNum
   2. 因为没有数组,所以每次输入完一个班级的成绩后,就立即得到结果
   3. 会使用到嵌套循环.
     */
    val classNum = 3
    val stuNum = 5
    var classTotalScore = 0.0
    var totalScore = 0.0
    var stuScore = 0.0
    var passStuNum = 0

    for (i <- 1 to classNum) {//遍历三个班
      //将班级成绩清0.0
      classTotalScore = 0.0
      for (j<-1 to stuNum) {//遍历学生
        printf("请输入%d班级的第%d个学生的成绩\n" , i, j)
        stuScore = StdIn.readDouble()

        //累计及格的学生个数
        if (stuScore >= 60) {
          passStuNum += 1
        }
        //累计到 classTotalScore
        classTotalScore += stuScore
      }
      //得到班级的总成绩
      printf("第%d个班的平均成绩为%.2f\n", i, classTotalScore / stuNum)
      //累计到totalScore, 为了计算所有班级的总成绩
      totalScore += classTotalScore
    }
    //统计所有班级的平均分
    printf("总有班级的平均分为%.2f\n", totalScore / (classNum * stuNum))
    printf("及格的人数有%d\n", passStuNum)


  }

9.scala循环的中断使用

9.1基本说明
Scala内置控制结构特地去掉了break和continue,是为了更好的适应函数化编程,推荐使用函数式的风格解决break和contine的功能,而不是一个关键字
9.2案例1

// _ 类似 java中的 * 表示 将 包中的内容(class, object,trait,package object)引入进来
import util.control.Breaks._
object BreakDemo {
  def main(args: Array[String]): Unit = {
    //看看scala中的break机制.
    //先看代码,再做分析[看源码]

    //breakable
    //1. breakable 是一个 def 函数/
    /*
     def breakable(op: => Unit) {
    try {
      op
    } catch {
      case ex: BreakControl =>
        if (ex ne breakException) throw ex
    }
  }
     */
    //2. breakable 是一个函数,而且是一个高阶函数
    //3. 简单的说一下, 在scala中 高阶函数就是可以接收函数作为参数的函数,而且还可以返回函数
    //4. op: => Unit 表示他接收的函数是,没有输入参数,也没有输出的函数
    //5. op 表示的就是接收到函数的参数名
    //6. op 执行传入函数
    breakable {
      var n = 1
      while (true) {
        println("n=" + n)
        n += 1
        if (n == 18) {
          //说明 看break()
          //def break(): Nothing = { throw breakException } 抛出breakException
          break() //默认会直接让程序崩溃
        }
      }
    }

    println("ok~~")


    f1(sayHi) //
    f1{
      sayHi // {}
    }

    f1 {
      println("say Hi~~")
    }
  }

  //我模拟一段高阶函数的代码

  def sayHi(): Unit = {
    println("say Hi~~")
  }

  //f1就是一个高阶函数,可以接收一个函数【没有输入参数,没有输出的函数比如 sayHi】
  def f1(op: => Unit): Unit = {
    op
  }

案例2

 object ForBreak {
      def main(args: Array[String]): Unit = {
    
        //在for循环中,仍然使用break() 中断
        breakable {
          for (i <- 1 to 900000) {
            if (i == 99) {
              break()
            }
            println("i=" + i)
          }
        }
    
        println("程序继续....")
      }

9.3关于循环中断的应用案例
题目要求
100以内的数求和,求出当和 第一次大于20的当前数是多少?【for】
请使用循环守卫和breakable,完成break的效果?
代码实现

import util.control.Breaks._

object BreakExercise {
  def main(args: Array[String]): Unit = {
    //100以内的数求和,求出当和 第一次大于20的当前数是多少
    //推荐
    val max = 100
    var sum = 0
    breakable {
      for (i <- 1 to max) {
        sum += i //累计
        if (sum > 20) {
          println("传统的breakable() 当前i=" + i)
          break()
        }
      }
    }

    //使用循环守卫完成 上面的题
    sum = 0
    var flag = true
    for (i <- 1 to max if flag == true) {
      sum += i
      if (sum > 20) {
        println("使用的是循环守卫机制 当前的i=" + i)
        flag = false
      }
    }

  }
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值