五、控制流(1)

news2024/9/23 17:23:24

本章概要

  • true 和 false
  • if-else
  • 迭代语句
    • while
    • do-while
    • for
      • 逗号操作符
  • for-in 语法

程序必须在执行过程中控制它的世界并做出选择。 在 Java 中,你需要执行控制语句来做出选择。

Java 使用了 C 的所有执行控制语句,因此对于熟悉 C/C++ 编程的人来说,这部分内容轻车熟路。大多数面向过程编程语言都有共通的某种控制语句。在 Java 中,涉及的关键字包括 if-else,while,do-while,for,return,break 和选择语句 switch。 Java 并不支持备受诟病的 goto(尽管它在某些特殊场景中依然是最行之有效的方法)。 尽管如此,在 Java 中我们仍旧可以进行类似的逻辑跳转,但较之典型的 goto 用法限制更多。

true和false

所有的条件语句都利用条件表达式的“真”或“假”来决定执行路径。举例:
a == b。它利用了条件表达式 == 来比较 ab 的值是否相等。 该表达式返回 truefalse。代码示例:

// control/TrueFalse.java
public class TrueFalse {
	public static void main(String[] args) {
		System.out.println(1 == 1);
		System.out.println(1 == 2);
	}
}

输出结果:

true false

通过上一章的学习,我们知道任何关系运算符都可以产生条件语句。 注意:在 Java 中使用数值作为布尔值是非法的,即便这种操作在 C/C++ 中是被允许的(在这些语言中,“真”为非零,而“假”是零)。如果想在布尔测试中使用一个非布尔值,那么首先需要使用条件表达式来产生 boolean 类型的结果,例如 if(a != 0)

if-else

if-else 语句是控制程序执行流程最基本的形式。 其中 else 是可选的,因此可以有两种形式的 if。代码示例:

if(Boolean-expression) 
	“statement”

if(Boolean-expression) 
	“statement”
else
  “statement”

布尔表达式(Boolean-expression)必须生成 boolean 类型的结果,执行语句 statement 既可以是以分号 ; 结尾的一条简单语句,也可以是包含在大括号 {} 内的的复合语句 —— 封闭在大括号内的一组简单语句。 凡本书中提及“statement”一词,皆表示类似的执行语句。

下面是一个有关 if-else 语句的例子。test() 方法可以告知你两个数值之间的大小关系。代码示例:

// control/IfElse.java
public class IfElse {
  static int result = 0;
  static void test(int testval, int target) {
    if(testval > target)
      result = +1;
    else if(testval < target) // [1]
      result = -1;
    else
      result = 0; // Match
  }

  public static void main(String[] args) {
    test(10, 5);
    System.out.println(result);
    test(5, 10);
    System.out.println(result);
    test(5, 5);
    System.out.println(result);
  }
}

输出结果:

1
-1
0

注解else if 并非新关键字,它仅是 else 后紧跟的一条新 if 语句。

Java 和 C/C++ 同属“自由格式”的编程语言,但通常我们会在 Java 控制流程语句中采用首部缩进的规范,以便代码更具可读性。

迭代语句

whiledo-whilefor 用来控制循环语句(有时也称迭代语句)。只有控制循环的布尔表达式计算结果为 false,循环语句才会停止。

while

while 循环的形式是:

while(Boolean-expression) 
  statement

执行语句会在每一次循环前,判断布尔表达式返回值是否为 true。下例可产生随机数,直到满足特定条件。代码示例:

// control/WhileTest.java
// 演示 while 循环
public class WhileTest {
    static boolean condition() {
        boolean result = Math.random() < 0.99;
        System.out.print(result + ", ");
        return result;
    }

    public static void main(String[] args) {
        while (condition()) {
            System.out.println("Inside 'while'");
        }
        System.out.println("Exited 'while'");
    }
}

输出结果:

在这里插入图片描述

condition() 方法使用到了 Math 库的静态方法 random()。该方法的作用是产生 0 和 1 之间 (包括 0,但不包括 1) 的一个 double 值。

