[JAVA编程思想]chap3控制流程程序

3.1 使用Java 运算符

一个运算符可改变运算对象的值,这叫作“副作用”(Side Effect)。
几乎所有运算符都只能操作“主类型”(Primitives)。
唯一的例外是“=”、“==”和“!=”,它们能操作所有对象(也是对象易令人混淆的一个地方)。
除此以外,String 类支持“+”和“+=”。

3.1.1 优先级

3.1.2 赋值

取得右边的值,把它复制到左边。
左边的值必须是一个明确的、已命名的变量。
(如果您的 main()用 package 语句封装到一个文件里,那么必须在程序名前面指定完整的包裹名称,否则不能运行程序。在这种情况下,命令行是:java c03.Assignment)
对一个对象进行操作时,我们真正操作的是它的句柄。所以倘若“从一个对象到另一个对象”赋值,实际就是将句柄从一个地方复制到另一个地方。这意味着假若为对象使用“C=D”,那么C 和 D 最终都会指向最初只有 D 才指向的那个对象。

3.1.3 算术运算符

用于打印(显示)的一些快捷方法:prt()方法打印一个String;pInt()先打印一个 String,再打印一个 int;而pFlt()先打印一个 String,再打印一个 float。当然,它们最终都要用System.out.println()结尾。
Random(随机)对象。

3.1.4 自动递增和递减

对于前递增和前递减(如++A 或–A),会先执行运算,再生成值。而对于后递增和后递减(如A++或A–),会先生成值,再执行运算。

3.1.5 关系运算符

尽管对象的内容相同,句柄却是不同的,而==和!=比较的正好就是对象句柄。

若想对比两个对象的实际内容是否相同,又该如何操作呢?此时,必须使用所有对象都适用的特殊方法equals()。但这个方法不适用于“主类型”,那些类型直接使用==和!=即可。

3.1.6 逻辑运算符

只可将 AND,OR 或NOT 应用于布尔值。
操作逻辑运算符时,我们会遇到一种名为“短路”的情况。这意味着只有明确得出整个表达式真或假的结论,才会对表达式进行逻辑求值。

3.1.7 按位运算符

按位运算符可与等号(=)联合使用,以便合并运算及赋值:&=,|=和^=都是合法的(由于~是一元运算符,所以不可与=联合使用)。
我们可执行按位AND,OR 和 XOR,但不能执行按位 NOT。对于布尔值,按位运算符具有与逻辑运算符相同的效果,只是它们不会中途“短路”。

3.1.8 移位运算符

左移位运算符(<<)在低位补0。
“有符号”右移位运算符(>>)
“无符号”右移位运算符(>>>)
移位可与等号(<<=或>>=或>>>=)组合使用。此时,运算符左边的值会移动由右边的值指定的位数,再将得到的结果赋回左边的值。
pBinInt()和pBinLong()。它们分别操作一个int 和long 值,并用一种二进制格式输出,同时附有简要的说明文字。

3.1.9 三元 if-else 运算符

布尔表达式 ? 值 0:值 1

3.1.10 逗号运算符

在Java 里需要用到逗号的唯一场所就是for 循环

3.1.11 字串运算符+

在Java 里有一项特殊用途:连接不同的字串。
“缩小转换”(Narrowing Conversion)
“放大转换”(Widening conversion)

3.1.12 运算符常规操作规则

3.1.13 造型运算符

“造型”(Cast)的作用是“与一个模型匹配”。
表达式中最大的数据类型是决定了表达式最终结果大小的那个类型。

3.1.14 Java 没有“sizeof”

Java 不需要 sizeof()运算符来满足这方面的需要,因为所有数据类型在所有机器的大小都是相同的。我们不必考虑移植问题——Java 本身就是一种“与平台无关”的语言。

3.1.15 复习计算顺序

3.1.16 运算符总结

3.2 执行控制

3.2.1 真和假

3.2.2 if-else

将流程控制语句缩进排列

if(布尔表达式)
 语句
if(布尔表达式)
 语句
else
 语句

3.2.3 反复

