第5章 在程序中存储和修改信息
本章介绍如下内容:
创建变量;
使用不同类型的变量;
在变量中存储值;
在数学表达式中使用变量;
把一个变量的值赋给另一个变量;
递增或递减变量的值。
在第2章中,我们使用到了一个变量,它是一个用于存储信息的特殊位置。程序运行时,变量中存储的信息可以发生改变。在你的第一个程序中,变量中存储了一个字符串。字符串只是可在变量中存储的一种信息类型,变量还可以存储字符、整数、浮点数和其他类型的信息。
本章将更详细地介绍如何在Java程序中使用变量。
5.1 语句和表达式
计算机程序是一组告诉计算机做什么的指令,每一个指令称为语句。下面就是Java程序中的一条语句:
在Java程序中,可以使用括号将一组语句编组,这一组语句称为块语句(block statement)。请看下面的程序片段:
其中第2~4行是一条块语句。第1行的左大括号表示块语句开始,第5行的右大括号表示块语句结束。
有些语句被称为表达式,原因是它包含一个数学表达式,并能得到一个结果。在上面的例子中,第4行就是一个表达式,因为它将变量c的值设置为8和5的乘积。在接下来的几节中,读者将会用到表达式。
5.2 指定变量类型
计算机在运行程序时,变量是计算机记住信息的主要方法。第 2 章的 Saluton 程序使用greeting 变量来存储“Saluton mondo!”消息。计算机需要记住这段文本,以便稍后显示。
在Java程序中,创建变量所使用的语句必须包含下列两项内容:
变量名;
变量存储的信息类型。
变量也可以包含将要存储的信息的值。
要看不同类型的变量以及如何创建它们,可以运行NetBeans,然后创建一个新的空Java文件,其类名为Variable。
开始编写程序,输入下面的代码:
对其进行修改前保存该文件。
至此,程序Variable有了一个main()块,其中只包含一条语句:注释//Coming soon: varia-bles。删除注释并输入下列语句:
这条语句创建一个名为tops的变量,但没有给它赋值,因此该变量此时是一个空的存储空间。语句开头的int指定tops是一个用于存储整数的变量。可以使用int类型来存储计算机程序所需的大多数整数,它能够存储−2.14×109~2.14×109的任何整数。
在语句 int tops;的末尾换行,然后输入下面的语句:
这条语句创建一个名为gradePointAverage的变量,其中float表示浮点数。浮点数变量用来存储可能包含小数的数值。
float变量类型可以存储高达38位的十进制数,而double变量类型可以存储高达300位的十进制数。
注意:
可以使用浮点变量来存储像2.25这样的绩点成绩(GPA)(我进入北德克萨斯大学的 GPA 就是 2.25),还可用于存储像 0 这样的数字。我当年凭GPA进入一所好研究院的机会也是0。不过,我在1996年找工作时,仍然被Sams出版社慧眼识珠,招募为他们的计算机图书作者。
到目前为止,你所处理的变量都是数值型的,因此可能认为所有变量都是用来存储数字的。也可以使用变量来存储文本,在变量中可以存储两种类型的文本:字符和字符串。字符是单个字母、数字、标点符号或其他符号。字符串是一组字符。
创建Variable程序的下一步是创建一个char变量和一个String变量。在语句float gradePoint Average;后面加入下面两条语句:
在程序中使用字符值时,必须用单引号将赋给变量的字符值括起来,而对于字符串值必须用双引号括起来。
引号可以将字符或字符串同变量名或其他语句部分区分开来。请看下面的语句:
这条语句看起来好像告诉计算机,创建一个名为productName的字符串变量,并将文本值 Larvets 赋给该变量。但是由于没有使用双引号将单词 Larvets 括起,计算机认为要将productName的值设置为变量Larvets的值。
加入 char 和 String 语句后,程序将如程序清单 5.1 所示。在更改之后,不要忘记存盘。
程序清单5.1 Variable程序
Variable程序中的最后两个变量在创建时,使用等号“=”赋予了初始值。在Java程序中,可以用这种方法给任何变量赋值,这将在本章后面看到。
该程序可以运行,但是不会产生输出。
注意:
尽管其他变量类型都是小写字母(int、float和char),但创建字符串变量时,单词String的首字母必须大写。在Java程序中,字符串与变量语句中使用的其他信息类型不同,这将在第6章介绍。
前面介绍的变量是本书使用的主要变量类型,读者编写的大多数Java程序也可能如此。在特殊情况下,还可使用其他几种变量。
还有3种其他类型的整型变量。第一种为byte,取值范围为−128~127的整数。下面的语句是创建一个名为escapeKey的变量,其初始值为27:
第二种为short,可用于存储比int类型小的整数,其取值范围为−32768~32767的整数,如下例所示:
最后一种数值变量类型的是long,通常用于存储int 类型无法存储的整数。long 变量可以存储−9.22×1018~9.22×1018的整数。
在Java中处理很大的数值时,很难一目了然地看到具体的数值,如下面的语句所示:
除非你数一下 0 的个数,否则你很难看出它表示的是 264.4 百万美元。Java 7 对此做了改进,在处理很大的数值时,可以在数值中间使用下划线(_),如下所示:
下划线将会忽略掉,因此变量的值没有发生变化,这只是一种让数值更容易阅读的方式。
警告:
如果NetBeans的IDE不能识别Java 7,则Java 7中提供的所有改进(包括数值中的下划线),在源代码编辑器中,都将标识为错误。对IDE进行设置,使其识别 Java 7的方法将在第 7 章介绍。
Java有一种特殊类型的变量叫布尔变量,它只能存储true或false。乍一看,布尔型变量好像没多大用途,除非要编写大量基于计算机的真假测验。然而,编写程序时,很多情况下都需要使用布尔型变量。下面是一些可使用布尔型变量解决的问题。
用户是否按下了某个键?
游戏结束了吗?
银行账户透支了吗?
这些裤子让我看起来更胖了么?
兔子能吃Trix吗?
下面这条语句创建了一个名为gameOver的布尔型变量:
这个变量的初始值为false,这样的语句可在游戏程序中指示游戏还没有结束。然后,当导致游戏结束的事件发生时,将变量gameOver设置为true。
虽然在程序中,布尔型变量的两个可能取值true或false看起来像字符串,但不应将它们用双引号括起。第7章将更详细地介绍布尔型变量。
注意:
布尔数字是用George Boole(1815~1864)的名字命名的。Boole是一名数学家,在成年前靠自学成才。他发明了布尔代数学,这是计算机编程、数字电路和逻辑学的重要组成部分。可以想象,他在孩童时就能够做很好的真假测试。
5.3 给变量命名
在 Java 中,变量名可以以字母、下划线字符(_)、美元符号($)打头。名称的其余部分可以是任何字母或数字。在遵守这些规则的情况下,你可以取任何喜欢的变量名,但应该采用统一变量命名规则。本节将介绍常用的变量命名方法。
在变量名的问题上,Java是区分大小写的,所以变量名在整个程序中必须大小写一致。例如,如果变量gameOver在程序的其他地方写成GameOver,编译程序时使用GameOver的地方将导致错误。
变量名应该描述变量的用途,第一个字母应该小写,如果变量名有多个单词组成,则将其他单词的首字母大写。例如,如果要创建一个整型变量,用于存储游戏中创记录的最高分,可使用下面的语句:
在变量名中不能使用标点符号和空格,因此下面的变量名都是非法的:
如果在程序中使用这些变量名,NetBeans将在源代码编辑器中的相应行处用红色警告图标来显示,表示这是一个错误。
5.4 在变量中存储信息
在Java程序中,可以在创建变量时就给它赋值,也可以以后再给变量赋值。
要在创建变量时就给它赋初值,可以使用等号(=)。下面的例子创建双精度浮点变量pi,且其初始值为3.14:
所有数值型变量都可以用类似的方法赋值。如果创建的是字符或字符串变量,必须像前面介绍的那样用引号将赋给变量的值括起来。
如果两个变量的类型相同,也可以将一个变量的值赋给另一个变量,请看下面的例子:
首先,创建了一个整型变量mileage,并且其初始值为300。接下来,创建了另一个整型变量totalMileage,并将变量mileage的值赋给它。这两个变量的初始值相同,都是300。在接下来的几章中,将介绍如何将一个变量的值转换为另一个变量的类型。
警告:
如果没有给变量赋初始值,则在另外一条语句中使用它之前,必须先赋值。如果没有赋值,则在程序编译时将报错,并显示如下错误消息“变量可能还没有初始化”。
前面已经学到,Java有多个相似的数值变量,来存储不同大小的数值。int 和long 都存储整数,但是long存储的数值范围更大。float和double都存储浮点数值,但是double类型存储的范围更大。
你可以在数值后面追加一个字母来指示数值的类型,如下面的语句所示:
数值3.14后面的F表示这是一个float浮点数值。如果忽略了这个字母,Java会认为3.14是一个双精度浮点数值。字母L表示长精度整数,D表示双精度浮点数值。
Java的另外一种命名约定是,值不变的变量名全部大写。这些变量被称为常量,下面创建了3个常量。
由于常量的值不变,读者可能会问,为何使用常量,只需使用赋给常量的值即可。使用常量的优点之一是,程序更容易理解。
在上面的3个语句中,常量的名字是大写的。尽管这在Java中不是必需的,但是编程人员已经将其作为区分常量和变量的一种标准约定。
5.5 运算符
通过使用+、−、*、/和%等运算符,就可以在语句中使用数学表达式。在Java程序中使用这些运算符,就可以处理数值运算。
在Java中使用+运算符的加法表达式语句如下所示:
上面第2条语句使用+运算符将weight变量的值设置为weight变量的初始值与10的和。使用-运算符的减法表达式如下:
该表达式将weight变量的值设置为weight变量的初始值减去15后的结果。
使用/运算符的除法表达式如下:
该表达式将weight变量的值设置为其初始值除以3后的结果(取整)。
要从除法表达式中找到余数,可以使用%运算符(也称为取模运算符)。下面两条语句可以求得245除以3之后的余数。
乘法表达式使用的是*运算符。下面这条复杂的语句使用了乘法表达式。
表达式 score*12 中,变量 score与 12 相乘。这条完整的语句是将变量 score 与 12 相乘,然后再加500,最后将结果赋给total变量。如果score的值为20,则total变量的最终值是740,也即 500 +(20*12)。
在程序中,常见的任务是将变量的值加1或减1。其中加1的操作称为变量递增,减1的操作称为变量递减。这些任务可以使用相应的运算符来完成。
使用++运算符可以将变量加1,如下面的语句所示:
该语句将存储在x变量中的值进行加1操作。
使用--运算符可以将变量减1,如下所示:
该语句将变量y中的值减1。
也可以将递增运算符和递减运算符放置在变量名的前面,如下面的语句所示。
将运算符放置在变量前面,称之为运算符前置;放到后面,则称之为运算符后置。
注意:
有点困惑?其实,当你回想一下在小学时学到的前缀的概念,就会发现前置与后置的概念很简单。与 sub-或 un-这样放在单词前面的前缀相同,前置运算符是放置在变量名的前面,而后置运算符则是放置在变量名的后面。
在表达式中使用递增、递减运算符时,一定要注意运算符前置和运算符后置的区别,这很重要。
考虑下面的语句:
在这两条语句处理完毕之后,answer变量的值是多少呢?你可能认为应该是40。当然,如果是对3加1,这样等于4,然后再乘以10,这样就是40。
然而,answer 变量实际的值却是 30,因为这里使用的后置运算符,而不是前置运算符。
当表达式中的变量使用了后置运算符时,只有当整个表达式执行完毕之后,变量的值才会发生改变。语句 int answer = x++*10 的执行顺序与下面的两条语句相同。
如果使用的是前置运算符,则顺序相反。也就是说,如果表达式的变量中使用的是前置运算符,则该变量的值会在表达式执行完毕之前就发生改变。
来看下面的语句:
此时answer变量的值将等于40。前置运算符会在表达式执行之前,先将变量x加1。语句 int answer = ++x*10 的执行顺序与下面的语句相同:
读者很容易就会对++运算符和--运算符产生恼怒心理,因为它们不像本书中出现的其他概念那样,容易让人理解。
注意:
第 1 章介绍 C++编程语言的名称时,指出这是一个玩笑的结果,以后读者将明白。知道运算符++,读者就能够明白为什么C++使用两个+而不是一个。也许可笑:由于C++在C语言的基础上增加了很多新特性和功能,因此将其命名为C++。
在阅读本书章后,读者也能够讲这个笑话,且全世界99%的人都不会理解。
在编写Java程序时,也可以不使用递增和递减运算符,通过如下方式来使用+和−运算符,同样也可以实现同样的结果。
递增和递减是很有效的便捷方式,但也会让表达式看起来更长。
当在一个表达式中使用多个运算符时,需要知道计算机处理这些运算符的先后顺序。来看下面的语句:
在计算机处理这些语句时,除非你事先知道其处理的先后顺序,否则将很难确定x变量的值到底是多少。取决于y*3先执行,还是3+5先执行,x的结果可能是35,也可能是80。
在计算表达式时,将会按照如下顺序来执行。
1.先执行递增和递减操作。
2.然后执行乘、除以及取模运算。
3.然后执行加、减操作。
4.然后是“比较”操作。
5.最后使用等号(=)来设置变量的值。
由于乘法运算先于加法运算发生,因此可以反过头来看前面的例子,然后得出答案:y先与3相乘,其结果是30,然后再加5,这样x变量的值最终为35。
“比较”操作将在第 7 章讲解。其他运算顺序已经在本章讲解了,因此现在可以求出下面语句的结果了。
上述语句执行完毕之后,number变量的值是50。
计算机是如何得出这个结果来的呢?计算机首先处理递增运算符,因此 x++表达式将变量x的值设为6。注意,++运算符位于变量x的后面,是后置运算符,也就是说,在计算该表达式时,使用的是变量x的初始值。
由于使用的是变量x在递增之前的初始值,因此表达式如下所示:
现在,计算机开始从左向右处理乘除运算。即5先乘以6,然后是4乘以10,这个结果再除以2,这样表达式成为下面的样子:
该表达式将变量number的值设置为50。
如果想以不同的顺序来对表达式求解,可以使用小括号把表达式的一部分括起来,它们就可以先被处理了。例如,x = 5*3 + 2;在执行完毕时,x 的值是 17,原因就是先执行乘法运算,然后再执行加法运算。然而,如果将该表达式修改为下面的形式:
此时,括号内的表达式将先被执行,这样x的最终结果就是25。读者可以根据需要在语句中使用括号。
5.6 使用表达式
当你小时候在学校遇到令人讨厌的数学题时,是否抱怨过高次乘方,发誓今后再也不使用这样的知识?对不起,这里可能破坏你的誓言,但所有的老师都是正确的——这些数学知识将在计算机编程中得到应用。这真是个坏消息。
但好消息是计算机将帮你做这些数学题。计算机程序中经常使用表达式,可以使用它们完成下面这样的任务:
修改变量的值;
在程序中计数;
在程序中使用数学公式。
编写计算机程序并使用表达式时,你又回到了过去的数学课中。表达式可以使用加、减、乘、除和求模。
要看一看运行中的表达式,回到 NetBeans 并创建一个新的 Java 文件,其类名为PlaneWeight。这个程序可以记录某一个人在进入到太阳系时,其体重的增减。输入程序清单5.2中的所有代码。下面依次讲解该程序的每一部分。
程序清单5.2 PlaneWeight程序
输入完毕后,保存文件。然后通过菜单命令 Run->Run File 来运行该程序。输出结果如图5.1所示。
图5.1 PlaneWeight 程序的输出
和你创建的其他程序一样,PlaneWeight 程序也使用了 main()块语句来进行相应的处理。该语句可以分成下面4部分。
1.第3~5行:将人在地球上的初始体重设置为205。
2.第7~9行:计算人在水星上的体重,其值减少。
3.第11~13行:计算人在月球上的体重,其值减少。
4.第15~17行:计算人在木星上的体重,其值增加。
第4行创建了weight变量,并使用int将其指定为整型变量。该变量的初始值为205,在整个程序中用于监控人的体重。
下一行类似于程序中的其他语句:
命令System.out.println( )显示其括号中包含的字符串。在第3 行,System.out.print( )命令显示文本“Your weight on Earth is”。程序中还有多个System.out.print( )和System.out.println( )语句。
它们之间的区别在于,print( )在显示完文本后,不会自动换行,而println( )则会自动换行。
5.7 总结
学习了变量和表达式后,读者将能够在程序中向计算机发出更多的指令。有了本章学习到的知识,读者可以编写程序,完成众多类似计算器的任务,轻松地处理复杂的数学等式。
数字只是一种可存储到变量中的信息,还可以存储字符、字符串以及特殊值true和false (被称为布尔型变量)。下一章将介绍字符串变量以及如何使用它们。
5.8 问与答
问:在Java程序中,一行和一条语句是一回事吗?
答:不是。虽然本书的程序都将每条语句放在一行内,但旨在让程序更容易理解,并非必须如此。
Java编译器在编译程序时不考虑行、空格或其他格式问题,编译器只要求每条语句以分号结束。下面的这一行代码对Java来说也无问题:
可以在一行中放置多条语句,但这样做让阅读源代码的人难以理解。鉴于这种原因,通常不建议这样做。
问:为什么变量名的首字母要小写,如gameOver?
答:这是一种命令约定,而且对你的编程很有帮助。首先,它可以让变量更容易识别,从而与Java程序中的其他元素区分开来。另外,通过采用统一的变量命名规则,当你在程序的多个地方使用同一个变量时,更容易修复出现的错误。本书使用的命名规则已被大多数Java程序员采用多年。
问:我可以在Java程序中将二进制值赋值给整型变量么?
答:在 Java 7 中可以这样做。在为整型变量赋二进制值时,需要在数值前面添加字符 0b。由于1101是数字13的二进制值,因此下面的语句是将13赋值给整型变量z。
下划线的目的只是为了增加语句的可读性,在编译阶段会被Java编译器忽略。
如果你的项目使用的不是 Java 7,则 NetBeans会把该特性当作错误来对待。第 7 章将会对其详细讲解。
5.9 测验
回答下列问题,以测试对变量、表达式以及本章介绍的其他知识的理解程度。
1.位于左大括号和右大括号之间的一组语句称为什么?
a.块语句。
b.组件(groupware)。
c.用括号括起的语句。
2.布尔型变量用于存储true或false。
a.正确。
b.错误。
c.不,谢谢,我吃过了。
3.变量名不能以哪些字符打头?
a.美元符号($)。
b.双斜线(//)。
c.字母。
1.a.括起来的语句称为块语句或块。
2.a.布尔型变量只能存储true或false。
3.b.变量名可以以字母、美元符号($)或下划线(_)打头。如果变量名以两个斜杠打头,该代码行后面的内容将被忽略,因为双斜杠表示注释行。
5.10 练习
为充分复习本章的主题,请完成下面的练习。
扩展PlaneWeight程序,记录人在金星上的体重(大约是人在地球上的体重的90.7%),以及人在天王星上的体重(大约是地球上的88.9%)。
创建一个简短的Java程序,它使用整型变量x和y,并显示x和y的平方和。
有关为完成这些练习而编写的Java程序,请访问本书的配套网站www.java24hours.com。