result 的值是通过比较运算符 < 产生的 boolean 类型的结果。当控制台输出 boolean 型值时,会自动将其转换为对应的文字形式 truefalse。此处 while 条件表达式代表:“仅在 condition() 返回 false 时停止循环”。

do-while

do-while 的格式如下:

do 
	statement
while(Boolean-expression);

whiledo-while 之间的唯一区别是:即使条件表达式返回结果为 falsedo-while 语句也至少会执行一次。 在 while 循环体中,如布尔表达式首次返回的结果就为 false,那么循环体内的语句不会被执行。实际应用中,while 形式比 do-while 更为常用。

for

for 循环可能是最常用的迭代形式。 该循环在第一次迭代之前执行初始化。随后,它会执行布尔表达式,并在每次迭代结束时,进行某种形式的步进。for 循环的形式是:

for(initialization; Boolean-expression; step)
  statement

初始化 (initialization) 表达式、布尔表达式 (Boolean-expression) ,或者步进 (step) 运算,都可以为空。每次迭代之前都会判断布尔表达式的结果是否成立。一旦计算结果为 false,则跳出 for 循环体并继续执行后面代码。 每次循环结束时,都会执行一次步进。

for 循环通常用于“计数”任务。代码示例:

// control/ListCharacters.java
public class ListCharacters {
    public static void main(String[] args) {
        for (char c = 0; c < 128; c++) {
            if (Character.isLowerCase(c)) {
                System.out.println("value: " + (int) c + " character: " + c);
            }
        }
    }
}

输出结果(前 10 行):

在这里插入图片描述

注意:变量 c 是在 for 循环执行时才被定义的,并不是在主方法的开头。c 的作用域范围仅在 for 循环体内。

传统的面向过程语言如 C 需要先在代码块(block)前定义好所有变量才能够使用。这样编译器才能在创建块时,为这些变量分配内存空间。在 Java 和 C++ 中,我们可以在整个块使用变量声明,并且可以在需要时才定义变量。 这种自然的编码风格使我们的代码更容易被人理解。

上例使用了 java.lang.Character 包装类,该类不仅包含了基本类型 char 的值,还封装了一些有用的方法。例如这里就用到了静态方法 isLowerCase() 来判断字符是否为小写。

逗号操作符

在 Java 中逗号运算符(这里并非指我们平常用于分隔定义和方法参数的逗号分隔符)仅有一种用法:在 for 循环的初始化和步进控制中定义多个变量。我们可以使用逗号分隔多个语句,并按顺序计算这些语句。注意:要求定义的变量类型相同。代码示例:

// control/CommaOperator.java
public class CommaOperator {
    public static void main(String[] args) {
        for (int i = 1, j = i + 10; i < 5; i++, j = i * 2) {
            System.out.println("i = " + i + " j = " + j);
        }
    }
}

输出结果:

i = 1 j = 11
i = 2 j = 4
i = 3 j = 6
i = 4 j = 8

上例中 int 类型声明包含了 ij。实际上,在初始化部分我们可以定义任意数量的同类型变量。注意:在 Java 中,仅允许 for 循环在控制表达式中定义变量。 我们不能将此方法与其他的循环语句和选择语句中一起使用。同时,我们可以看到:无论在初始化还是在步进部分,语句都是顺序执行的。

for-in 语法

Java 5 引入了更为简洁的“增强版 for 循环”语法来操纵数组和集合。(更多细节,可参考 数组 和 集合 章节内容)。大部分文档也称其为 for-each 语法,但因为了不与 Java 8 新添的 forEach() 产生混淆,因此这里称之为 for-in 循环。 (Python 已有类似的先例,如:for x in sequence)。注意:你可能会在其他地方看到不同叫法。

for-in 无需你去创建 int 变量和步进来控制循环计数。 下面我们来遍历获取 float 数组中的元素。代码示例:

import java.util.*;

// control/ForInFloat.java
public class ForInFloat {
    public static void main(String[] args) {
        Random rand = new Random(47);
        float[] f = new float[10];
        for (int i = 0; i < 10; i++) {
          f[i] = rand.nextFloat();
        }
        for (float x : f) {
          System.out.println(x);
        }
    }
}

