本文是《Java学习指南》原书的网络版,作者邵发,拥有本书的全部权利。相关视频课程在此查看。
目录
第4章 语句
4.1 语句的概念
先稍微了解一下语句的概念。语句,Statement,表示一行可执行的代码。例如,
示例1:
package my;
public class HelloWorld
{
public static void main(String[] args)
{
int a = 10;
double b = 12.34;
a = (int) (b * b);
System.out.println("a=" + a );
}
}
这里有4条语句。它们的特点是,位置在main大括号里面,并且以分号结束。
并非所有以分号结束的代码都叫语句,比如 package my; 这一行代码,由于位置不在main{ } 这个大括号里,所以就不叫语句。
通常把一条语句单独写在一行里,但是也可以把多条语句凑在一行里书写。比如以下的代码,就很不美观,可读性很差。数一数在这个代码,总共有几条语句呢?
a=10; b=11; c = 12;
虽然都写在同一行里,但是它们是3条语句,因为每个分号就算是一条语句。
4.1.1 空语句
一个单独的分号也算是一条语句,称为空语句,也就是说这条语句什么也没干。例如,
int a = 10;
;
;
;
a ++;
这里有5条语句,其中3条是空语句。看到了吗,虽然只有一个分号,也是算一条语句的。
4.1.2 复合语句
可以把多条语句合在一个大括号里,构成一个复合语句。例如,
{
int a = 10;
a ++;
}
这个就不多解释了。这一节只是纯概念的东西,有一点点印象即可,无需深入探讨。
4.2 if语句
在Java里,用if语句来实现“当满足XXX条件时,执行YYY”这样的逻辑判断。
例如,在使用共享单车时需要检查人的年纪。如果在12岁以下,则禁止骑行。用Java代码可以表示为,
int age = 11; // 年龄
if ( age < 12 )
{
System.out.println("未满12岁,不能骑小黄车");
}
在这里就使用了if 语句。其基本形式如下,
if ( E1 )
{
S1
}
其运行规则为:“当E1成立时,执行S1”。 也就是说,当E1的值为true时执行S1语句。
4.2.1 分步过程讲解
为了方便书面讲解,对每一行代码前面加一个行号。做两组测试。
* 第一组测试 *
1 2
3
4 | int age = 11 ; // 年龄 if ( age < 12 ) { System.out.println("未满12岁,不能骑小黄车"); } System.out.println("结束"); |
运行过程如下:
运行 ①:age的值为11
运行 ②:先计算 a<12 的值为true ,所以会进入大括号内部运行
运行 ③:
运行 ④:结束
* 第二组测试 *
现在,我们把初始条件 age 设为14,再运行一下:
1 2
3
4 | int age = 14 ; // 年龄 if ( age < 12 ) { System.out.println("未满12岁,不能骑小黄车"); } System.out.println("结束"); |
则运行过程如下:
运行 ①: age的值为14
运行 ②: 先计算 a<12 的值为false,所以直接跳出if
运行 ④: 结束
4.2.2 if语句的两种基本形式
if语句有两种基本写法,分别介绍一下。
第一种:
if ( E1 )
{
S1
}
第二种:表示“如果,。。。;否则,。。。”这样的逻辑。如果E1成立,就执行S1;否则,就执行S2。
if ( E1 )
{
S1
}
else
{
S2
}
下面就第二种写法给一个例子。
例如,一个学生的分数用score来表示,如果分数少于60分,则判定为不及格;否则,则提示通过、并有奖励。
代码如下,
int score = 77; // 分数
if ( score < 60)
{
System.out.println("不及格!得重考啦!");
}
else
{
System.out.println("恭喜,通过了!");
System.out.println("有奖励!");
}
System.out.println("结束");
通过这个例子,我们发现大括号里其实是可以添加多条语句的。比如,在else{ } 里,我们添加了2行语句,它们会一并执行。
4.2.3 if语句的完全形式
用if... else if ... else if ... else 可以表示“如果... 再如果 ... 再如果...否则”这样的多重判断的逻辑。形式如下,
if ( E1 )
{
S1
}
else if ( E2 )
{
S2
}
else if (E3)
{
S3
}
else
{
SS
}
在运行时,先判断E1是否成功;若E1不成产,再判断E2是否成功;...一直到最后一个条件。
下面举一个例子来说明这种多重条件的判断。例如,一个学生分数score,若在90分以上记为A,若在80-90分记为B,若在70-80记为C,若在70分以下记为D。代码如下,
int score = 77;
if ( score >= 90 ) // 90以上
{
System.out.println("等级: A");
}
else if (score >= 80) // 80-90
{
System.out.println("等级: B");
}
else if (score >= 70) // 70-80
{
System.out.println("等级: C");
}
else // 70以下
{
System.out.println("等级: D");
}
System.out.println("结束");
有的同学可能为问,第2重条件判断为什么不是
else if ( score>=80 && scroe < 90 )
呀?这是因为,前端已经判断过了第一重条件 score > 90 ,第一重条件不成立,才能走第二重条件这里。所以,就不用重复判断了。
4.2.4 常见问题
if语句相对比较容易,其实和我们日常生活中的逻辑是一样的。唯一需要提醒和注意的是,在书写if语句的时候,不要加分号。例如,
提示:看书百遍,不如自己手写一遍。先把例子码一遍,然后就去本教程的配套题库去练习一下吧!
4.3 for语句
4.3.1 引例
为了便于大家的理解,先给出一个引例。要求写一段代码,计算1到100的平方之和。怎么实现呢?
int total = 0;
total += 1 * 1;
total += 2 * 2;
...写100行类似的语句 ...
total += 100 * 100;
System.out.println("结果为: " + total);
现在我们所学的还太少,要实现这个功能的话,似乎只有老老实实写一百行非常机械的代码了!
但这么写的话,毕竟是心有不甘的,Java为设计得这么愚蠢吗?不会的,肯定有一种方式,可以快速的实现这种有规律的循环逻辑。
4.3.2 for语句
在Java语言里,使用for语句来实现循环逻辑。其基本形式为,
for ( E1; E2; E3 )
{
S1
}
其中,
E1: 初始化表达式
E2: 前置表达式(循环条件判断)
E3: 后置表达式
S1: 循环体
其执行的步骤为:
① 运行初始化表达式E1,仅执行一次
② 运行E2(循环条件):条件若成立,则执行循环; 否则退出循环
③ 运行S1(循环体)
④ 运行E3(后置表达式)
⑤ 执行下一轮: ② ③ ④
简单的讲,一轮循环就是 E2 >> S1 >> E3 ,每轮循环之前先判断E2是否成立。E2为True则执行本轮循环,否则退出循环。
现在,用for语句来解决引例的问题,代码如下,
int total = 0;
int i;
for ( i=1 ; i<=100 ; i++ )
{
total += i * i;
}
System.out.println("结果为: " + total);
其中,
E1 :i=1 将 i初始化为1
E2 : 每次判断 i<=100 是否成立
S1 : 循环体为 total += i * i
E3 : 在循环体之后执行 i ++
其中,E2 >> S1 >> E3 构造一个循环。
4.3.3 更多例子
例:求1到100以内,能被3整除的数 (如3 6 9 12 ... )
示例代码如下,
int i;
for ( i=1 ; i<=100 ; i++ )
{
if ( i % 3 == 0)
{
System.out.println("Got: " + i );
}
}
在for的循环体里,使用了一个if语句来判断i的值是否为3的倍数。若i % 3 == 0 ,则表明i就是3的倍数。
通过这个例子,我们知道在for语句里是可以添加其他语句(如if语句)的。
4.3.4 循环变量
通常,我们可以把用于循环迭代的那个变量直接写在for语句的小括号里,例如,
for (int i=1; i<=100; i++)
{
。。。
}
也就是说,把 int i=1 直接定义在初始化变达式里,这样的专门用于循环的变量,有时候我们称为循环变量。(这不是正式的术语)
4.4 for语句的嵌套
前面我们已经见识了,在for语句里可以嵌套if语句。实际上,这些语句都是可以多层嵌套的。
例如这种形式也可以,
if ( ... )
{
for (...) { }
}
再复杂一点,像下面这种形式也可以,
for (...)
{
for (...)
{
for(...) {}
}
}
这种写法是很自然、也是很常见的,并没有固定的术语。为了方便我们的教学,把这种现象通俗地称为嵌套。
4.4.1 例子
给定整数n,当n为偶数时从小大到输出,n为奇数时从大到小输出。
示例代码如下,
int nnn = 11;
if( nnn % 2 == 0)
{
// nnn为偶数,从小到大输出
for (int i=1; i<= nnn;i++)
{
System.out.print( i + " ");
}
}
else
{
// nnn为奇数,从大到小输出
for (int i= nnn; i >0; i--)
{
System.out.print( i + " ");
}
}
在这个例子,我们发现:
v 在if语句里,可以嵌套for语句
v for语句也可以从大到小递减的方式来实现循环逻辑
例如, for (int i= nnn; i >0; i--)
v print() 用于输入文本,不换行
而println () 则在输出文本时末尾有换行
4.4.2 例子
再看一个例子。
要求输出打印以下图形:
*
**
***
****
先来分析一下,这样的图形有什么循环规律呢?
第1行有1个星
第2行有2个星
... 第i行有i个星
根据这个规律分析,用一个嵌套的循环(2重循环)就可以实现这样的功能。代码如下,
int N = 5;
for ( int i=0; i<N; i ++) // 循环变量 i
{
for(int k=0;k <=i; k++) // 循环变量 k
{
System.out.print("*");
}
System.out.print("\n"); // 输出换行
}
其中,print ("\n" ) 表示输出一个换行。
对于初学者来说,循环变量从0开始、还是从1开始,是一个问题。比如,以下两个写法都是可以的,
for (int i=0; i<n; i++)
for (int i=1; i<=n; i++)
但是,按照计算机编程的惯例,我们一般采用从0开始的写法。即,
for (int i=0; i<n; i++)
{
}
这种从0开始计数的写法是推荐写法。初学者开始会觉得不适应这种思维,但是坚持十几天后就会习惯的。
4.5 break与continue
在循环体中,break与continue可以控制循环的运行。其中,break用于中断循环,continue用于跳过本轮循环。
4.5.1 break语句
例1,
for (int i=0; i<100; i++)
{
if ( i >= 10)
{
break; // 运行到break时循环中止
}
System.out.println( i + " ");
}
当运行到i为10时,i>=10成立,执行break语句,退出循环。
4.5.2 continue语句
例2 ,打印所有1-20的数,当n为4的整数倍时除外。
for(int i=1; i<=20;i++)
{
if(i %4 ==0)
{
continue; // 跳过本轮,进入下一步
}
System.out.print( i + " ");
}
当 i%4==0时,continue被执行,跳过本轮,进入下一轮。所以执行的结果为:
4.5.3 注意事项
v break和continue必须放在循环里
v 当存在嵌套时, break中断的是上层循环,不是上上层循环
4.6 for语句的变形
下面我们来了解一下for语句的几种特殊形式。一般形式下,
for (E1 ; E2; E3)
{
S1
}
在这里,E1, E2, E3都是可以置空的。最极端的情形,
for ( ; ; ) // E1,E2,E3均置空
{
System.out.println("in loop");
}
也就是说,即便小括号的三个部分均为空,也是符合语法规则的。
下面分别按三种情况,来讨论一下E1,E2,E3为空的三种变形。为方便讨论,先给出一个标准形式的写法。如下代码,
以下代码,打印了从0到9的十个数字。
for (int i=0; i<10; i++)
{
/ 循环体
System.out.print(i + " ");
//
}
4.6.1 初始化E1为空
小括号里的第一部分表示初始化,在第一次循环之前运行。因此,在形式可以将E1表达式提到for语句之前,并没有什么影响。
int i=0;
for ( ; i<10 ; i++) // E1为空
{
/ 循环体
System.out.print(i + " ");
//
}
小括号里的第一部分表示初始化,在第一次循环之前运行。因此,在形式可以将E1表达式提到for语句之前,并没有什么影响。
4.6.2 循环条件E2为空
E2如果为空,则默认为true,每轮循环都会执行。例如,
for ( int i=0 ; ; i++) // E2为空
{
/ 循环体
System.out.print(i + " ");
}
由于E2为空,所以这个循环会一直运行,没有休止。可以在循环体中加上条件判断,来控制循环的中止。例如,
for ( int i=0 ; ; i++)
{
if ( i>= 10)
{
break; // 控制循环退出
}
/ 循环体
System.out.print(i + " ");
}
4.6.3 后置表达式E3为空
后置表达式E3在循环体之后运行,也可以置空,如下,
for ( int i=0 ; i<10 ; ) // E3为空
{
/ 循环体
System.out.print(i + " ");
i ++; // 放在循环体的下面执行,效果相同
}
通过以上3种情况的比较,可以发现for语句的写法是比较灵活的。对于初学者来说,应以标准形式为主。对于这三种变形,稍微了解即可。
4.7 while语句
在Java里,while语句也用于表示“循环”的逻辑。其一般形式为,
while ( E1 )
{
S1
}
运行规则为:当条件E1成立的时候,执行循环体S1;否则退出循环。
4.7.1 例子
先给出一个简单的例子。要求打印1到10之间的数,可以用while语句实现如下,
int i = 1;
while ( i <=10)
{
System.out.println( i);
i++;
}
按照while语句的规则,每轮循环之前,要检查循环条件 i<=10是否成立。所以,此循环体会执行10轮,然后结束退出。
4.7.2 while语句的变形
以上例子也可以写成,
int i = 1;
while ( true ) // 循环条件总是为true
{
if(i > 10)
{
break;
}
System.out.println( i);
i++;
}
在这里,循环条件总是为true,所以它成一个无限循环。为了控制循环的退出,在循环体检查if(i>10)时,使用break语句来控制循环的退出。
小结一下,在Java语言里,一共有三种形式的循环,分别为:
for ( E1; E2; E3) { S1 }
while( E1 ) { S1 }
do { S1 } while (E1);
所有的循环其运行的本质原理都是相同的,而且在写法上也是可以互相转换的。也就是说,一个循环可以用 for 实现,也必须可以用 while来实现。
其中我们常用的就是for和while ,另一种do...while循环并不常用。