while(布尔表达式)
 语句

3.2.4 do-while

do
语句
while(布尔表达式)

while 和do-while 唯一的区别就是do-while 肯定会至少执行一次

3.2.5 for

for(初始表达式; 布尔表达式; 步进)
语句

无论初始表达式,布尔表达式,还是步进,都可以置空。每次反复前,都要测试一下布尔表达式。若获得的结果是 false,就会继续执行紧跟在 for 语句后面的那行代码。在每次循环的末尾,会计算一次步进。
for 循环通常用于执行“计数”任务。

for( char c = 0; c < 128; c++)

Java 里唯一用到逗号运算符的地方就是for 循环的控制表达式。在控制表达式的初始化和步进控制部分,我们可使用一系列由逗号分隔的语句。而且那些语句均会独立执行。

3.2.6 中断和继续

break 用于强行退出循环,不执行循环中剩余的语句。
continue 则停止执行当前的反复,然后退回循环起始和,开始新的反复。
“无限循环”
标签机制,如汇编语言的跳转。
e.g.:while:
(1) 简单的一个 continue 会退回最内层循环的开头(顶部),并继续执行。
(2) 带有标签的 continue 会到达标签的位置,并重新进入紧接在那个标签后面的循环。
(3) break 会中断当前循环,并移离当前标签的末尾。
(4) 带标签的break 会中断当前循环,并移离由那个标签指示的循环的末尾。

3.2.7 开关

switch(整数选择因子) {
case 整数值 1 : 语句; break;
case 整数值 2 : 语句; break;
case 整数值 3 : 语句; break;
case 整数值 4 : 语句; break;
case 整数值 5 : 语句; break;
//..
default:语句;
}

3.3 总结

3.4 练习

1.编写程序以打印从1到100的值。
package control;

public class E01_To100{
	public static void main(String[] args){
		for(int i=1;i<=100;i++)
			System.out.print(i+" ");
	}
}
2.编写程序以生成25个随机int值。 对每个值使用if-else语句将其分类为大于,小于或等于第二个随机生成的值。
package control;
import java.util.*;

public class E02_RandomInts{
	static Random r=new Random(47);
	public static void compareRand(){
		int a=r.nextInt();
		int b=r.nextInt();
		System.out.println("a="+a+",b="+b);
		if(a<b)
			System.out.println("a<b");
		else if (a>b)
			System.out.println("a>b");
		else
			System.out.println("a=b");
	}
	public static void main)String[] args){
		for(int i=0;i<25;i++)
			compareRand();
	}
}
3.修改练习2,使代码被“无限”while循环包围。 然后它将运行,直到您中断它,通常使用Control-C。
package control;

public class E03_RandomInts2{
	public static void main(String[] args){
		while(true)
			E02_RandomInts.compareRand();
	}
}

main()之外的方法完成了上一个练习中的大部分工作,因此这个解决方案只需要对main()进行微小的更改。 正确构建程序,在其生命周期内需要更少的代码更改。 好处可能在于降低软件的维护成本而不是初始版本的成本,但精心设计的程序通常更容易开始运行。

4.编写一个程序来检测和打印素数(整数只能被它们自己和1整除),使用两个嵌套的for循环和模数运算符(%)。
package control;

public class E04_FindPrimes{
	public static void main(String[] args){
		int max=100;
		if(args.length!=0)
			max=Integer.parseInt(args[0]);
		for(int i=1;i<max;i++){
			boolean prime=true;
			for(int j=2;j<i;j++)
				if(i%j==0)
					prime=false;
				if(prime)
					System.out.print(i+" ");
		}
	}
}

注意,程序包括1作为素数,即使2通常被认为是最小素数。
找到素数的最快方法之一叫做the Sieve of Eratosthenes。

5.重复上一章的练习10,但使用三元运算符和按位测试而不是Integer.toBinaryString()来显示1和0。

私有静态方法toBinaryString()的行为类似于Integer.toBinaryString(),使用缓冲区来保存二进制数字,因为打印出遇到的数字会产生反转输出。