输出结果:

在这里插入图片描述

上例中我们展示了传统 for 循环的用法。接下来再来看下 for-in 的用法。代码示例:

for(float x : f) {}

这条语句定义了一个 float 类型的变量 x,继而将每一个 f 的元素赋值给它。

任何一个返回数组的方法都可以使用 for-in 循环语法来遍历元素。例如 String 类有一个方法 toCharArray(),返回值类型为 char 数组,我们可以很容易地在 for-in 循环中遍历它。代码示例:

// control/ForInString.java
public class ForInString {
    public static void main(String[] args) {
        for (char c : "An African Swallow".toCharArray()) {
            System.out.print(c + " ");
        }
    }
}

输出结果:

A n   A f r i c a n   S w a l l o w

很快我们能在 集合 章节里学习到,for-in 循环适用于任何可迭代(iterable)的 对象。

通常,for 循环语句都会在一个整型数值序列中步进。代码示例:

for(int i = 0; i < 100; i++){}

正因如此,除非先创建一个 int 数组,否则我们无法使用 for-in 循环来操作。为简化测试过程,已在 onjava 包中封装了 Range 类,利用其 range() 方法可自动生成恰当的数组。

Range.java

public class Range {
    // Produce sequence [start..end) incrementing by step
    public static int[] range(int start, int end, int step) {
        if (step == 0) {
            throw new IllegalArgumentException("Step cannot be zero");
        }
        int sz = Math.max(0, step >= 0 ? (end + step - 1 - start) / step : (end + step + 1 - start) / step);
        int[] result = new int[sz];
        for (int i = 0; i < sz; i++) {
            result[i] = start + (i * step);
        }
        return result;
    }  // Produce a sequence [start..end)

    public static int[] range(int start, int end) {
        return range(start, end, 1);
    }

    // Produce a sequence [0..n)
    public static int[] range(int n) {
        return range(0, n);
    }
}

在 封装(Implementation Hiding)这一章里我们介绍了静态导入(static import),无需了解细节就可以直接使用。 有关静态导入的语法,可以在 import 语句中看到:

import static BASE0002.Range.range;
// control/ForInInt.java
public class ForInInt {
    public static void main(String[] args) {
        for (int i : range(10)) // 0..9
        {
            System.out.print(i + " ");
        }
        System.out.println();
        for (int i : range(5, 10)) // 5..9
        {
            System.out.print(i + " ");
        }
        System.out.println();
        for (int i : range(5, 20, 3)) // 5..20 step 3
        {
            System.out.print(i + " ");
        }
        System.out.println();
        for (int i : range(20, 5, -3)) // Count down
        {
            System.out.print(i + " ");
        }
        System.out.println();
    }
}

输出结果:

0 1 2 3 4 5 6 7 8 9
5 6 7 8 9
5 8 11 14 17
20 17 14 11 8

range() 方法已被 重载(重载:同名方法,参数列表或类型不同)。上例中 range() 方法有多种重载形式:第一种产生从 0 至范围上限(不包含)的值;第二种产生参数一至参数二(不包含)范围内的整数值;第三种形式有一个步进值,因此它每次的增量为该值;第四种 range() 表明还可以递减。range() 无参方法是该生成器最简单的版本。

range() 的使用提高了代码可读性,让 for-in 循环在本书中适应更多的代码示例场景。

请注意,System.out.print() 不会输出换行符,所以我们可以分段输出同一行。

for-in 语法可以节省我们编写代码的时间。 更重要的是,它提高了代码可读性以及更好地描述代码意图(获取数组的每个元素)而不是详细说明这操作细节(创建索引,并用它来选择数组元素) 本书推荐使用 for-in 语法。(注:本人曾看过一篇文章,是测试不同迭代方式的效率问题,最后结论为使用 for(int i = 0; i < 100; i++){} 方式为最优,个人推荐此方法)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/801448.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

KNN模型进行分类和回归任务

KNN工作原理 “近朱者赤&#xff0c;近墨者黑”可以说是KNN的工作原理。整个计算过程分为三步&#xff1a;1:计算待分类物体与其他物体之间的距离&#xff1b;2:统计距离最近的K个邻居&#xff1b;3:对于K个最近的邻居&#xff0c;它们属于哪个分类最多&#xff0c;待分类物体就…

