`
缠小溪
  • 浏览: 24250 次
  • 性别: Icon_minigender_1
  • 来自: 江苏
社区版块
存档分类
最新评论

控制程序流程

 
阅读更多

、使用运算符

几乎所有的运算符都只能操作基本数据类型,唯一例外的是“=”、“==”和“!=”,它们能操作所有对象。除此之外,String类支持“+”和“+=”

1、优先级

使用括号来明确运算顺序是一个很好的习惯。

2、赋值

赋值使用“=”运算符进行的,它的含义是:取得右边的值,把它复制给左边。

基本数据类型的赋值是非常直接的。假设使用A=B的模式赋值,那么具体的操作就是把B处的值复制到A处,若接着有修改了A,B是不受到任何影响的。作为一个程序员,这个应该是自己的一个常识。

对象的赋值是特殊的。对一个对象进行操作时,我们实际上操作的是对象的句柄。倘若从一个对象到另一个对象赋值,其实是句柄从一个地方复制到另一个地方。比如C=D,那么C和D都指向最初只有C指向的那个地方。改变任何一个,最终数据都会改变。

//:Assignment.java

//Assignment with objects is a bittricky

package c03;

class Number{

inti;

}

publicclassAssignment {

publicstaticvoid main(String[] args){

Numbern1=newNumber();

Numbern2=newNumber();

n1.i=9;

n2.i=47;

System.out.println("1:n1.i:"+n1.i+",n2.i:"+n2.i);

n1=n2;

System.out.println("2:n1.i:"+n1.i+",n2.i:"+n2.i);

n1.i=27;

System.out.println("3:n1.i:"+n1.i+",n2.i:"+n2.i);

}

}///:-

观察上述程序的输出结果:由此可以看出基本类型的赋值操作和对象的赋值操作的区别。

1:n1.i:9,n2.i:47

2:n1.i:47,n2.i:47

3:n1.i:27,n2.i:27

方法调用中的别名处理

讲一个对象传递到方法内部时,也会出现别名现象。

//:PassObject.java

//passing objects to methods canbe a bit tricky

package c03;

class Letter{

charc;

}

publicclassPassObject {

staticvoid f(Letter y){

y.c='z';

}

publicstaticvoid main(String[] args){

Letterx=newLetter();

x.c='a';

System.out.println("1:x.c:"+x.c);

f(x);

System.out.println("2:x.c:"+x.c);

}

}

输出结果如下:可以看出,y和x是同一个对象,只不过,y是x的别名而已,这种情况需要特别注意。

1:x.c:a

2:x.c:z

3、算术运算符

//:MathOps.java

//Demonstrates the mathematicaloperators

package c03;

import java.util.*;

publicclassMathOps {

//creating a shorthand to sava typing

staticvoid prt(String s){

System.out.println(s);

}

//shorthand to print a string and an int:

staticvoid pInt(String s,int i){

prt(s+"="+i);

}

//shorthand to print a string and a float:

staticvoid pFlt(String s,Float f){

prt(s+"="+f);

}

publicstaticvoid main(String[] args){

//create a random number generator

//seeds with current time by default

Randomrand=newRandom();

int i,j,k;

//'%' limits maximun value to 99

j=rand.nextInt()%100;

k=rand.nextInt()%100;

pInt("j",j);

pInt("k",k);

i=j+k;pInt("j+k",i);

i=j-k;pInt("j-k",i);

i=k/j;pInt("k/j",i);

i=k*j;pInt("k*j",i);

j%=k;pInt("k%j",j);

//floating-point number tests:

float u,v,w;

v=rand.nextFloat();

w=rand.nextFloat();

pFlt("w",w);

pFlt("v",v);

u=v+w;pFlt("v+w",u);

u=v-w;pFlt("v-w",u);

u=v/w;pFlt("v/w",u);

u=v*w;pFlt("v*w",u);

//the following also works for

//char byte short int long and double

}

}

该代码的第一个两点:设置用于打印显示的一些快捷方法

staticvoidprt(String s){

System.out.println(s);

}

生成模运算对象减一的随机数字

k=rand.nextInt()%100;


4、自动递增和递减

对于前递增和递减,先执行运算在生成值,对于后递增和递减,先生成值后执行运算。

5、 关系运算符

关系运算符生成的是一个boolean结果。若关系是真是的,则true;若关系不真实,则false。

对于基本类型==和!=比较的是数据的值,而对于对象来说,==和!=则比较的是对象的句柄,所以即使他们的对象的值相同,但是他们的句柄不相同,所以返回值也不相同。要使用equals()来比较,但是equals()的默认行为比较的是句柄,在有些时候也会出现意想不到的结果。

6、 逻辑运算符

逻辑运算符能生成一个boolean值,逻辑运算符中运算的也是boolean值,所以不能将一个非boolean值当做boolean值在逻辑表达式中使用。

“短路”情况

操作逻辑运算符时,我们会遇到一种名为短路的情况,在判断式能够确定的前提下,程序不会运算完所有的逻辑表达式。

7、按位运算符

8、位移运算符

9、 三元if-else运算符

格式如下:布尔表达式?值0:值1

若boolean表达式为true,计算值0,否则计算值1

10、 逗号运算符

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

11、 子串运算符+

12、 造型运算符(强制转换)

“造型”(cast)的作用是“与一个模型匹配”。在适当的时候,java会将一种数据类型转换成另一种,也就是类型的强制转换。

我们既可以对一个数值进行造型处理,也可以对一个变量进行造型处理。

造型处理的时候如果遇到“缩小转换”(容量大的强制转换成容量小的),此时就可能面临信息丢失的危险。并且此时编译器让你必须明确造型,在暗示这是一种大转小的过程,可能会有信息丢失的危险。如果是小转大,编译器则不会刻意让你必须明确造型,它会自动进行。

Java允许我们将任何主类型造型成其他任何一种类型。但是boolean要除外。“类”不允许造型。

字面值

一般情况下,编译器会根据字面值来明确数值的类型,但是,有些情况下这种情况是暧昧不清的。此时的处理办法就是添加一些额外信息来帮助编译器明确数据类型。比如,double类型的数据后面加d,float的类型后面跟f等。这些单个字母的大小写都一样。

通常表达式中最大的数据类型决定了表达式的最终结果数据类型。

java没有sizeof

其他语言如c中存在sizeof是用来获取为数据项目分配的字符数量,这样就能够在不同机器之间移植的时候避免出错。Java是一个与平台无关的语言,所以在根本上来说,他是不需要这个功能的。

//Arithmetic operators

//!x=x*y; The operator * is undefined for the argumenttype(s) boolean, boolean

//!x=x/y; The operator / is undefined for the argumenttype(s) boolean, boolean

//!x=x%y; The operator % is undefined for the argumenttype(s) boolean, boolean

//!x=x+y; The operator + is undefined for the argumenttype(s) boolean, boolean

//!x=x-y; The operator - is undefined for the argumenttype(s) boolean, boolean

//!x++; Typemismatch: cannot convert from boolean to int

//!x--; Typemismatch: cannot convert from boolean to int

//可以看出boolean类型无法进行算术运算

Boolean值的能力非常有限,我们只能为其赋予false或true值,而且可以测试它为真还是为假,但不可为它再添加boolean值,或进行其他任何类型运算。

在char,byte和short中,算术运算会有转型的效果,运算结果会获得一个int类型的值,必须将其明确造型成原来的类型。

在进行运算的时候选择合适的数据类型是相当重要的,比如两个比较大的int型在运算后结果也会是int型,但是由于运算结果太大,结果溢出,但是编译器此时不会报错,程序也是正确进行,这种安全隐患是很重要的。

二、执行控制

java并不支持非常有害的goto(它仍是解决某些特殊问题的权宜之计)。仍然可以进行像goto那样的跳转,但是比典型的goto要局限很多。

1、 真和假

Java不允许我们将一个数字作为boolean值使用,即使它在C或者C++中是允许的(真是非零,而假是零)。若想在一个boolean测试中使用一个非boolean值,那么必须想将他通过条件表达式来转换成boolean值

2、if-else

条件必须产生一个boolean结果。

Return关键字

Return指定一个方法返回什么值,并立即返回那个值。在if中,遇到return之后便不再继续。

3、 反复(循环)

While(boolean表达式){}

4、 do-while

Do{}wihle(boolean表达式)

5、for循环

格式:for(初始表达式;boolean表达式;步进(steeping))

无论表达式,boolean表达式还是steep都可以置空

6、中断和继续 break and continue

Break用于强行退出循环,不执行循环中剩余语句。

Continue停止执行当前的反复,然后退回循环起始,开始新的反复。

臭名昭著的goto

尽管goto仍是java的保留字,但并未在语言中得到运用。Java没有goto。continue和break之所以和goto扯上关系是在于他们使用了标签:label 如:

Label1:

外部循环{

内部循环{

Break 1;中断内部循环

Continue1;循环移动到起始处

Continuelabel1;中断内部循环和外部循环,并在label1处开始重新进入循环。

Break label1;中断内部循环和外部循环,回到label1处但是并不进入循环。

}

}

//java's labeled for loop

package c03;

publicclassLabeledFoe {

publicstaticvoid main(String[] args){

int i=0;

outer://can't have statements here

for(;true;){//infinite loop

inner://can't hava statements here

for(;i<10;i++){

System.out.println("i="+i);

if(i==2){

System.out.println("continue");

continue;

}

if(i==3){

System.out.println("break");

i++;//otherwise i never gets incremented

break;

}

if(i==7){

System.out.println("continue outer");

i++;

continue outer;

}

if(i==8){

System.out.println("break outer");

break outer;

}

for(int k=0;k<5;k++){

if(k==3){

System.out.println("continue inner");

continue inner;

}

}

}

}

//can't break or continue to labels here

}

}

运行结果:

i=0

continue inner

i=1

continue inner

i=2

continue

i=3

break

i=4

continue inner

i=5

continue inner

i=6

continue inner

i=7

continue outer

i=8

break outer

我们要注意如下重要问题:

程序执行流程在抵达for循环末尾之前,步进表达式不会执行。For中使用break的时候会跳过步进表达式。Continue outer语句同样跳过了步进表达式。

Break只能跳出内部循环,没有break outer语句的话,该循环是没有退出口的,如果不想使用break outer可以用return来退出循环。

Java里唯一要用到标签的地方就是嵌套循环,而且像中断或者继续多个嵌套级别的时候。

7、 开关 switch(选择)

根据一个整数表达式的值,switch语句可从一系列代码中选取一项执行。它要求使用一个选择因子,并且必须是int或是char型的整数值。非整数的类型,就只能够用一系列的if语句了。

将一个float或者double造型成int时,不会四舍五入,总是砍掉小数部分,只保留整数部分。

//what happens when you cast afloat or double to an integeral value?

package c03;

publicclassCastingNumbers {

publicstaticvoid main(String[] args){

double

above=0.7,

below=0.4;

System.out.println("above:"+above);

System.out.println("below:"+below);

System.out.println("(int)above:"+(int)above);

System.out.println("(int)below:"+(int)below);

System.out.println("(char)('a'+above):"+(char)('a'+above));

System.out.println("(char)('a'+below):"+(char)('a'+below));

}

}

运行结果如下:

above:0.7

below:0.4

(int)above:0

(int)below:0

(char)('a'+above):a

(char)('a'+below):a

Math.random()的输出范围是[0,1)
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics