目录
一,变量和数据类型
1.1 变量
计算机的内存类似于人的大脑,计算机使用内存来记忆大量运算时要使用的数据。内存是一个物理设备,如何来存储一个数据呢?很简单,把内存想象成一间旅馆,要存储的数据就好比要住宿的客人。试想一下去旅馆住宿的场景。首先,旅馆的服务人员会询问要住什么样的房间,如单人间、双人间、总统套间;然后,根据选择的房间类型,服务员会安排一个合适的房间。"先开房间,后入住"就描述了数据存入内存的过程。首先,根据数据的类型为它在内存中分配一块空间(即找一个合适的房间),然后数据就可以放进这块空间中(即入住)。那么数据为什么对存储空间有要求呢?试想有三个客人,服务员安排了一个单人间,这能入住吗?分配的空间过小会导致数据无法存储。在下面的课程中将详细介绍。
到底使用内存做什么呢?看一看下面的问题,就可一目了然了。
问题:在银行中存储 1000 元钱,银行一年的利息是 5%, 那么一年后存款是多少?
分析:很简单,首先计算机在内存中开辟一块空间用来存储 1000, 然后把存储在内存中的数据1000 取出后进行计算,根据公式:本金×利率+本金(即1000×5%+1000), 获得的结果1050重新存入该存储空间,这就是一年后的存款了。图 2.1 显示了内存中存储数据的变化。可见,数据被存储在内存中,目的是便于在需要时取出来使用,或者如果这个数据被改变了,内存中存储的值也会随之进行相应的更新,以便下次使用新的数值。那么,内存中存储的这个数据到底在哪里,我们怎样获得?
通常,根据内存地址可以找到这块内存空间的位置,也就找到了存储的数据。但是内存地址非常不好记,因此,我们给这块内存空间起一个别名,通过使用别名找到对应空间存储的数据。变量是一个数据存储空间的表示。
通过变量名可以简单快速地找到它存储的数据。将数据指定给变量,就是将数据存储到以别名为变量名的那个房间;调用变量,就是将那个房间中的数据取出来使用。可见,变量是存储数据的一个基本单元,不同的变量相互独立
1.2 数据类型
1.不同的数据类型
计算机的基本作用就是运算。要运算就需要数据,这些数据可以由用户输入、从文件获得,甚至从网络中得到。数据不计其数,但是我们可以把数据归类。例如,根据是整数还是小数,是一串字符还是单个字符来分类。例如,对下面的数据分类。
手机品牌:"三星"、"小米"、"苹果"。
手机价格(单位:元): 4500.34、1200.00、3900.5。
手机电池待机时间(单位:天):2、5、3。
这里,手机品牌都是由一串字符组成的,手机价格都是小数,手机电池待机时间都是整数。当然还会经常碰到别的数据,如手机"开"或"关",这就是一个字符。
2. Java 常用数据类型
如何在程序中表示不同类型的数据呢? Java 中定义了许多数据类型,生活中的数据都能在这里得到匹配。
讲解中提到了 "根据数据的类型为它在内存中分配一块空间",数据的类型是整数、小数还是字符,不同的数据在存储时所需要的空间各不相同。例如,int 型的数值要占四字节,而 double型的数值占八字节。因此,不同类型的数据就需要用不同大小的内存空间来存储。其中,int 、double 、char 都是 Java 定义的关键字。
1.3 变量声明及使用
在程序运行的过程中,将数值通过变量加以存储,以便程序随时使用,整体步骤如下。
(1) 根据数据的类型在内存中分配一个合适的"房间",并给它命名,即"变量名"。
(2) 将数据存储到这个"房间"中。
(3) 从"房间"中取出数据使用,可以通过变量名来获得。
现在,大家一定能够很清楚地想象到一个数据如何被存储到内存中及如何被取出来使用了。如何使用 Java 语言真正实现这一过程呢?
问题:根据 2.1.1 节中描述的问题,在内存中存储本金 1000 元,显示内存中存储的数据的值。
示例1
package cn.dbit.demo;
public class MyVariable {
public static void main(String[] args) {
int money = 1000; //存储本息
System.out.println(money); //显示存储的数据的值
}
}
示例 1 展示了存储数据和使用数据的过程,输出结果如下。
1000
关键代码虽只有两行,但展示了如何定义和使用变量,任何复杂的程序都由此构成。下面对其进行分析。
(1) 声明变量,即"根据数据类型在内存中申请一块空间",这里需要给变量命名。
语法
数据类型 变量名;
其中,数据类型可以是 Java 定义的任意一种数据类型。例如,要存储 Java 考试最高分 98.5 、获得最高分的学生姓名 "张三" 及性别 ’男’。
double score; //声明双精度浮点型变量score存储分数
String name; //声明字符串型变量name存储学生姓名
char sex; //声明字符型变量sex存储性别
(2) 给变量赋值,即"将数据存储至对应的内存空间"。
score = 98.5; //存储98.5
name = "张三"; //存储”张三”
sex = '男'; //存储 1 男'
这样的分解步骤有些烦琐,也可以将步骤 (1) 和步骤 (2) 合二为一,如示例 1 所示,在声明一个变量的同时给变量赋值。
语法
数据类型 变量名 = 值;
例如:
double score = 98.5;
String name = "张三";
char sex = '男';
(3) 调用变量。使用存储的变量, 我们称之为 "调用变量"。
System.out.println(score); //从控制台输出变量score存储的值
System.out.println(name); //从控制台输出变量name存储的值
System.out.println(sex); //从控制台输出变量sex存储的值
可见,使用声明的变量名就是使用变量对应的内存空间中存储的数据。
另外,需要注意的是,尽管可以选用任意一种自己喜欢的方式进行变量声明和赋值,但是要记住 "变量都必须声明和赋值后才能使用"。因此要想使用一个变量,变量的声明和赋值必不可少。
1.4 变量命名规则
旅馆可以随心所欲地给房间命名,可以是数字"1001",也可以是一些有趣的名称,如"美国总统"、"英国女王"、"埃塞俄比亚王妃"等。但是在给变量命名时,就要受到一些约束
另外,Java变量名的长度没有任何限制,但是Java语言区分大小写,所以price和Price是两个完全不同的变量
注意:Java关键字是Java中定义的、有特别意义的标识符,如public、int、class、boolean、void、char、double、package、static等。随着学习的深入,会接触越来越多的Java关键字。Java关键字不能用做变量名、类名、包名等。
规范:变量名要简短且能清楚地表明变量的作用,可以由一个或多个单词组合而成,通常第一个单词的首字母小写,其后单词的首字母大写。例如:
int ageOfStudent; //学生年龄
int ageOfTeacher; //老师年龄
经验:为了日后更容易维护程序,变量的名称要让人一眼就能看出这个变量的作用。例如,ageOfStudent代表学生的年龄,ageOfTeacher代表老师的年龄。但是在初学时,很多人喜欢使用一些简单的字母来作为变量名称,如a、b、c等。这样尽管正确,但是以后会发现,如果有100个变量,在使用时就会分不清某个变量代表什么意思。所以要尽量使用有意义的变量名,且最好使用简短的英文单词。
1.5 常见错误
尽管同学们可能很细心,或者很自信已经掌握了刚刚学到的所有知识,但当进行实战时,所编写的代码还是会不可避免地被编译器提示出错。下面列举一些初学者常犯的错误。
1.变量未赋值先使用
在前面的讲解中一再强调"变量要先声明后使用",那么如果程序使用了未被赋值的变量会怎样呢?
常见错误1
public class Error1 {
/*
* 常见错误
*/
public static void main(String[] args) {
String title; //声明变量title存储课程名
System.out.println(title); //从控制台输出变量的值
}
}
编译运行代码,编译器会提示编译错误,如图2.2所示。
排错方法:按照所学的内容,使用前要给变量赋值。
2. 使用非法的变量名
变量在命名时如果不符合规则,Java编译器同样无法正常编译。
常见错误2
public class Error2 {
/*
* 常见错误
*/
public static void main(String[] args) {
int %hour = 18; //声明变量hour存储学时
System.out.println(%hour); //从控制台输出变量的值
}
}
将代码编译运行,IDEA提示编译错误,如图2.3所示。
图2.3使用非法变量名的错误提示页面
排错方法:按照变量的命名规则,修改不合法的变量名。
3. 变量不能重名
常见错误 3
public class Error3 {
/*
* 常见错误
*/
public static void main(String[] args) {
String name = "张三"; //声明变量存储“张三”
String name = "李四"; //声明变量存储“李四”
}
将代码编译运行,IDEA提示图2.4所示的错误。
图 2.4 变量重名的错误提示页面
排错方法:使用两个不同的变量名来存储。
二,运算符
2.1 赋值运算符
在前面章节的学习中,使用最多的是什么呢?那就是 "="。例如:
int before = 20; //存储本金
使用将数值1000放入变量money的存储空间中,称为赋值运算符。例如:
double weight = 177.5;
int weight = 78;
问题 学员王浩的Java成绩是80分,学员张萌的Java成绩与王浩的相同,输出张萌的成绩。
示例 2
public class OperatorDemo {
public static void main(String [] args) {
int wangScore = 80; //王浩成绩
int zhangScore; //张萌成绩
zhangScore = wangScore;
System.out.println("张萌的成绩是: " + zhangScore );
}
由示例2可知,可以将某个数值赋给变量,或是将某个表达式的值赋给变量。表达式就是符号(如加号、减号)与操作数(如b、3等)的组合。例如:
int zhangScore;
int a = (b + 3) * (b - 1);
最后一个语句将变量b的值取出后进行计算,然后将计算结果存储到变量a中。如果写成“(b + 3) * (b - 1) =a”,则会出错。切记,”=” 的功能是将等号右边表达式的结果赋给等号左边的变量。
2.2 算术运算符
我们小时候就开始学习如何进行算术运算了。最简单的算术运算是加、减、乘、除。那么,如何编写程序让计算机来完成算术运算呢? Java中提供运算功能的就是算术运算符,它主要使用数值操作数进行数学计算。表2-4展示了常用的算术运算符
下面就使用Java提供的算术运算符来解决一个简单的问题。
问题:从控制台输入学员王浩的三门课程 ( STB、Java、SQL)的成绩,编写程序实现:Java课程和SQL课程的分数之差;三门课程的平均分。
分析:先声明变量来存储数据,数据来源于用户从控制台中输入的信息;然后进行计算并输出结果。
package cn.dbit.demo;
import java.util.Scanner;
public class ScoreStat {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("STB的成绩是:");
int stb = input.nextInt();
System.out.print("Java的成绩是:");
int java = input.nextInt();
System.out.print("SQL的成绩是:");
int sql = input.nextInt();
int diffen;
double avg;
System.out.println("-------------------------------------");
System.out.println("STB\tJava\tSQL");
System.out.println(stb + "\t" + java + "\t" + sql);
System.out.println("-------------------------------------");
diffen = java - sql;
System.out.println("Java和SQL的成绩差:" + diffen);
avg = (stb + java + sql) / 3;
System.out.println("3门课的平均分是:" + avg);
}
}
程序运行结果如图2.5所示。
图2.5示例3的运行结果
示例3与前面章节不同的是,可以从控制台输入数据,然后把它存储在已经定义好的变量中,而不是直接在程序中给变量进行赋值。这种交互是通过两行简单的代码实现的。
Scanner input = new Scanner(System.in);
int stb = input.nextInt();
这两行代码的作用就是通过键盘的输入得到STB的成绩。这是Java所提供的从控制台获取键盘输入的功能,就像System.out.println("")可以向控制台输出信息一样。这里,获取的是一个整型变量,因此调用nextInt()方法。如果获取的是字符串,则需要调用next()方法。需要注意的是要使用这个功能,必须在Java源代码的第一行写上如下语句。
import java.util.Scanner;
或者
import java.util.*;
后面的章节会做进一步解释。这里,大家只需要记住它的写法即可。
另外,算术运算符的使用基本上和平时进行的加减乘除运算一样,也遵守 "先乘除后加减,必要时加上括号表示运算的先后顺序" 的原则。要特别注意的是,在使用 "/" 运算符进行运算时,一定要分清哪一部分是被除数,必要时应加上括号。例如:
System.out.println(2+4+6/2);
以上代码计算的是2+4+(6/2),而不是(2+4+6)/2。
另外,还有两个非常特殊且有用的运算符:自加运算符 "++" 和自减运算符"--"。它们不像别的算术运算符那样,运算时需要两个操作数,如 "5+3","++" 和运算符只需要一个操作数。例如:
int num1 = 3;
int num2 = 2;
num1++;
num2--;
这里,"num1++" 等价于 "numl =num1+1" , "num2—" 等价于"num2=num2-1"。因此,经过运算,numl的结果是4, num2的结果是1。为什么要写成这样?现在也许只觉得它是写起来简单一点,但在以后的学习中,大家会慢慢发现它的优点
2.3 数据类型转换
1.为什么需要数据类型转换
实际中可能会遇到下面的问题。
问题:某班第一次考试平均分是81.29,第二次比第一次增加了 2分,第二次的平均分是多少?
分析:有时会遇到这样的情况:必须将一个int数据类型的变量与一个double数据类型的变量相加。那么,不同的数据类型能进行运算吗?运算的结果又是什么数据类型呢?
下面就分别回答这些问题。
2.如何进行数据类型转换
1)自动数据类型转换
要解决不同类型之间的数据计算问题,就必须进行数据类型转换。示例4用来解决刚才的问题。
示例4
代码:
package cn.dbit.demo;
public class AutoTypeChange {
public static void main(String[] args) {
double fisrtAvg = 81.29;
double secondAvg;
int rise = 2;
secondAvg = fisrtAvg + rise;
System.out.println("第二次平均分是:" + secondAvg);
}
}
解析:
package cn.dbit.demo;
public class AutoTypeChange {
public static void main(String[] args) {
double fisrtAvg = 81.29; //第一次考试的平均分
double secondAvg; //第二次考试的平均分
int rise = 2; //增长的分数
secondAvg = fisrtAvg + rise; //自动类型转换
System.out.println("第二次平均分是:" + secondAvg); /*显示第二次考试平均分*/
}
}
程序运行结果如图2.6所示。
图2.6示例4的运行结果
从代码中可以看出,double型变量firstAvg和int型变量rise相加后,计算的结果赋给一个double型变量secondAvg.这时就发生了自动类型转换。
规则1 :如果一个操作数为double类型,则整个表达式可提升为double 类型。
首先,Java具有应用于一个表达式的提升规则,表达式(firstAvg + rise)中操作数firstAvg是double类型,则整个表达式的结果为double类型。这时,int类型变量「ise隐式地自动转换成double类型,然后它和double类型变量firstAvg相加,最后结果为double类型并赋给变量secondAvg。那么为什么int类型变量可以自动转换成double类型变量呢?这也是因为Java语言的一些规则造成的。将一种类型的变量赋给另一种类型的变量时,就会发生自动类型转换。
例如:
int socre = 80;
double newScore = score;
这里,int类型变量score隐式地自动转换为double类型变量。但是,这种转换并不是永远无条件发生的。
规则2:满足自动类型转换的条件。
两种类型要兼容:数值类型(整型和浮点型)互相兼容。
目标类型大于源类型:double类型可以存放int类型数据,因为为double类型变量分配的空间宽度足够存储int类型变量。因此,我们也把int类型变量转换成double类型变量称为 "放大转换"。
2)强制数据类型转换
事实上,自动类型转换并非所有情况下都有效。如果不满足上述条件,当必须将double类型变量的值赋给一个int类型变量时,该如何进行转换呢?这时系统就不会完成自动类型转换了。
问题:去年Apple笔记本所占的市场份额是20%,今年增长的市场份额是9.8%,求今年所占的份额?
分析:不难发现计算的方法并不难,原有市场份额加上增长的市场份额便是现在所占的市场份额。因此,可以声明一个int类型变量before来存储去年的市场份额,一个double类型变量rise来存储增长的部分。但是如果直接将这两个变量的值相加,然后将计算结果直接赋给一个int类型变量now会提示出现问题吗?尝试后会发现IDEA会提示 “类型不匹配” 的错误信息。
示例5
代码:
package cn.dbit.demo;
public class TypeChange {
public static void main(String[] args) {
int before = 20;
double rise = 9.8;
int now = before + (int)rise;
System.out.println("新的市场份额是:" + now);
}
}
分析:
package cn.dbit.demo;
public class TypeChange {
public static void main(String[] args) {
int before = 20; //Apple 笔记本市场份额
double rise = 9.8; //增长的份额
//计算新的市场份额 (double 类型变量强制转化成 int 类型变量)
int now = before + (int)rise; //现在的份额
System.out.println("新的市场份额是:" + now);
}
}
示例5给出了解决方案,示例5的运行结果如下。
新的市场份额是: 29
根据类型提升规则,表达式(before + rise)的值应该是double类型,但是最后的结果却要转变成int类型,赋给int类型变量now。由于不能进行放大转换,因此必须进行显式地强制类型转换。
语法:
(数据类型)表达式
在变量前加上括号,括号中的类型就是要强制转换成的类型。例如:
double d = 34.5634;
int b = (int)d;
运行后b的值如下:
34
从示例中可以看出.,由于强制类型转换往往是从宽度大的类型转换成宽度小的类型,使数值损失了精度(如2.3变成了 2,34.5634变成了 34),因此可以形象地称这种转换为 "缩小转换"。
小结:数据类型转换的形式分为自动数据类型转换和强制数据类型转换两种。
2.4 boolean 类型
前面已经学习了一些数据类型,有表示数字的,有表示字符的,……。但是事物往往还有真假之分,如在判断一件艺术品的时候常说:"这是真的" 或 "这是假的"。另外,也会经常做一些这样的判断,如 "地铁2号线的首发车时间是5:00吗?"、"这次考试成绩在90分之上吗?"、"健身俱乐部的年费低于1000元吗?"等,这些问题都需要经过判断。但答案只能有两个,要么"是"(即真)要么"否"(即假)。程序也一样,有时也需要判断真假。这时就需要一种数据类型,专门用来表示真和假。Java中使用boolean类型表示真假。"boolean" 又称 "布尔",所以我们常说 "布尔类型"。boolean是Java的关键字,所有字母为小写。
表示真假可以用boolean类型,那么怎么表示呢?其实boolean类型有两个值,而且只有这两个值。boolean类型的值如下表所示。
2.5 关系运算符
现在知道了程序用boolean数据类型表示真和假,但是程序如何知道真假呢?程序可以通过比较大小、长短、多少等得知其真假。Java提供了一种可以比较大小、长短、多少等的运算符,这就是关系运算符。下表列出了 Java语言中提供的关系运算符。
从上表可以看出,关系运算符是用来做比较运算的,而比较的结果是一个boolean类型的值,要么是真(true),要么是假 (false)。
问题:从控制台输入张三同学的成绩,与李四的成绩( 80分)进行比较,然后输出“张三成绩比李四的成绩高吗? ”这句话的判断结果。
分析:程序要实现的功能可以分为以下两部分。
(1) 实现从键盘获取数据。
(2) 比较数据,并输出比较结果。
示例6
代码:
package cn.dbit.demo;
import java.util.Scanner;
public class BoolTest {
public static void main(String[] args) {
int liSi = 80;
boolean isBig;
Scanner input = new Scanner(System.in);
System.out.print("输入学员张三成绩:");
int zhangSan = input.nextInt();
isBig = zhangSan > liSi;
System.out.println("张三成绩比李四高吗?" + isBig);
}
}
分析:
package cn.dbit.demo;
import java.util.Scanner;
public class BoolTest {
public static void main(String[] args) {
int liSi = 80; //学员李四的成绩
boolean isBig; //声明一个 boolean 类型的变量
Scanner input = new Scanner(System.in); //Java 输入的一种方法
System.out.print("输入学员张三成绩:"); //提示要输入学员张三的成绩
int zhangSan = input.nextInt(); //输入张三的成绩
isBig = zhangSan > liSi; //将比较结果保存在 boolean 变量中
System.out.println("张三成绩比李四高吗?" + isBig); //输出比较结果
}
}
程序运行结果如图2.7所示。
图2.7示例6的运行结果
由示例6可见,和所有其他数据类型一样,在使用boolean类型之前,也需要先进行声明和赋值,如下所示。
boolean isBig;
isBig = zhangSan > liSi;
比较结果是一个boolean类型的值,结果为"假",因此示例6的输出结果为false。
注意:”=” 和 “==” 的区别。
(1) “=” 是赋值运算符,即把右边的值赋给 “=” 左边的变量,如int num = 20。
(2) “==” 是比较运算符,即 “左边的值与 “==” 右边的值比较,看它们是否相等,如果相等则为true, 否则为false,如3==4的结果为false。
小结:
(1)到现在为止,已经学过的数据类型和运算符有哪些?自己在纸上写一下,记不起来时可以翻看前面的内容,这些数据类型和运算符在后面的学习中会经常用到。
(2)运算符的优先级:算术运算符>关系运算符>逻辑运算符,即在一个表达式中,算术运算符的优先级最高,关系运算符次之,然后是逻辑运算符。逻辑运算符将在下一章进行学习。如果在一个表达式中包含赋值运算符,则它的优先级最低。当运算符比较多时,可以使用小括号改变某个运算符的执行顺序