【Nginx12】Nginx学习:HTTP核心模块(九)浏览器缓存与try_files

Nginx学习&#xff1a;HTTP核心模块&#xff08;九&#xff09;浏览器缓存与try_files 浏览器缓存在 Nginx 的 HTTP 核心模块中其实只有两个简单的配置&#xff0c;这一块也是 HTTP 的基础知识。之前我们就一直在强调&#xff0c;学习 Nginx 需要的就是各种网络相关的基础知识&…

前端程序员入门:先学Vue3还是Vue2?

一、前言 对于新手来说&#xff0c;学习Vue.js框架时往往会有这样一个疑问&#xff1a;应该先学习Vue2还是直接学习Vue3&#xff1f;在回答这个问题之前&#xff0c;我们先简单介绍一下Vue.js框架。 Vue.js是一个轻量级的MVVM(Model-View-ViewModel)框架&#xff0c;它以数据驱…

数字世界未来十年面貌展望

2023年&#xff0c;数字技术已经深刻改变了我们的生活和社会&#xff0c;而未来十年数字世界的面貌将会更加令人瞩目。从人工智能到区块链&#xff0c;从虚拟现实到5G&#xff0c;各种科技将继续发展演进&#xff0c;给我们带来更多令人兴奋的可能性。以下是对数字世界未来十年…

交换机之HOL拥塞

队首阻塞(Head of Line Blocking, HOL)是一种出现在缓存式通信网络交换中的一种现象&#xff0c;其交换结构通常由缓存式FIFO输入端、交换结构(Switch Fabric)、FIFO输出端构成。 HOL阻塞用一个现实生活中的例子说明&#xff0c;就如同你在一条单车道的马路上右转&#xff0c;…

人机交互与人机混合智能的区别

人机交互和人机融合智能是两个相关但不完全相同的概念&#xff1a; 人机交互是指人与计算机之间的信息交流和互动过程。它关注的是如何设计和实现用户友好的界面&#xff0c;以便人们能够方便、高效地与计算机进行沟通和操作。人机交互通常强调用户体验和界面设计&#xff0c;旨…

如何找回删除的文件?文件恢复,3招就行!

“昨天不小心把我的毕业资料删除了&#xff0c;因为改了很多版&#xff0c;删除的时候没想到把正确的版本删除了&#xff0c;错误的版本还在&#xff01;这种情况应该怎么办呢&#xff1f;怎样才能找回我删除的文件呀&#xff1f;” 对于一些比较重要的文件&#xff0c;不小心删…

【C++初阶】C++基础(上)——C++关键字、命名空间、C++输入输出、缺省参数、函数重载

目录 1. C关键字 2. 命名空间 2.1 命名空间的定义 2.2 命名空间的使用 3. C输入&输出 4. 缺省参数 4.1 缺省参数概念 4.2 缺省参数分类 5. 函数重载 5.1 函数重载概念 5.2 C支持函数重载的原理——名字修饰&#xff08;name Mingling&#xff09; 5.3 extern &…

围棋基础知识

1、气 1.1星位位置 1.2天元位置 1.3 气的位置 2、禁入点 白棋里面的位置就是禁入点&#xff0c;也可以称为没有气的位置可以称为禁入点 破解之法&#xff1a; 在于将白棋全部围住&#xff0c;下一步为围住之策&#xff0c;即可。 3、死棋和活棋 3.1活棋 3.2 死棋 白棋的样…

探寻数据服务的本质:API之外的可能性

数据服务在数据建设中发挥着重要的作用。数据服务到底啥样&#xff1f; 是不是只对外提供一个API&#xff1f; 这么简单&#xff1f; 而我希望你能在学完这部分内容之后&#xff0c;真正掌握数据服务的产品功能设计和系统架构设计。因为这会对你设计一个数据服务&#xff0c;或…

青少年护眼灯哪个好?2023全新五款台灯推荐