6.修改前两个程序中的两个test()方法,使它们有两个额外的参数,begin和end,这样testval就会测试它是否在(包括)begin和end之间的范围内。
package control;

public class E06_RangeTest{
	static boolean test(int testval,int begin,int end){
		boolean result=false;
		if (testval>=begin && testval<=end)
			result=true;
		return result;
	}
	public static void main(String[] args){
		System.out.println(test(10,5,15));
		System.out.println(test(5,10,15));
		System.out.println(test(5,5,5));
	}
}
7.修改练习1,以便程序通过在值99处使用break关键字退出。请尝试使用return。
package control;

public class E07_To98{
	public static void main(String[] args){
		for(int i=1;i<=100;i++){
			if(i==99)
				break;
			System.out.print(i+" ");
		}
	}
}
8.在for循环中创建一个switch语句,尝试每个case并打印一条消息。 在每个案例之后break并测试它,然后看看当你移除break时会发生什么。
package control;

public class E08_SwitchDemo{
	public static void main(String[] args){
		for(int i=0;i<7;i++)
			switch(i){
				case 1:System.out.println("case 1");break;
				case 2:System.out.println("case 2");break;
				case 3:System.out.println("case 3");break;
				case 4:System.out.println("case 4");break;
				case 5:System.out.println("case 5");break;
				default: System.out.println("default");
			}
	}
}				

有break的输出:

default 
case 1 
case 2 
case 3 
case 4 
case 5 
default

没有break的输出:

default 
case 1 
case 2 
case 3 
case 4 
case 5 
default 
case 2 
case 3 
case 4 
case 5 
default 
case 3 
case 4 
case 5 
default 
case 4 
case 5 
default 
case 5 
default 
default
9.Fibonacci序列是数字1,1,2,3,5,8,13,21,34等的序列,其中每个数字(从第三个开始)是前两个的总和。 创建一个以整数作为参数的方法,并从头开始显示许多斐波那契数字。 例如,如果您运行java Fibonacci 5(其中Fibonacci是类的名称),则输出将为:1,1,2,3,5。
package control;

public class E09_Fibonacci{
	static int fib(int n){
		if(n<=2)
			return 1;
		return fib(n-1)+fib(n-2);
	}
	public static void main(String[] args){
		int n=Integer.parseInt(args[0]);
		if(n<0){
			System.out.println("cannot use negative numbers");
			return;
		}
		for (int i=1;i<=n;i++)
			System.out.println(fib(i)+",");
	}
}

此问题通常在介绍性编程类中提供,它使用递归,这意味着函数会调用自身,直到达到触底条件并返回。

10.吸血鬼号码具有偶数个数字,并且通过乘以包含结果的一半数字位数的一对数字而形成。 数字以任何顺序从原始数字中获取。 不允许成对的尾随零。 例子包括:1260 = 21×60,1827 = 21×87,2187 = 27× 81。编写一个程序,找到所有4位数的吸血鬼号码。
package control;

public class E10_Vampire{
	public static void main(String[] args){
		int[] startDigit=new int[4];
		int[] productDigit=new int[4];
		for(int num1=10;num1<=99;num1++)
			for(int num2=num1;num2<=99;num2++){
				// Pete Hartley's theoretical result: 
				// If x·y is a vampire number then 
				// x·y == x+y (mod 9)
				if((num1*num2)%9!=(num1+num2)%9)
					continue;
				int product=num1*num2;
				startDigit[0]=num1/10;
				startDigit[1]=num1%10;
				startDigit[2]=num2/10;
				startDigit[3]=num2%10;
				productDigit[0]=product/1000;
				productDigit[1]=(product%1000)/100;
				productDigit[2]=product%1000%100/10;
				productDigit[3]=product%1000%100%10;
				int count=0;
				for(int x=0;x<4;x++)
					for(int y=0;y<4;y++){
						if(productDigit[x]==startDigit[y]){
							count++;
							productDigit[x]=-1;
							startDigit[y]=-2;
							if(count==4)
								System.out.println(num1+*num2+":"+product);
						}
					}
			}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值