zoukankan      html  css  js  c++  java
  • Day 3 : 运算符和表达式2、分支结构

    1. 运算符和表达式-2
    2. 分支结构

    1. 运算符和表达式-2

    1.1. 赋值运算

    1.1.1. 使用“=”进行赋值运算

    “=”称为赋值运算符,用于对变量赋值。关于赋值运算符,除了将右边的表达式计算出来赋给左边以外还具备如下特点:赋值表达式本身也有值,其本身之值即为所赋之值。示例代码如下所示:

    int num = 18, index;
    System.out.println(index = num % 5);  // 结果为:3,赋值表达式本身也有值
    System.out.println(index);  // 结果为:3
    int a, b, c;
    a = b = c = 100;  
    // c=100 整个表达式的值为100, 将其赋值给b,同样b=(c=100)整个表达式的值也为100,然后有将这个值赋给了a,所以a 的值也是100。

    1.1.2. 使用扩展赋值表达式

    在赋值运算符”= ”前加上其它运算符,即为扩展赋值运算符,其效率高于赋值运算符,推荐使用,扩展赋值运算符如下图 - 5所示:


    图- 5

    1.2. 字符连接运算

    1.2.1. 使用“+”进行字符串连接

    “+”除了可以进行算术运算以外,还可以实现字符串的连接,同时可以实现字符串与其他数据类型的“相连”。

    当 + 号作用于两个数字类型变量时,是在进行算术运算。

    当 + 号两边的变量有一个是字符串类型,即””括起来的时候,则其进行的是字符串的连接,连接后的结果为字符串类型。示例代码如下所示:

    int a = 100;
    String msg = "a=" + a;
    System.out.println(msg);    //a=100,字符串拼接
    msg = "" + 100 + 200;
    System.out.println(msg);   //结果为: 100200,””+100,为字符串100再拼上200为100200
    msg = 100 + 200 + "";
    System.out.println(msg);   //结果为:300,100+200为算术运算结果为300,再加上””为300

    1.3. 条件(三目)运算

    1.3.1. 使用条件(三目)运算符

    条件运算符又称“三目”运算符,其结构为:boolean表达式 ? 表达式1:表达式2。

    条件运算符的规则如下:

    1. 先计算boolean表达式;
    2. 如果boolean表达式的值为true,整个表达式的值为表达式1的值;
    3. 如果boolean表达式的值为false,整个表达式的值为表达式2的值。

    示例代码如下:

    int a = 100, b = 200;
    int flag = a > b ? 1 : -1;   //因为a>b为false,所以整个表达式的值为-1,将其赋给flag,即:flag的值为-1。

    1.3.2. 条件(三目)运算符的嵌套

    条件运算符可以嵌套使用,所谓嵌套是指在条件(三目)表达式:“boolean表达式 ? 表达式1:表达式2”中的表达式1或表达式2也是条件(三目)表达式,相当于多重判断,示例代码如下所示:

    int a = -3;
    String r = a > 0 ? "正数" : (a == 0 ? "0":"负数");
    System.out.println(r); //结果为负数,因为 a 的值小于 0,即boolean 表达式的值为 false ,则取问号后第二个表达式的值作为表达式的结果。而问号后的第二个表达式也是一个三目运算符所构成的表达式。因为 a==0 表达式的值为 false,则取“负数”为表达式的结果。

    2. 分支结构

    2.1. 什么是分支结构

    首先,看一个需求,假设需要编写一个收银柜台收款程序,要求根据商品单价、购买数量以及收款金额,计算并输出应收金额和找零。

    通过分析可以想到,这个程序,需要定义三个输入,即:单价、数量、金额。定义两个输出,即:应收金额、找零。因为金额有可能为小数类型,所以变量的数据结构定义为double类型。

    此程序可以以如下方式解决,用户由控制台输入:商品单价、购买数量、收款金额;而后计算商品的总价及找零,并输出。示例代码如下所示:

    public static void main(String[] args) {
            //定义输入
            Scanner console = new Scanner(System.in);
            System.out.println("请输入单价(¥):");
            double unitPrice = console.nextDouble();
            System.out.println("请输入数量:");
            double amount = console.nextDouble();
            System.out.println("请输入金额(¥):");
            double money = console.nextDouble();
            console.close();
            
            //计算商品总价
            double totalPrice = unitPrice * amount;
            //计算找零
            double change = money - totalPrice;
            
            //输出
            System.out.println("应收金额为:" + totalPrice +",找零为:" + change);
        }

    如上代码,输入数据后,可以正确输出应收金额及找零,假设现在需求增加,当商品总价满500时享受8折优惠, 如何解决?这种情况,在软件应用中,需要使用分支结构来实现。

    任何复杂的程序逻辑结构都可以通过“顺序”,“分支”,“循环”这三种基本的程序结构实现。如图 – 1所示:


    图- 1

    刚刚的案例即为顺序结构,第一步A执行完执行第二步B,第二步执行完执行第三步,一步一步顺序执行。分支结构即为根据一个条件做判断,如果条件满足则执行A,否则执行B。还有一种即为后面要介绍的循环结构。原则上,任何复杂的程序, 都可以通过这三种结构来解决。

    当程序在运行过程中, 需要根据不同的条件而运行不同的语句时,即可以使用分支结构,Java中有专门的语法结构来实现分支:

    1. 当条件满足时运行某些语句;当条件不满足时则不运行这些语句——if结构。
    2. 当条件满足时运行某些语句; 当条件不满足时运行另外一些语句——if-else结构

    2.2. if语句

    2.2.1. if语句的执行逻辑

    首先看下面if语句的语法:

    语句0;
    if(逻辑表达式){
            语句1;
            语句2;
    }
    语句3;

    如上语句的执行步骤如下所示:

    步骤一:执行语句0;

    步骤二: 判断逻辑表达式的值,此表达式的值结果为boolean类型,即true或者false。此处可以是关系表达式也可以是逻辑表达式。

    1. 若值为true,则执行if语句块中的语句;
    2. 若值为false,则跳过if语句块;

    步骤三:执行语句3语句。

    2.2.2. if语句流程图

    if语句的执行逻辑如下图 - 2所示:


    图- 2

    通过图示得出结论:当条件满足时,执行语句块,然后执行if语句下面的语句;否则跳过语句块,直接执行if语句下面的语句。

    2.2.3. if语句用于处理分支逻辑

    if语句是java中用于处理分支结构的语句,下面,通过if语句来实现刚刚的打折功能逻辑,再回顾一下新添的需求:如果商品总价大于等于500,则打8折。如下图– 3 红色部分即为if的判断逻辑:


    图- 3

    可以看到,计算商品总价之后,进行了总价大于等于500的业务判断,若判断结果为true,则计算折扣后的应收金额,再计算找零后输出。若判断结果为false,则直接计算找零后输出。如下即为实现代码:

    ……
        double totalPrice = ……;
        if (totalPrice >= 500) {
             totalPrice = totalPrice * 0.8;
        }
        ……

    通过如上代码可以看出: 当total>=500为true时, 总额乘以0.8, 即打8折。当total>=500为false时,不执行if语句块的内容。

    2.2.4. if语句块不要省略“{}”

    if语句块在执行过程中,有一个问题是需要注意的,先看下面的两段代码:

    代码一:
    int num = 5;
    if(num>2)
               System.out.print(num);
               System.out.println(“ 大于2 ”);
    代码二:
    int num = 5;
    if(num>2){
            System.out.print(num);
            System.out.println(“ 大于2 ”);}

    分析如上两个代码段,得出的结论是:两段代码输出结果一样,即 “5 大于 2”。再看如下两段代码,输出结果还一样吗?

    代码一:
    int num = 5;
    if(num<2)
               System.out.println(num);
               System.out.println(“小于2”);
    代码二:
    int num = 5;
    if(num<2){
            System.out.print(num);
            System.out.println(“小于2”);}

    分析如上两个代码段,可以得出,代码段一的输出结果是“大于2”,代码段二没有任何输出。分析输出结果可以看出,代码段二的结果为正确结果,而代码段一输出的“小于2”是不应该存在的,出现这个问题的原因在于,在if语句之后没有添加“{}”,而java语法规定,当if语句块中只包含一条语句时,可以省略“{}”,但是if语句块也只能作用于它下面的一条语句。

    看如上代码段一的if判断,只作用于第一个输出语句,因为num<2结果为false,所以第一个输出语句并未执行,而第二个输出语句“小于2”不属于if作用范围,所以无论条件满足与否,都会执行。故而,输出了“小于2”的结果。

    所以,考虑到代码的可读性、扩展性,建议即便if语句块中只有一条语句,也不要省略“{}”。

    2.3. if-else语句

    2.3.1. if-else语句的执行逻辑

    分析上面的案例,当计算出最终(打折前、打折后)的应收金额后,直接计算找零,这

    个时候就出现了一个问题,如果收款的金额小于应收的金额,那么输出的找零就会为负数结果,这显然用户体验不好,下面对它做一下改进,要求考虑程序的异常情况,增加需求如下:

    1. 若收款金额大于等于应收金额,则计算找零后输出;
    2. 若收款金额小于应收金额,则输出错误提示信息,如何处理?

    这种情况,单单使用if语句显然无法解决了,因为if语句用于解决的是,当某条件满足时执行某段业务处理的逻辑,而现在的逻辑时,当条件满足时执行某段业务逻辑,当条件不满足时需要执行另一段业务逻辑。看如下图 – 4所示的红色部分:


    图- 4

    若想实现这样的判断逻辑,可以考虑if-else语句。看一下下面的语法:

    语句0;
    if(逻辑表达式){
            语句块1;
    } else {
            语句块2;
    }
    语句3;

    如上语句的执行步骤如下所示:

    步骤一:执行语句0;

    步骤二:判断if逻辑表达式的值:

    1. 若值为true,则执行语句块1;
    2. 若值为false,则执行语句块2;

    步骤三:执行语句3语句。

    2.3.2. if-else语句流程图

    if-else语句的执行逻辑如下图 - 5所示:


    图- 5

    通过图-5可以看到:当条件满足时,执行语句块1,然后执行if-else语句下面的语句;否则执行语句块2,再执行if-else语句下面的语句。

    2.3.3. if-else语句用于处理分支逻辑

    通过下面的代码,可以解决新增加的异常情况处理问题:

    ……
    if( money >= totalPrice ) {        double change = money – totalPrice;
             System.out.println("应收金额为:" + totalPrice +",找零为:" + change);
    } else {        System.out.println(“Error! 收款金额小于应收金额”);
    }

    说明:money为收款金额,totalPrice为应收金额;当收款金额大于等于应收金额时,则计算找零并输出,否则,提示错误信息。

    2.4. else if语句

    2.4.1. if-else语句的嵌套

    在日常生活中,很多情况并非进行一次逻辑判断就可以获取最终的结果, 如图– 6所示:


    图 - 6

    可以看出,实现制作沙拉的过程进行了两次判断,首先判断是否有黄瓜,若有则直接制作黄瓜沙拉后结束,若没有黄瓜则判断是否有胡萝卜,若有则制作胡萝卜沙拉结束,没有则不能上菜结束。这种情况,单单使用if-else还无法实现,因为if-else只是判断了一次就结束了,而当前的情况需要判断两次。

    在java程序中,当程序的分支数大于2时,可以用if-else嵌套的方式解决,即:else语句块中又包含if语句(或if-else语句),下面看一个实际的需求:

    根据学员的成绩来输出等级:

    1. A(成绩大于等于90分);
    2. B(成绩小于90分且大于等于80分);
    3. C(成绩小于80分且大于等于60分);
    4. D(成绩小于60)。

    此程序即为多路判断,如图– 7所示流程图:


    图- 7

    首先判断分数是否大于等于90,若为真则输出A终止,为假则再判断分数是否大于等于80,若为真输出B终止,为假则再判断分数是否大于等于60,若为真输出C终止,为假则输出D。分析可以看出,该程序经过了3次判断。需要在else中嵌套判断。代码如下所示:

    2.4.2. else if语句执行逻辑

    如下图 – 8所示,在else中再次进行if-else的判断:


    图- 8

    从上图中看出,当判断层数比较多时,代码清晰度不够好,在实际开发中常常使用如下图- 9的方式来实现,事实上,else if结束就是if-else嵌套的简便写法:


    图 – 9

    实现该程序代码如下所示:

    … … ...
    if(score>=90) {
            System.out.println("A");
    } else if (score>=80) {
            System.out.println("B");
    } else if(score>=60) {
            System.out.println("C");
    } else {
            System.out.println("D");
    }

    通过上面的代码可以看出,使用else if方式,程序逻辑更清晰,可读性更好。

    2.5. switch-case语句

    2.5.1. switch-case语句执行逻辑

    switch-case是一种特殊的分支结构,与else if类似,但其应用面不如else if,只能用于特殊的情况之下, switch-case可以根据一个整数值的不同取值,从不同的程序入口开始执行。语法如下所示:

         switch(整型表达式) {
             case 整型常量值1:     //入口1
                 语句1;
                 语句2;
             case 整型常量值2:     //入口2
                 语句3;
                 ……
             default:               //默认入口
                 语句n;
         }

    switch-case流程图见图 – 10所示:


    图- 10

    分析上图,可以看出其执行逻辑如下:

    计算整型表达式的值:

    1. 若值等于整型常量值1,则从语句1开始执行,而后语句2、3,一直执行到语句n。
    2. 若值等于整型常量值2,则从语句3开始执行,一直执行到语句n。
    3. 若没有找到匹配的值,则只执行语句n。

    通过分析可以看出,switch是以case后的整型常量值作为入口的,若值相等,即开始执行其后面的语句。

    使用switch时需要注意两个问题,第一,case后面的常量值必须不同,第二,switch后面的整型表达式的值必须是整型或字符型。

    2.5.2. switch-case和break联合使用

    前面的代码中判断整型表达式的值,若其值等于某个整型常量值,则会以此作为入口,依次执行其后面所有的语句。但是在实际应用中,通常case1、case2、…、caseN对应完全不同的操作,即: 若表达式的值等于case1,则只执行case1后的语句,不会再执行case2、caseN等后面的语句。这种情况下可以和break语句配合使用,执行完相应语句后即退出switch块,不继续执行下面的语句。语法如下所示:

    switch(整型表达式) {
             case 整型常量值1:     //入口1
                 语句1;
                 语句2;
                 break ;
             case 整型常量值2:     //入口2
                 语句3;
                 break ;
                 ……
             default:               //默认入口
                 语句n;
    }

    如上程序中的break语句的作用在于跳出switch结构,其执行逻辑如下:

    1. 计算整型表达式的值:
    2. 如果值等于整型常量值1,则执行语句1、语句2,跳出switch结构结束;
    3. 若值等于整型常量值2,则执行语句3,跳出switch结构结束;
    4. 如果没有找到匹配的值,则执行语句n,结束。default后可以不写break。

    2.5.3. switch-case语句用于分支

    在实际应用中,switch-case语句常常与break配合使用,参见下面的代码:

    int num = 2;
    switch(num) {
             case 1: 
                 System.out.println(“呼叫教学部”);
                 break;
             case 2:
                 System.out.println(“呼叫人事部”);
                 break;
             default:
                  System.out.println(“人工服务”);
    }

    上面代码的输出结果为“呼叫人事部“,因为匹配case 2输出后,即break跳出switch语句了。

    2.5.4. switch-case的优势

    switch-case结构在实际应用中较广泛, 常常和break语句结合使用实现分支的功能。

    在很多情况下,switch-case可以代替else if结构,而switch-case实现分支功能的效率要高于else if结构,并且结构更清晰,所以推荐使用。从JDK 7.0开始,switch-case可以支持字符串表达式,将更加方便程序的操作。

  • 相关阅读:
    centos安装python3
    MongoDB 索引
    dockerfile
    docker端口映射与容器互联
    操作docker容器
    docker数据管理
    ubuntu安装docker
    MVC框架
    图像标签
    HTML的标签
  • 原文地址:https://www.cnblogs.com/hkxd/p/3975919.html
Copyright © 2011-2022 走看看