数据类型
标识符
【1】标识符:读音 biao zhi fu
【2】什么是标识符?
包,类,变量,方法.....等等,只要是起名字的地方,那个名字就是标识符
【3】标识符定义规则:
1.四个可以(组成部分):数字,字母,下划线_,美元符号$
注意:字母概念比较宽泛,指的是英文字母,汉字,日语,俄语......
但是我们一般起名字尽量使用英文字母
2.两个不可以:不可以以数字开头,不可以使用java中的关键字
3.见名知意:增加可读性
4.大小写敏感: int a ; int A;
5.遵照驼峰命名:
类名:首字母大写,其余遵循驼峰命名
方法名,变量名:首字母小写,其余遵循驼峰命名
包名:全部小写,不遵循驼峰命名
6.长度无限制,但是不建议太长 asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasfd
关键字
关键字:被JAVA语言赋予了特殊含义,用作专门用途的单词
特点:JAVA中所有关键字都为小写
官网:https://docs.oracle.com/javase/tutorial/java/nutsandbolts/_keywords.html
变量和常量
常量:
常量分为两种:
常量通常指的是一个固定的值,例如:1、2、3、’a’、’b’、true、false、”helloWorld”等。
在Java语言中,主要是利用关键字final来定义一个常量。 常量一旦被初始化后不能再更改其值。
为了更好的区分和表述,一般将1、2、3、’a’、’b’、true、false、”helloWorld”等称为字面常量,而使用final修饰的PI等称为符号常量(字符常量)。
字面常量的类型:
注意:逻辑常量就两个值,一个是true,一个是false
变量:
变量本质上就是代表一个”可操作的存储空间”,空间位置是确定的,但是里面放置什么值不确定。我们可通过变量名来访问“对应的存储空间”,从而操纵这个“存储空间”存储的值。Java是一种强类型语言,每个变量都必须声明其数据类型。变量的数据类型决定了变量占据存储空间的大小。 比如,int a=3; 表示a变量的空间大小为4个字节。变量作为程序中最基本的存储单元,其要素包括变量名,变量类型和作用域。变量在使用前必须对其声明, 只有在变量声明以后,才能为其分配相应长度的存储空间。
【1】变量声明格式:
type varName [=value][,varName[=value]...]; //[ ]中的内容为可选项,即可有可无
数据类型 变量名 [=初始值] [,变量名 [=初始值]…];
案例:
int age = 19 , age2 = 90 ;
int age,age2;
【2】变量的声明:
(1)如果你只定义一个变量,没有给变量进行赋值的话,那么其实这个变量相当于没有定义:
(2)变量如果没有进行赋值的话,那么使用的时候会出错,告诉你:尚未初始化变量:
【3】变量的赋值:
我们自己定义的时候直接就可以用一句话定义:
int age = 10;
public class TestVar01{
public static void main(String[] args){
//变量的声明(定义变量)(以年龄为案例讲解)
//java是一个强类型的语言,只要声明变量就必须定义类型:定义整数类型
int age ; //定义一个整数类型的变量,变量名字为age
//对变量进行赋值操作:
age = 10; //变量名字为age,具体的值为10
age = 12;
age = 20;
age = age + 4;
age = 9;
age = 9;
System.out.println(age);
}
}
变量不可以重复定义
【4】变量的使用:
public class TestVar01{
public static void main(String[] args){
//变量的声明(定义变量)(以年龄为案例讲解)
//java是一个强类型的语言,只要声明变量就必须定义类型:定义整数类型
int age ; //定义一个整数类型的变量,变量名字为age
//对变量进行赋值操作:
age = 10; //变量名字为age,具体的值为10
age = 12;
age = 20;
age = age + 4;
age = 9;
age = 9;
System.out.println(age);
System.out.println(age-2);
System.out.println(age+10);
int num = age + 66;
System.out.println(num);
}
}
扩展:
public class TestVar02{
public static void main(String[] args){
int a = 10;
int b = 20;
int c = a + b ;
}
}
现在对上述代码进行“反编译过程”“反汇编过程”
【5】变量的内存:
【6】习题:
public class TestVar03{
public static void main(String[] args){
int num1 = 10;
int num2 = 20;
num1 = num2;
num2 = num2 + 10;
num1 = num2 - 10;
num2 = num1;
System.out.println("num1="+num1);
System.out.println("num2="+num2);
}
}
内存分析:
结果:
【7】变量的作用域:
作用域指的就是作用范围,变量在什么范围中有效
作用范围就是离它最近的{}
备注:一会我们写的代码,不要去运行,会出错
/*
局部变量:定义在方法中
成员变量:定义在类中,方法外
*/
public class TestVar04{
int b = 20;
public static void main(String[] args){
System.out.println(a);//no
int a = 10;
System.out.println(a);//yes
System.out.println(b);//yes
{
int c = 40;
System.out.println(c);//yes
int a = 50;//属于变量的重复定义
}
System.out.println(c);//no
}
public void eat(){
System.out.println(b);//yes
System.out.println(a);//no
int a = 30;//不是变量的重复定义
System.out.println(a);//yes
}
}
基本数据类型
Java是一种强类型语言,每个变量都必须声明其数据类型。
Java的数据类型可分为两大类:基本数据类型(primitive data type)和引用数据类型(reference data type)。
PS:巧妙记忆:除了基本数据类型以外的所有类型都属于引用数据类型,本章重点:基本数据类型
1.整数类型
基本数据类型常量
十进制整数,如:99, -500, 0
八进制整数,要求以 0 开头,如:015
十六进制数,要求 0x 或 0X 开头,如:0x15
二进制:要求0b或者0B开头,如:0b11
几进制:就是逢几进1的问题:
平时实际生活中用的最多的是:十进制
计算机用二进制最多
【1】二进制转换为十进制:
二进制: 1101
12^3 + 12^2 + 02^1 + 12^0
= 8 + 4 + 0 + 1
= 13
【2】十进制转换为二进制:
十进制 13
【3】八进制转换十进制:
八进制: 16
18^1 + 68^0
= 8 + 6
=14
【4】十进制转换为八进制:
十进制14:
【5】八进制转换为十六进制:
把十进制当做一个中转站:
八进制---》十进制---》十六进制
实际上根本不用自己转换这么麻烦:我们可以直接用系统中提供给我们的计算器:
整型数据类型:
比如:byte的右侧表数范围127怎么算出来的?
byte: 1字节 = 8位
二进制:01111111
12^6 + 12^5 + 12^4 + 12^3 + 12^2 + 12^1 + 1*2^0
= 64 + 32 + 16 +8 +4 + 2 +1
= 127
public class TestVar05{
public static void main(String[] args){
//定义整数类型的变量:
//给变量赋值的时候,值可以为不同进制的:
int num1 = 12 ;//默认情况下赋值就是十进制的情况
System.out.println(num1);
int num2 = 012;//前面加上0,这个值就是八进制的
System.out.println(num2);
int num3 = 0x12;//前面加上0x或者0X,这个值就是十六进制的
System.out.println(num3);
int num4 = 0b10;//前面加上0b或者0B,这个值就是二进制的
System.out.println(num4);
//定义byte类型的变量:
byte b = 126;//定义了一个byte类型的变量,名字叫b,赋值为12
System.out.println(b);
//注意:超范围的赋值会报错。
short s = 30000;
System.out.println(s);
int i = 1234;
System.out.println(i);
//整数类型默认就是int类型的,所以12345678910是一个int类型的数,对于int类型来说,它超出范围了
//要想把一个数给long类型变量,那么后面加上L(推荐)或者l就可以了
long num5 = 12345678910L;
System.out.println(num5);
//注意:只有这个数超出int类型的范围了后面才需要加上L,否则无需加L也可以赋值给long类型:
long num6 = 12;
System.out.println(num6);
}
}
2.浮点类型
浮点类型常量
(1)十进制数形式,例如:
3.14 314.0 0.314
(2)科学记数法形式,如
314e2 314E2 (E的大小写没有区分) 314E-2
double f = 314e2; //31410^2-->31400.0
double f2 = 314e-2; //31410^(-2)-->3.14
浮点类型变量
float类型又被称作单精度类型,尾数可以精确到7位有效数字,在很多情况下,float类型的精度很难满足需求。
而double表示这种类型的数值精度约是float类型的两倍,又被称作双精度类型,绝大部分应用程序都采用double类型。
float类型的数值有一个后缀F或者f ,没有后缀F/f的浮点数值默认为double类型。
也可以在浮点数值后添加后缀D或者d, 以明确其为double类型。
PS:有效数字指的是从左开始第一个不为0的数到最后一个数
代码:
public class TestVar06{
public static void main(String[] args){
//浮点类型的常量有两种形式:
//十进制形式:
double num1 = 3.14;
System.out.println(num1);
//科学计数法形式:
double num2 = 314E-2;
System.out.println(num2);
//浮点类型的变量:
//注意:浮点型默认是double类型的,要想将一个double类型的数赋给float类型,必须后面加上F或者f
float f1 = 3.14234567898623F;
System.out.println(f1);
//注意:double类型后面可以加D或者d,但是一般我们都省略不写
double d1 = 3.14234567898623D;
System.out.println(d1);
//注意:我们最好不要进行浮点类型的比较:
float f2 = 0.3F;
double d2 = 0.3;
System.out.println(f2==d2);
/*
区别:
= 赋值运算: 将等号右侧的值赋给等号左侧
== 判断==左右两侧的值是否相等 :结果要么相等 要么不相等
==运算符的结果就是要么是true,要么是false
*/
}
}
3.字符类型
(1)编码和字符集
【1】什么是编码?
【2】通过生活案例:
【3】由权威机构形成的编码表才可以称之为:字符集
ASCII
英文字符集
用一个字节的7位表示
IOS8859-1
西欧字符集
用一个字节的8位表示
GB2312
简体中文字符集
最多使用两个字节编码
PS:中文:2个字节
GB2312兼容了ASCII中的字符:
GBK
GB2312的升级,加入了繁体字
最多使用两个字节编码
疑问:
首位如果是0:一个字节代码代表一个字符
首位如果是1:那么一个字节不够,要加上后面的字节才能完整的表示一个字符。
Unicode
国际通用字符集,融合了目前人类使用的所有字符。为每个字符分配唯一的字符码。
退出了UTF标准:
三种编码方案: UTF-8,UTF-16,UTF-32
以UTF-8为案例讲解:
中文: 珊 ---》Unicode : 29642
以后我们用的最多的就是UTF-8.
(2)布尔类型:
boolean类型有两个常量值,true和false,在内存中占一位(不是一个字节),不可以使用 0 或非 0 的整数替代 true 和 false ,这点和C语言不同。 boolean 类型用来判断逻辑条件,一般用于程序流程控制 。
public class TestVar09{
public static void main(String[] args){
//创建一个布尔类型的变量:
boolean flag1 = true;
System.out.println(flag1);
boolean flag2 = false;
System.out.println(flag2);
boolean flag3 = 5==9;
System.out.println(flag3);
boolean flag4 = 5<9;
System.out.println(flag4);
}
}
(3)基本数据类型的转换:
【1】什么是类型转换:
在赋值运算或者算数运算的时候,要求数据类型一致,就要进行类型的转换。
【2】类型转换的种类:
自动转换,强制转换
public class TestVar10{ public static void main(String[] args){ //类型转换的两种形式: double d = 6;//int-->double 自动类型转换 System.out.println(d); int i = (int)6.5;//double--->int 强制类型转换 (强转) System.out.println(i); //在同一个表达式中,有多个数据类型的时候,应该如何处理: //多种数据类型参与运算的时候,整数类型,浮点类型,字符类型都可以参与运算,唯独布尔类型不可以参与运算。 //double d2 = 12+1294L+8.5F+3.81+'a'+true; double d2 = 12+1294L+8.5F+3.81+'a'; System.out.println(d2); /* 类型级别:(从低到高的) byte,short,char-->int--->long--->float--->double 级别用来做什么?当一个表达式中有多种数据类型的时候,要找出当前表达式中级别最高的那个类型,然后 其余的类型都转换为当前表达式中级别最高的类型进行计算。 double d2 = 12+1294L+8.5F+3.81+'a'; = 12.0+1294.0+8.5+3.81+97.0 */ int i2 = (int)(12+1294L+8.5F+3.81+'a'); System.out.println(i2); /* 在进行运算的时候: 左=右 : 直接赋值 左<右 :强转 左>右 :直接自动转换 */ //以下情况属于特殊情形:对于byte,short,char类型来说,只要在他们的表数范围中,赋值的时候就不需要进行 //强转了直接赋值即可。 byte b = 12; System.out.println(b); byte b2 = (byte)270; System.out.println(b2); }}
(4)练习:final,字符常量,Scanner的使用:
import java.util.Scanner;//形象理解:在java.util下将Scanner拿过来用public class TestVar11{ public static void main(String[] args){ //实现功能:求圆的周长和面积 //【1】提取变量:提取变量,就是为了一劳永逸,以后只要改变变量的值,下面只要用到这个变量的地方,取值也都发生变化了 //【2】一个变量被final修饰,这个变量就变成了一个常量,这个常量的值就不可变了 // 这个常量就是我们所说的 字符常量 ---》pi // 约定俗成的规定:字符常量的名字全部大写 //【3】使用扫描器:Scanner的使用--》注意通过形象的理解去使用 final double PI = 3.14; //拿来一个扫描器: Scanner sc = new Scanner(System.in); //给一个友好性的提示: System.out.print("请录入一个半径:"); //让扫描器扫描键盘录入的int类型的数据: int r = sc.nextInt(); //求周长: double c = 2*PI*r; System.out.println("周长为:"+c); //求面积: //PI = 9.29;报错:TestVar11.java:12: 错误: 无法为最终变量pi分配值 double s = PI*r*r; System.out.println("面积为:"+s); }}
(5)练习:加深对Scanner的使用:
import java.util.Scanner;public class TestVar12{ public static void main(String[] args){ //键盘录入学生的信息:年龄,身高,姓名,性别: //键盘录入年龄:(接收int类型数据) Scanner sc = new Scanner(System.in); System.out.print("请录入年龄:"); int age = sc.nextInt(); //键盘录入身高:(接收double类型数据) System.out.print("请录入身高:"); double height = sc.nextDouble(); //键盘录入姓名:(接收String类型数据--》字符串) System.out.print("请录入姓名:"); String name = sc.next(); //键盘录入性别:(接受char类型) System.out.print("请录入性别:"); String sexStr = sc.next(); char sex = sexStr.charAt(0); //上面两句可以合为一句表示:char sex = sc.next().charAt(0); System.out.println("该学生的信息为:姓名是:"+name+",年龄是:"+age+",身高为:"+height+",性别是:"+sex); }}
运算符
【1】Java 语言支持如下运算符:
算术运算符
+,-,*,/,%,++(自增),--(自减)
赋值运算符
扩展赋值运算符
+=,-=,*=,/=
关系运算符
>,<,>=,<=,==,!=
逻辑运算符
&,|, &&,||,!,^
位运算符
&,|,^,~ , >>,<<,>>> (了解!!!)
条件运算符
?:
1 算术运算符
1.1 运算符和表达式(了解)
运算符:对常量或者变量进行操作的符号
表达式:用运算符把常量或者变量连接起来符合java语法的式子就可以称为表达式。
不同运算符连接的表达式体现的是不同类型的表达式。
举例说明:
int a = 10;int b = 20;int c = a + b;
+:是运算符,并且是算术运算符。
a + b:是表达式,由于+是算术运算符,所以这个表达式叫算术表达式。
1.2 算术运算符(应用)
符号 作用 说明+ 加 参看小学一年级- 减 参看小学一年级* 乘 参看小学二年级,与“×”相同/ 除 参看小学二年级,与“÷”相同% 取余 获取的是两个数据做除法的余数
注意:
\1. /和%的区别:两个数据做除法,/取结果的商,%取结果的余数。
\2. 整数操作只能得到整数,要想得到小数,必须有浮点数参与运算。
int a = 10;int b = 3;System.out.println(a / b); // 输出结果3System.out.println(a % b); // 输出结果1
1.3 字符的“+”操作(理解)
char类型参与算术运算,使用的是计算机底层对应的十进制数值。需要我们记住三个字符对应的数值:
'a' -- 97 a-z是连续的,所以'b'对应的数值是98,'c'是99,依次递加'A' -- 65 A-Z是连续的,所以'B'对应的数值是66,'C'是67,依次递加'0' -- 48 0-9是连续的,所以'1'对应的数值是49,'2'是50,依次递加
// 可以通过使用字符与整数做算术运算,得出字符对应的数值是多少char ch1 = 'a';System.out.println(ch1 + 1); // 输出98,97 + 1 = 98char ch2 = 'A';System.out.println(ch2 + 1); // 输出66,65 + 1 = 66char ch3 = '0';System.out.println(ch3 + 1); // 输出49,48 + 1 = 49
算术表达式中包含不同的基本数据类型的值的时候,整个算术表达式的类型会自动进行提升。
提升规则:
byte类型,short类型和char类型将被提升到int类型,不管是否有其他类型参与运算。
整个表达式的类型自动提升到与表达式中最高等级的操作数相同的类型
等级顺序:byte,short,char --> int --> long --> float --> double
例如:
byte b1 = 10;byte b2 = 20;// byte b3 = b1 + b2; // 该行报错,因为byte类型参与算术运算会自动提示为int,int赋值给byte可能损失精度int i3 = b1 + b2; // 应该使用int接收byte b3 = (byte) (b1 + b2); // 或者将结果强制转换为byte类型-------------------------------int num1 = 10;double num2 = 20.0;double num3 = num1 + num2; // 使用double接收,因为num1会自动提升为double类型
1.4 字符串的“+”操作(理解)
当“+”操作中出现字符串时,这个”+”是字符串连接符,而不是算术运算。
System.out.println("itheima"+ 666); // 输出:itheima666
在”+”操作中,如果出现了字符串,就是连接运算符,否则就是算术运算。当连续进行“+”操作时,从左到右逐个执
行。
System.out.println(1 + 99 + "年黑马"); // 输出:100年黑马System.out.println(1 + 2 + "itheima" + 3 + 4); // 输出:3itheima34// 可以使用小括号改变运算的优先级System.out.println(1 + 2 + "itheima" + (3 + 4)); // 输出:3itheima7
1.5 数值拆分(应用)
需求:
键盘录入一个三位数,将其拆分为个位,十位,百位,打印在控制台
示例代码:
import java.util.Scanner;public class Test {public static void main(String[] args) {// 1:使用Scanner键盘录入一个三位数Scanner sc = new Scanner(System.in);System.out.println("请输入一个三位数");int num = sc.nextInt();// 2:个位的计算:数值 % 10int ge = num % 10;// 3:十位的计算:数值 / 10 % 10int shi = num / 10 % 10;// 4:百位的计算:数值 / 100int bai = num / 100;// 5:将个位, 十位, 百位拼接上正确的字符串, 打印即可System.out.println("整数"+num+"个位为:" + ge);System.out.println("整数"+num+"十位为:" + shi);System.out.println("整数"+num+"百位为:" + bai);}
2 自增自减运算符(理解)
符号 作用 说明++ 自增 变量的值加1-- 自减 变量的值减1
注意事项:
++和-- 既可以放在变量的后边,也可以放在变量的前边。
单独使用的时候, ++和-- 无论是放在变量的前边还是后边,结果是一样的。
参与操作的时候,如果放在变量的后边,先拿变量参与操作,后拿变量做++或者--。
参与操作的时候,如果放在变量的前边,先拿变量做++或者--,后拿变量参与操作。
最常见的用法:单独使用。
int i = 10;i++; // 单独使用System.out.println("i:" + i); // i:11int j = 10;++j; // 单独使用System.out.println("j:" + j); // j:11int x = 10;int y = x++; // 赋值运算,++在后边,所以是使用x原来的值赋值给y,x本身自增1System.out.println("x:" + x + ", y:" + y); // x:11,y:10int m = 10;int n = ++m; // 赋值运算,++在前边,所以是使用m自增后的值赋值给n,m本身自增1System.out.println("m:" + m + ", m:" + m); // m:11,m:11
练习:
int x = 10;int y = x++ + x++ + x++;System.out.println(y); // y的值是多少?/*解析,三个表达式都是++在后,所以每次使用的都是自增前的值,但程序自左至右执行,所以第一次自增时,使用的是10进行计算,但第二次自增时,x的值已经自增到11了,所以第二次使用的是11,然后再次自增。。。所以整个式子应该是:int y = 10 + 11 + 12;输出结果为33。*/注意:通过此练习深刻理解自增和自减的规律,但实际开发中强烈建议不要写这样的代码!小心挨打!
3 赋值运算符(应用)
符号 作用 说明= 赋值 a=10,将10赋值给变量a+= 加后赋值 a+=b,将a+b的值给a-= 减后赋值 a-=b,将a-b的值给a*= 乘后赋值 a*=b,将a×b的值给a/= 除后赋值 a/=b,将a÷b的商给a%= 取余后赋值 a%=b,将a÷b的余数给a.
注意:
扩展的赋值运算符隐含了强制类型转换。
short s = 10;s = s + 10; // 此行代码报出,因为运算中s提升为int类型,运算结果int赋值给short可能损失精度s += 10; // 此行代码没有问题,隐含了强制类型转换,相当于 s = (short) (s + 10);
4 关系运算符(应用)
关系运算符有6种关系,分别为小于、小于等于、大于、等于、大于等于、不等于。
注意事项:
关系运算符的结果都是boolean类型,要么是true,要么是false。
千万不要把“”误写成“=”,""是判断是否相等的关系,"="是赋值。
int a = 10;int b = 20;System.out.println(a == b); // falseSystem.out.println(a != b); // trueSystem.out.println(a > b); // falseSystem.out.println(a >= b); // falseSystem.out.println(a < b); // trueSystem.out.println(a <= b); // true// 关系运算的结果肯定是boolean类型,所以也可以将运算结果赋值给boolean类型的变量boolean flag = a > b;System.out.println(flag); // 输出false
5 逻辑运算符(应用)
逻辑运算符把各个运算的关系表达式连接起来组成一个复杂的逻辑表达式,以判断程序中的表达式是否成立,判断
的结果是 true 或 false。
//定义变量int i = 10;int j = 20;int k = 30;//& “与”,并且的关系,只要表达式中有一个值为false,结果即为falseSystem.out.println((i > j) & (i > k)); //false & false,输出falseSystem.out.println((i < j) & (i > k)); //true & false,输出falseSystem.out.println((i > j) & (i < k)); //false & true,输出falseSystem.out.println((i < j) & (i < k)); //true & true,输出trueSystem.out.println("--------");//| “或”,或者的关系,只要表达式中有一个值为true,结果即为trueSystem.out.println((i > j) | (i > k)); //false | false,输出falseSystem.out.println((i < j) | (i > k)); //true | false,输出trueSystem.out.println((i > j) | (i < k)); //false | true,输出trueSystem.out.println((i < j) | (i < k)); //true | true,输出trueSystem.out.println("--------");//^ “异或”,相同为false,不同为trueSystem.out.println((i > j) ^ (i > k)); //false ^ false,输出falseSystem.out.println((i < j) ^ (i > k)); //true ^ false,输出trueSystem.out.println((i > j) ^ (i < k)); //false ^ true,输出trueSystem.out.println((i < j) ^ (i < k)); //true ^ true,输出false
6 短路逻辑运算符(理解)
在逻辑与运算中,只要有一个表达式的值为false,那么结果就可以判定为false了,没有必要将所有表达式的值都
计算出来,短路与操作就有这样的效果,可以提高效率。同理在逻辑或运算中,一旦发现值为true,右边的表达式
将不再参与运算。
逻辑与&,无论左边真假,右边都要执行。
短路与&&,如果左边为真,右边执行;如果左边为假,右边不执行。逻辑或|,无论左边真假,右边都要执行。短路或||,如果左边为假,右边执行;如果左边为真,右边不执行。
int x = 3;int y = 4;System.out.println((x++ > 4) & (y++ > 5)); // 两个表达都会运算System.out.println(x); // 4System.out.println(y); // 5System.out.println((x++ > 4) && (y++ > 5)); // 左边已经可以确定结果为false,右边不参与运算System.out.println(x); // 4System.out.println(y); // 4
7 三元运算符(理解)
三元运算符语法格式:
关系表达式 ? 表达式1 : 表达式2;
解释:问号前面的位置是判断的条件,判断结果为boolean型,为true时调用表达式1,为false时调用表达式2。其
逻辑为:如果条件表达式成立或者满足则执行表达式1,否则执行第二个。
举例:
int a = 10;int b = 20;int c = a > b ? a : b; // 判断 a>b 是否为真,如果为真取a的值,如果为假,取b的值
8 三元运算符案例(应用)
需求:
一座寺庙里住着三个和尚,已知他们的身高分别为150cm、210cm、165cm,请用程序实现获取这三个和尚的最
高身高。
public class OperatorTest02 {public static void main(String[] args) {//1:定义三个变量用于保存和尚的身高,单位为cm,这里仅仅体现数值即可。int height1 = 150;int height2 = 210;int height3 = 165;//2:用三元运算符获取前两个和尚的较高身高值,并用临时身高变量保存起来。int tempHeight = height1 > height2 ? height1 : height2;//3:用三元运算符获取临时身高值和第三个和尚身高较高值,并用最大身高变量保存。int maxHeight = tempHeight > height3 ? tempHeight : height3;//4:输出结果System.out.println("maxHeight:" + maxHeight);}}
流程控制
【1】流程控制的作用:
流程控制语句是用来控制程序中各语句执行顺序的语句,可以把语句组合成能完成一定功能的小逻辑模块。
【2】控制语句的分类:
控制语句分为三类:顺序、选择和循环。
“顺序结构”代表“先执行a,再执行b”的逻辑。
“条件判断结构”代表“如果…,则…”的逻辑。
“循环结构”代表“如果…,则再继续…”的逻辑。
三种流程控制语句就能表示所有的事情!不信,你可以试试拆分你遇到的各种事情。这三种基本逻辑结构是相互支撑的,它们共同构成了算法的基本结构,无论怎样复杂的逻辑结构,都可以通过它们来表达。所以任何一种高级语言都具备上述两种结构。
本章是大家真正进入编程界的“门票”。
【3】流程控制的流程:
分支结构(选择结构)
if:
(1)单分支
【1】语法结构:
if(布尔表达式){语句块}
if语句对布尔表达式进行一次判定,若判定为真,则执行{}中的语句块,否则跳过该语句块。流程图如图所示:
public class TestIf01{ public static void main(String[] args){ //实现一个功能:给出三个数(1-6),对三个数求和计算,根据和的大小来分配不同的奖品 //1.给出三个数: int num1 = 6; int num2 = 2; int num3 = 3; //2.求和 int sum = 0; sum += num1; sum += num2; sum += num3; System.out.println("和为:"+sum); //3.根据和判断奖品: //如果和大于等于14,那么就是一等奖 if(sum>=14){ System.out.println("一等奖"); System.out.println("恭喜你很幸运,中了一等奖"); } if(sum>=10&&sum<14){ System.out.println("二等奖"); } if(sum>=6&&sum<10){ System.out.println("三等奖"); } if(sum<6){ System.out.println("四等奖"); } /* if-单分支: (1)结构: if(条件表达式,这个表达式的结果是布尔值:要么是false,要么是true){ //如果上面()中的表达式返回结果是true,那么执行{}中代码 //如果上面()中的表达式返回结果是false ,那么不执行{}中代码 //PS:{}中的代码是否执行,取决于()中表达式的返回结果 } (2)上面的代码中,我用四个单分支拼凑出四个选择,每个选择是独立的,依次判断执行的 (3)if后面的()中的条件,要按照自己需求尽量完善 (4){}可以省略不写,但是一旦省略,这个if就只负责后面的一句话,所以我们不建议初学者省略 */ }}
(2)多分支
【1】语法结构:
if(布尔表达式1) {语句块1;} else if(布尔表达式2) {语句块2;}……else if(布尔表达式n){语句块n;} else {语句块n+1;}
当布尔表达式1为真时,执行语句块1;否则,判断布尔表达式2,当布尔表达式2为真时,执行语句块2;否则,继续判断布尔表达式3······;如果1~n个布尔表达式均判定为假时,则执行语句块n+1,也就是else部分。
public class TestIf02{ public static void main(String[] args){ //实现一个功能:给出三个数(1-6),对三个数求和计算,根据和的大小来分配不同的奖品 //1.给出三个数: int num1 = 6; int num2 = 4; int num3 = 2; //2.求和 int sum = 0; sum += num1; sum += num2; sum += num3; System.out.println("和为:"+sum); //3.根据和判断奖品: /* 利用一个多分支 【1】结构: if(){ }else if(){ }else if(){ }... else{ } 【2】else:隐藏了一个条件,跟上面分支条件表达式相反的功能 (详见数轴分析) 【3】多分支:好处:只要满足一个 分支以后,后面的分支就不需要判断了 --》效率高 【4】我们写代码的时候,尽量保证else的存在--》else分支相当于“兜底”“备胎”的作用,别的分支都不走,就会走这个分支了 */ if(sum>=14){ System.out.println("一等奖"); }else if(sum>=10){//隐藏了sum<14 System.out.println("二等奖"); }else if(sum>=6){//隐藏了sum<10 System.out.println("三等奖"); }else{//隐藏了sum<6 System.out.println("四等奖"); } }}
(3)双分支
【1】语法结构:
if(布尔表达式){语句块1}else{语句块2}
当布尔表达式为真时,执行语句块1,否则,执行语句块2。也就是else部分。流程图如图所示:
Switch:
【1】switch多分支结构(多值情况)
语法结构:
switch (表达式) {case 值1:语句序列1;[break];case 值2:语句序列2;[break];… … … … …[default:默认语句;]}
switch语句会根据表达式的值从相匹配的case标签处开始执行,一直执行到break语句处或者是switch语句的末尾。如果表达式的值与任一case值不匹配,则进入default语句(如果存在default语句的情况)。根据表达式值的不同可以执行许多不同的操作。switch语句中case标签在JDK1.5之前必须是整数(long类型除外)或者枚举,不能是字符串,在JDK1.7之后允许使用字符串(String)。大家要注意,当布尔表达式是等值判断的情况,可以使用if-else if-else多分支结构或者switch结构,如果布尔表达式区间判断的情况,则只能使用if-else if-else多分支结构。
public class TestSwitch{ public static void main(String[] args){ /* 实现一个功能: 根据给出的学生分数,判断学生的等级: >=90 -----A >=80 -----B >=70 -----C >=60 -----D <60 -----E 用if分支: if(score>=90){ }else if(score>=80){ } */ //1.给出学生的成绩: int score = 167; //2.根据成绩判断学生的等级: switch(score/10){ case 10 : case 9 : System.out.println("A级");break; case 8 : System.out.println("B级");break; case 7 : System.out.println("C级");break; case 6 : System.out.println("D级");break; default:System.out.println("成绩错误");break; case 5 : case 4 : case 3 : case 2 : case 1 : case 0 : System.out.println("E级");break; } /* 【1】语法结构: switch(){ case * : case * : ....... } 【2】switch后面是一个(),()中表达式返回的结果是一个等值,这个等值的类型可以为: int,byte,short,char,String,枚举类型 【3】这个()中的等值会依次跟case后面的值进行比较,如果匹配成功,就执行:后面的代码 【4】为了防止代码的“穿透”效果:在每个分支后面加上一个关键词break,遇到break这个分支就结束了 【5】类似else的“兜底”“备胎”的分支:default分支 【6】default分支可以写在任意的位置上,但是如果没有在最后一行,后面必须加上break关键字, 如果在最后一行的话,break可以省略 【7】相邻分支逻辑是一样的,那么就可以只保留最后一个分支,上面的都可以省去不写了 【8】switch分支和if分支区别: 表达式是等值判断的话--》if ,switch都可以 如果表达式是区间判断的情况---》if最好 【9】switch应用场合:就是等值判断,等值的情况比较少的情况下 */ }}
循环结构
(1)while
【1】语法结构:
while (布尔表达式) {循环体;}
在循环刚开始时,会计算一次“布尔表达式”的值,若条件为真,执行循环体。而对于后来每一次额外的循环,都会在开始前重新计算一次。
语句中应有使循环趋向于结束的语句,否则会出现无限循环–––"死"循环。
public class TestWhile{ public static void main(String[] args){ //功能:1+2+3+4+5 //1.定义变量: int num = 1;[1]条件初始化 //2.定义一个求和变量,用来接收和: int sum = 0; while(num<=5){[2]条件判断 sum += num;[3]循环体 num++;[4]迭代 } //3.输出和 System.out.println(sum); }}
(2)do-while
【1】语法结构:
do {循环体;} while(布尔表达式) ;
do-while循环结构会先执行循环体,然后再判断布尔表达式的值,若条件为真,执行循环体,当条件为假时结束循环。do-while循环的循环体至少执行一次。
public class TestDoWhile{ public static void main(String[] args){ //1+2+3+4+...100 //while方式: /* int i = 101; int sum = 0; while(i<=100){ sum += i; i++; } System.out.println(i);//101 System.out.println(sum);//0 */ //do-while方式: int i = 101; int sum = 0; do{ sum += i; i++; }while(i<=100);//一定要注意写这个分号,否则编译出错 System.out.println(i);//102 System.out.println(sum);//101 /* 【1】while和do-while的区别: while:先判断,再执行 do-while:先执行,再判断---》至少被执行一次,从第二次开始才进行判断 【2】什么场合使用do-while: while(考试是否通过){ 考试; } ---》不合适 do{ 考试; }while(考试是否通过); ---》合适 */ }}
(3)for
【1】语法结构:
for (初始表达式; 布尔表达式; 迭代因子) {循环体;}
for循环语句是支持迭代的一种通用结构,是最有效、最灵活的循环结构。for循环在第一次反复之前要进行初始化,即执行初始表达式;随后,对布尔表达式进行判定,若判定结果为true,则执行循环体,否则,终止循环;最后在每一次反复的时候,进行某种形式的“步进”,即执行迭代因子。
初始化部分设置循环变量的初值
条件判断部分为任意布尔表达式
迭代因子控制循环变量的增减
for循环在执行条件判定后,先执行的循环体部分,再执行步进。
public class TestFor01{ public static void main(String[] args){ //1+2+3+..+100 //while: /*int i = 1; int sum = 0; while(i<=100){ sum += i; i++; } System.out.println(sum); */ //for: int sum = 0; int i; for(i = 1;i<=100;i++){ sum += i; } System.out.println(sum); System.out.println(i); /* 【1】for的结构: for(条件初始化;条件判断;迭代){ 循环体; } 【2】i的作用域:作用范围:离变量最近{} --->可以自己去控制 【3】for循环格式特别灵活:格式虽然很灵活,但是我们自己写代码的时候不建议灵活着写。 for(;;){} -->死循环 int i = 1; for(;i<=100;){ sum += i; i++; } 【4】死循环: for(;;){} while(true){} do{ }while(true); 【5】循环分为两大类: 第一类:当型 while(){} for(;;){} 第二类:直到型 do{}while(); 【6】以后常用:for循环 【7】do-while,while,for循环谁的效率高? 一样高 */ }}
关键字
(1)break
【1】通过练习感受break的作用:作用:停止循环:
public class TestFor02{ public static void main(String[] args){ //功能:求1-100的和,当和第一次超过300的时候,停止程序 int sum = 0; for(int i=1;i<=100;i++){ sum += i; if(sum>300){//当和第一次超过300的时候 //停止循环 break;//停止循环 } System.out.println(sum); } }}
【2】加深理解:
public class TestFor03{ public static void main(String[] args){ //break的作用:停止最近的循环 /* for(int i=1;i<=100;i++){ System.out.println(i); if(i==36){ break;//1-36 } } */ for(int i=1;i<=100;i++){ System.out.println(i); while(i==36){ break; //1-100 ---》break停止的是while循环,而不是外面的for循环 } } }}
【3】break带标签的使用:
public class TestFor04{ public static void main(String[] args){ outer: ----》定义标签结束的位置 for(int i=1;i<=100;i++){ System.out.println(i); while(i==36){ break outer; ----》根据标签来结束循环 } } }}
多层循环也可以使用标签,按照自己的需求去设定即可:
(2)continue
【1】通过案例感受continue的作用:结束本次循环,继续下一次循环
public class TestFor05{ public static void main(String[] args){ //功能:输出1-100中被6整除的数: //方式1: /* for(int i=1;i<=100;i++){ if(i%6==0){//被6整除 System.out.println(i); } } */ //方式2: for(int i=1;i<=100;i++){ if(i%6!=0){//不被6整除 continue;//停止本次循环,继续下一次循环 } System.out.println(i); } }}
【2】加深理解:
public class TestFor06{ public static void main(String[] args){ //continue:结束本次离它近的循环,继续下一次循环 /* for(int i=1;i<=100;i++){ if(i==36){ continue;//1-100中间没有36 } System.out.println(i); } */ for(int i=1;i<=100;i++){ while(i==36){ System.out.println("------"); continue; //1-35+死循环 } System.out.println(i); } }}
【3】continue带标签的使用:
public class TestFor07{ public static void main(String[] args){ outer: for(int i=1;i<=100;i++){ while(i==36){ continue outer; //1-100没有36 } System.out.println(i); } }}
(3)return
return的作用:跟循环无关,就是程序中遇到return那么return所在的那个方法就停止执行了:
public class TestFor08{ public static void main(String[] args){ //return:遇到return结束当前正在执行的方法 for(int i=1;i<=100;i++){ while(i==36){ return; } System.out.println(i); } System.out.println("-----"); }}
练习:
public class TestFor09{ public static void main(String[] args){ /* 输出1-100中被5整除的数,每行输出6个*/ //引入一个计数器: int count = 0;//初始值为0 for(int i=1;i<=100;i++){ if(i%5==0){//被5整除的数 System.out.print(i+"\t"); count++;//每在控制台输出一个数,count就加1操作 if(count%6==0){ System.out.println();//换行 } } } }}import java.util.Scanner;public class TestFor10{ public static void main(String[] args){ /* 实现一个功能: 【1】请录入10个整数,当输入的数是666的时候,退出程序。 【2】判断其中录入正数的个数并输出。 【3】判断系统的退出状态:是正常退出还是被迫退出。 */ //引入一个计数器: int count = 0; //引入一个布尔类型的变量: boolean flag = true; //---》理解为一个“开关”,默认情况下开关是开着的 Scanner sc = new Scanner(System.in); for(int i=1;i<=10;i++){//i:循环次数 System.out.println("请录入第"+i+"个数:"); int num = sc.nextInt(); if(num>0){//录入的正数 count++; } if(num==666){ flag = false;//当遇到666的时候,“开关”被关上了 //退出循环: break; } } System.out.println("你录入的正数的个数为:"+count); if(flag){//flag==true System.out.println("正常退出!"); }else{//flag==false System.out.println("被迫退出!"); } }}
多重循环
乘法口诀:
public class TestFor11{ public static void main(String[] args){ //1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36 /* System.out.print("1*6=6"+"\t"); System.out.print("2*6=12"+"\t"); System.out.print("3*6=18"+"\t"); System.out.print("4*6=24"+"\t"); System.out.print("5*6=30"+"\t"); System.out.print("6*6=36"+"\t"); for(int i=1;i<=6;i++){ System.out.print(i+"*6="+i*6+"\t"); } //换行 System.out.println(); //1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49 for(int i=1;i<=7;i++){ System.out.print(i+"*7="+i*7+"\t"); } //换行 System.out.println(); //1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64 for(int i=1;i<=8;i++){ System.out.print(i+"*8="+i*8+"\t"); } //换行 System.out.println(); */ for(int j=1;j<=9;j++){ for(int i=1;i<=j;i++){ System.out.print(i+"*"+j+"="+i*j+"\t"); } //换行 System.out.println(); } }}
打印各种形状:
【1】长方形:
for(int j=1;j<=4;j++){//j:控制行数 //********* for(int i=1;i<=9;i++){//i:控制*的个数 System.out.print("*"); } //换行: System.out.println(); }
【2】距离前面有一定空隙的长方形:
for(int j=1;j<=4;j++){//j:控制行数 //加入空格: for(int i=1;i<=5;i++){//i:控制空格的个数 System.out.print(" "); } //********* for(int i=1;i<=9;i++){//i:控制*的个数 System.out.print("*"); } //换行: System.out.println(); }
【3】平行四边形:
for(int j=1;j<=4;j++){//j:控制行数 //加入空格: for(int i=1;i<=(9-j);i++){//i:控制空格的个数 System.out.print(" "); } //********* for(int i=1;i<=9;i++){//i:控制*的个数 System.out.print("*"); } //换行: System.out.println(); }
【4】三角形:
for(int j=1;j<=4;j++){//j:控制行数 //加入空格: for(int i=1;i<=(9-j);i++){//i:控制空格的个数 System.out.print(" "); } //********* for(int i=1;i<=(2*j-1);i++){//i:控制*的个数 System.out.print("*"); } //换行: System.out.println(); }
【5】菱形:
//上面三角形: for(int j=1;j<=4;j++){//j:控制行数 //加入空格: for(int i=1;i<=(9-j);i++){//i:控制空格的个数 System.out.print(" "); } //********* for(int i=1;i<=(2*j-1);i++){//i:控制*的个数 System.out.print("*"); } //换行: System.out.println(); } //下面三角形: for(int j=1;j<=3;j++){//j:控制行数 //加入空格: for(int i=1;i<=(j+5);i++){//i:控制空格的个数 System.out.print(" "); } //********* for(int i=1;i<=(7-2*j);i++){//i:控制*的个数 System.out.print("*"); } //换行: System.out.println(); }
【6】空心菱形:
//上面三角形:
for(int j=1;j<=4;j++){//j:控制行数
//加入空格:
for(int i=1;i<=(9-j);i++){//i:控制空格的个数
System.out.print(" ");
}
//*********
for(int i=1;i<=(2*j-1);i++){//i:控制*的个数
if(i==1||i==(2*j-1)){
System.out.print("*");
}else{
System.out.print(" ");
}
}
//换行:
System.out.println();
}
//下面三角形:
for(int j=1;j<=3;j++){//j:控制行数
//加入空格:
for(int i=1;i<=(j+5);i++){//i:控制空格的个数
System.out.print(" ");
}
//*********
for(int i=1;i<=(7-2*j);i++){//i:控制*的个数
if(i==1||i==(7-2*j)){
System.out.print("*");
}else{
System.out.print(" ");
}
}
//换行:
System.out.println();
}