国内儿童青少年的视力健康问题越来越突出&#xff0c;甚至许多孩子年纪非常小就已经近视了&#xff0c;所以许多老师以及眼科医生都和家长们强调护眼台灯的重要性。不过&#xff0c;护眼台灯虽好&#xff0c;但在选购时也要注意那些无法护眼的不专业品牌&#xff0c;许多产品有…

ICC2如何计算Gate Count?

我正在「拾陆楼」和朋友们讨论有趣的话题&#xff0c;你⼀起来吧&#xff1f;知识星球入口 我们认为gate count等于standard cell(非physical only)总面积 / 最小驱动二输入与非门面积。 ICC2没有专门的命令去报告gate count&#xff0c;只能自己计算&#xff0c;使用report_d…

MySQL数据库——DDL基本操作

文章目录 前言数据库操作查看已存在的所有数据库创建数据库选中数据库删除数据库修改数据库编码 表操作创建表显示创建表时的语句显示表结构删除表修改表的结构增加列修改列删除列 修改表名 前言 DDL 操作是与数据库结构相关的操作&#xff0c;它们不涉及实际的数据操作&#…

B2B企业如何选择CRM系统?

CRM软件的优势在于简化业务流程&#xff0c;实现企业的降本增效。越来越多的B2B企业通过CRM为业务赋能&#xff0c;B2B企业如何快速找到适合公司业务的CRM系统&#xff1f;总的来说就是根据企业自身业务而量身打造的一套系统。 1.整理业务需求 B2B企业首先要考虑是业务痛点&a…

易基因:m6A-seq等揭示RBM33参与调控m6A去甲基化酶ALKBH5活性及其底物选择性|科研进展

大家好&#xff0c;这里是专注表观组学十余年&#xff0c;领跑多组学科研服务的易基因。 RNA结合蛋白&#xff08;RNA-binding protein&#xff0c;RBP&#xff09;是一类结构和功能多样化的蛋白质&#xff0c;参与多种生物过程。越来越多的证据表明&#xff0c;RBP通过调控编…

意外:WPS编程新工具,不用编程,excel用户:可以不用VBA啦

来来来&#xff0c;拓宽一下视野&#xff01; 别总以为excel和WPS只能用VBA编程&#xff0c;也别总是想着ACCESS这些老生常谈的工具。其实对于电子表格高级用户来讲&#xff0c;不会VBA&#xff0c;不用ACCESS&#xff0c;也一样可以解决复杂问题或者高级应用。 尤其是WPS用户…

C++多线程编程(第三章 利用栈特性自动释放锁RALL,锁管理器、控制器)

1、什么是RALL&#xff0c;手动代码实现 RALL&#xff08;resource Acquisition Is Initialization &#xff09;C 之父Bjarne Stroustrup 提出&#xff1b; 使用局部对象来管理资源的技术称为资源获取即初始化&#xff1b;它的生命周期是由操作系统来管理的&#xff0c;无需人…

Hive分区分桶

分区 分区概念 在逻辑上分区表与未分区表没有区别&#xff0c;在物理上分区表会将数据按照分区键的列值存储在表目录的子目录中&#xff0c;目录名“分区键键值”。其中需要注意的是分区键的值不一定要基于表的某一列&#xff08;字段&#xff09;&#xff0c;它可以指定任意…

ubuntu软件:录制视频和截图工具,压缩视频

1. 自带录制视频工具&#xff1b; 使用方式&#xff1a; 无需下载 开始录屏/结束录屏&#xff1a;Ctrl Alt Shift r 当看到 Ubuntu 桌面的右上方多了一个红色的小圆点&#xff0c;代表正在录制 注意&#xff1a; 录屏默认的时长30秒&#xff0c;超时会自动结束&#xff01…

Postman如何导出接口的几种方法

本文主要介绍了Postman如何导出接口的几种方法&#xff0c;文中通过示例代码介绍的非常详细&#xff0c;具有一定的参考价值&#xff0c;感兴趣的小伙伴们可以参考一下 前言&#xff1a; 我的文章还是一贯的作风&#xff0c;简确用风格&#xff08;简单确实有用&#xff09;&am…