day2--java基础编程:变量,数据类型,类型转换,运算规则,Scanner,运算符,分支结构
1 Day02–变量+数据类型+类型转换
1.1 前言
1.1.1 标识符
可以简单的理解为一个名字。在Java中,我们需要标识代码的很多元素,包括包名、类名、方法、字段、变量等。我们选择的名称就称为标识符,并且遵循以下规则:
- A.标识符可以由字母、数字、下划线(_)、美元符($)组成,但不能包含 @、%、空格等其它特殊字符。
- B.不能以数字开头。
- C.标识符是严格区分大小写的。
- D.标识符的命名最好能反映出其作用,做到英文的见名知意。
- E.可以写使用中文命名,但一般不建议使用,也不建议使用拼音,很low。
1.1.2 关键字
在java语言中已经被赋予特定意义的一些单词。一共有53个关键字。其中有两个保留字:const(常数,不变的)和goto(转到)。关键字不能被用作标识符!!
保留字:暂时没用未来也许会用。
关键字中所有字母都为小写。
Java中关键字很多,不需要强制记忆,因为在编译程序是如果你使用了关键字做标识符编译器会提醒你出错。
1.1.3 注释
1) java规范的三种注释方式:
// 单行注释 (快捷键:ctrl+/, 取消注释:重复使用一次)
/* 多行注释 */ (快捷键:ctrl+shift+/),取消注释:重复使用一次
/** 文档注释(java特有) */ (快捷键:/**+enter)
使用位置:
类上,类的属性上,类的方法上-----推荐使用文档注释
方法内部----推荐使用单行、多行注释
2) 单行注释和多行注释:
2.1) 作用:
- Java代码的解释说明。不影响程序的运行,用于辅助读程序。
- 调试所写的代码
2.2) 特点:
单行注释和多行注释,注释了的内容不参与编译。
换句话说,编译以后生成的.class结尾的字节码文件中不包含注释掉的信息。
2.3) 注意事项:多行注释不可以嵌套使用,其它注释虽然可以嵌套但没有啥意义。
3). 文档注释:
3.1) 作用:注释内容可以被JDK提供的工具 javadoc 所解析,生成一套以网页文件形式体现的该程序的说明文档。
3.2) 案例:
生成自己的API文档:通过命令行或者通过开发工具如idea,具体百度一下。
命令:javadoc 参数 文件
1.1.4 eclipse中的快捷键
查看源码, ctrl+鼠标点击。
syso+alt+/: 输出语句快捷键
ctrl +/ : 选中多行代码,快速添加单行注释。(取消掉,再次快捷键)
Ctrl+shift+o: 导包快捷键
Ctrl +d: 每次删除一行的快捷键(在要删除的代码块,后使用快捷键可以删除一行)
ctrl +n 快捷键相当于new在用上下键 (创建项目,包,类全程不用鼠标)
Alt+上下箭头(对代码进行上下移动)
1.1.5 java中的转义字符
转义字符:用来表示特殊的符号或特殊意义.
\b :表示后退一个字符
\t :表示一个制表位
\n :表示换到下一行
\r:回车
\” :表示双引号
\’ :表示单引号
\ :表示反斜杠字符\
1.1.6 java中的输出语句
System,out.print(); //输出不换行
System,out.println(); //换行
System,out.println(“ ”);//输出一个空格
System,out.println(“\t”); //对齐:输出的数加上空格一共8位。也可以改为(“ “)的形式。
1.1.7 变量(默认值)
举例:
房间 --------- 变量
房间名字 --------- 变量名
房间类型-------- 变量类型
入住的客人------- 变量值
概念:在JAVA中,有的数据值是不固定的,总在变,我们还需要记录这些值,我们可以把这些值理解为变量。
变量的本质:其实是内存里的一部分空间,创建变量的时候,意味着向操作系统申请一部分内存的空间,声明不同类型的变量本质上就是申请的内存空间大小不一样;(程序的执行的第一步,都是载入内存,接着按照程序的执行和硬件的关系)
变量的使用原则:就近原则,尽量控制到最小范围。
变量的声明:变量类型 变量名 = 变量值。
= :赋值号,右边的数据,赋予给左边的变量。
int num = 18; //声明的同时赋值
等价于:
int num; //先声变量
num = 20;//在进行赋值
注意:
- 变量名必须是一个有效的标识符。
- 变量名不可以使用java关键字。
- 同一个作用域内,变量名不能重复。
- java中的标点符号是英文的。
- 变量每句话都以分号结尾。
Java中变量使用的规则:
- java中的变量需要先声明后使用。(局部变量没有默认值,想要输出使用,必须声明并且赋值好才能使用。成员变量有默认值,想要输出使用,不赋值也能输出)
- 变量使用时,可以声明变量的同时进行初始化(初始化:第一次赋值),也可以先声明后赋值。
- 变量中每次只能赋一个值,但可以修改多次。
- Main方法中定义的变量必须先赋值,然后才能输出。
- 虽然语法中没有提示错误,但实际开发中,变量名不建议使用中文,容易产生安全隐患,譬如后期跨平台操作时出现乱码等等。
- 变量的使用必须与数据类型匹配。
- 变量都定义在其作用域内。在作用域内,它是有效的。换句话说,出了作用域,就失效了
- 变量作用域范围:从变量的声明开始一直到包含它最近的{ }的程序结束。
- 变量命名规则:驼峰命名法"score,myScore,myJavaScore(第二个单词首字母大写)。
变量的分类:
- 按被声明的位置划分:
成员变量
(类里方法外)和局部变量
(方法内部)。成员变量又分为:实例变量
和静态变量
(添加Static关键字) - 按所属的数据类型划分:
基本数据类型
和引用数据类型(类,接口,数组)
。
局部变量:
- 定义在方法中(包括方法的参数),或者局部代码块中。
- 必须手动初始化(赋初值),来分配内存。如:int i=5;
- 作用域也就是方法里或者局部代码块里,方法运行完内存就释放了。
成员变量:
- 定义在类里方法外。
- 不用初始化,也会自动被初始化成默认值。
- 作用域是整个类中,类消失了,变量才释放。
成员变量的默认值:
1).引用类型(除了8大基本类型):默认值为 null
2).基本类型:
其中char: /u0000
(默认值,一般不显示。空白符的code是0x20,0x20以下是不可见的控制字符。某些系统在遇到不可见字符时会输出一个方框表示遇到了不可见字符)
基本类型 | 默认值 |
---|---|
byte | 0 |
shot | 0 |
int | 0 |
long | 0L |
float | 0.0f |
double | 0.0d |
boolean | false |
1.1.8 常量
在day03 – 3.3 --final中学习的常量。
概述:在程序运行过程中一直不会改变的量成为常量。
常量的定义形式: final 数据类型 常量名 = 值;
,一般为了方便外界调用,都会被static修饰,可以直接被类名.访问。最终形式为:public static final 数据类型 常量名 = 值;
。
常量命名规范:推荐常量名所有字母大写,多个单词用下划线(“_”)隔开(推荐就是不强制)如:MAX_VALUE
常量注意事项:
- 必须声明同时初始化(必须直接赋初值,不能修改),(静态块中赋值也可以,但不推荐)
- 由类名点来访问,并且不能改变。
常量优点:常量在编译期被直接替换为具体的值- -效率高
常量何时用?数据永远不变并且经常被使用。
1.1.9 变量测试案例
//测试一:
package cn.tedu.variable;
import org.junit.Test;
//测试 变量的使用
public class Test6_Variable {
//TODO 测试其他类型 的默认值
//2,成员变量:位置是在类里方法外 + 有默认值 + 作用范围是整个类里
double count ;
//3,就近原则---前提是---当成员变量 和 局部变量同名时,你使用的一定是局部变量
int sum = 20 ;
//单元测试junit :要求方法要有标志@Test + 方法必须是public的 + 方法返回值是void,没有参数列表
@Test //需要导包(1 2 都可以)
public void show() {
//1,局部变量:位置是在方法里 + 必须初始化 + 作用范围是方法里
int sum = 10;
System.out.println(sum);//10,就近原则
System.out.println(count);//0.0
}
}
//测试二:
package cn.tedu.arrays;
public class Test2_Variable {
//1、成员变量:在类里方法外
//作用范围就是整个类里
//可以不初始化,也会有默认值
int age = 20;
int sum = 30;
public static void main(String[] args) {
//2局部变量:在方法里
//作用范围就是方法里,出了这个方法就不认识了
//必须初始化
int sum = 10;
System.out.println(sum);//10
//3、变量的就近原则,附近有同名的会去执行最近的
System.out.println(sum);//10
}
}
1.1.10 成员变量注意点
注意:成员变量不能先声明后赋值。
解释:成员变量在类的范围内,存在于堆内存中,会有默认的初始值,在声明的同时已经给变量赋值了。再次”赋值“实际是使用了语句,而类体里面只能出现变量和方法,不能出现语句。
package com.cn.ins;
public class Aa {
private int age = 10;
int b;
b= 20;//报错:成员变量不能先声明后赋值。
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
1.2 数据类型
强类型语言:要求变量的使用要严格符合规定,所有变量必须先定义后使用。如:Java、.net 、Python、C++等语言。
弱类型语言:数据类型可以被忽略的语言。它与强类型定义语言相反, 一个变量可以赋不同数据类型的值。如:vb 、PHP、javascript等语言。
Java的数据类型分为2大类:
- 基本数据类型:变量存的是数据本身。(相当于抽屉里的东西)
- 引用数据类型:(除了基本类型都是引用类型,如:类,接口,数组)变量存的是保存数据的空间地址。(相当于抽屉的钥匙)
1.2.1 基本类型(八种)
从小到大排序:byte short (char) int long float double
解释:布尔类型不参与排序,char会自动转化为int。
名词解释:什么是字节。
1.2.2 练习1:最大值最小值
package day0102;
//总结
//1,基本类型:byte short int long float double char boolean
//2,工具类:Byte Short Integer Long Float Double Character Boolean
//3,工具类提供了很多功能,其中就包含了大小值
//基本类型对应的包装类提供了一些功能,最大值,最小值 没有括号不是方法
//注意包装类首字母大写,尤其2个特殊
public class Test1 {
public static void main(String[] args){
//=====1、整型测试开始
//变量类型 变量名 = 变量值
byte a=-128; 打印变量的值,不需要" "
byte b=127;
short c=Short.MIN_VALUE;
short d=Short.MAX_VALUE;
int e=Integer.MIN_VALUE;
int f=Integer.MAX_VALUE;
long g=Long.MIN_VALUE;
long h=Long.MAX_VALUE;
System.out.println(a);
System.out.println(b);
System.out.println(c);
System.out.println(d);
System.out.println(e);
System.out.println(f);
System.out.println(g);
System.out.println(h);
//=====整型测试结束
//=====2、浮点测试开始
/**
*float是单精度,对小数运算不精确。double是双精度,对小数运算精确。
*对于编程人员来说,double和float的区别是double精度高,但double消耗内存是float的两倍。
*且double的运算速度较float稍慢。
*/
float i=Float.MIN_VALUE; //1.4E-45(代表10的负45次方)
float j=Float.MAX_VALUE; //3.4028235E38(代表10的38次方)
double k=Double.MIN_VALUE; //4.9E-324
double l=Double.MAX_VALUE; //1.7976931348623157E308
System.out.println(i);
System.out.println(j);
System.out.println(k);
System.out.println(l);
//=====浮点测试结束
//=====3、字符测试开始
/**
*字符char 单引号
*字符串String(S大写) 双引号
*/
//① 定义char型变量,通常使用一对'',内部只能写一个字符
char c = 'a'; //可以存一个字母或者数字或者符号不能没有,可以是空格
char c4 ='1'; //数字也只能存一个。
char c2 = 97; //可以直接存数字(可以写多个数字)
char c3 = '中'; //可以存一个中文汉字
//char类型可以存一个数字,但是在使用时,并不是使用了数字本身,而是去查数字对应的字符,然后使用字符。
//ascii码表,规定了数字和字符的对应关系。其中数字97就是对应了字符a。 97----a 65---A 48---0
//ascii码表里,规定了0~127数字对应的字符,char类型的取值
//范围是0~65535.那么从128~65535默认对应的字符是?.
System.out.println(c);
System.out.println(c2);//a
System.out.println(c3);
//② 表示方式:1.声明一个字符 2.转义字符 3.直接使用 Unicode 值来表示字符型常量
char c5 = '\n';//换行符
c5 = '\t';//制表符
System.out.print("hello" + c5);
System.out.println("world");
char c6 = '\u0043';
System.out.println(c6);
//=====4、布尔
//① 只能取两个值之一:true 、 false
//② 常常在条件判断、循环结构中使用
boolean b = true;
boolean b2 = false;
}
}
//long start = System.currentTimeMillis()用于获取自1970.1.1零时到此时此刻的毫秒数,返回值类型为long类型·
1.2.3 练习2:输入个人信息
王海涛今年20岁,月薪20000,奉劝大家拼命学java,才能早日走向人生巅峰。
package day0201_规则;
import java.util.Scanner;
public class Test1_个人信息 {
public static void main(String[] args) {
System.out.println("姓名:");
String name= new Scanner(System.in).nextLine();
//注意:String对应的是Line
System.out.println("性別:");
String gender= new Scanner(System.in).nextLine();
System.out.println("年龄:");
//其它的都是首字母大写
int age= new Scanner(System.in).nextInt();
System.out.println("您输入的个人信息是:");
System.out.println("姓名:"+name);
System.out.println("性別:"+gender);
System.out.println("年龄:"+age);
}
}
1.2.4 练习3:String类型变量的使用
/*
String类型变量的使用
1. String属于引用数据类型,翻译为:字符串
2. 声明 String类型变量时,使用一对""
3. String可以和 8种基本数据类型变量做运算,且运算只能是连接运算:+
4. 运算的结果仍然是String类型
*/
class StringTest {
public static void main(String[] args) {
String s1 = "Hello World!";
System.out.println(s1);
String s2 = "a";
String s3 = "";
//char c = '';//编译不通过
//***********************
int number = 1001;
String numberStr = "学号:";
String info = numberStr + number;// +:连接运算
boolean b1 = true;
String info1 = info + b1;// +:连接运算
System.out.println(info1);
//***********************
//练习1
char c = 'a';//97 A:65
int num = 10;
String str = "hello";
System.out.println(c + num + str);//107hello
System.out.println(c + str + num);//ahello10
System.out.println(c + (num + str));//a10hello
System.out.println((c + num) + str);//107hello
System.out.println(str + num + c);//hello10a
//练习2
//* *
System.out.println("* *");
System.out.println('*' + '\t' + '*');
System.out.println('*' + "\t" + '*');
System.out.println('*' + '\t' + "*");
System.out.println('*' + ('\t' + "*"));
//***********************
//String str1 = 123;//编译不通过
String str1 = 123 + "";
System.out.println(str1);//"123"
//数字类型不能和字符串类型进行 自动和强制类型转换
//int num1 = str1;
//int num1 = (int)str1;//"123"
//基本类型和引用类型,可以使用包装类进行转换
int num1 = Integer.parseInt(str1);
System.out.println(num1);//123
}
}
1.2.5 练习4:字符串的拼接过程。
大家好,我叫渣渣辉,今年28。
package cn.tedu.basic;
//这个类用来测试字符串拼接
public class Test2_Info {
public static void main(String[] args) {
//值是一串,Java里表示一串数据,就是String类型。
String name = "蔡徐坤";
byte age = 28;
//通过+拼接字符串, "+?+"
System.out.println("大家好,我叫"+name+",今年"+age+"。");
}
}
1.2.6 练习5:圆形面积
圆的面积:π*r*r
圆的周长:2*π*r
package day0104;
import java.util.Scanner;
public class Test1 {
public static void main(String[] args) {
//定义变量,记录半径r
// double r = 10.1;//不好,值写死了。
//动态的接受键盘输入的值
//测试时:console试图中小红点常亮,表示等待用户的输入,输入完毕后敲回车,表示输入结束。
double r = new Scanner(System.in).nextDouble();
double result = 3.14*r*r;//带入公式
System.out.println(result);
//或者 System.out.println(3.14*r*r);
}
}
1.2.7 练习6:变量交换(3种)
接收用户输入的值:假设a=1,b=2将a和b的值做交换。
package day0103;
import java.util.Scanner;
public class Test1 {
public static void main(String[] args) {
案例1:
//1,接受键盘输入整数a和整数b
System.out.print("输入整数a:");
int a=new Scanner(System.in).nextInt();
//前后对照
System.out.print("输入整数b:");
int b=new Scanner(System.in).nextInt();
//第一种方式:
//2.开始交换
int t=a; //把a的值给t 首尾相连
a=b; //把b的值给a
b=t; //把t的值给b
System.out.println(a);
System.out.println(b);
}
//第二种方式:a=a+b; b=a-b;a=a-b 另一种2个数进行交换
}
案例2:
//练习:交换两个变量的值
int num1 = 10;
int num2 = 20;
System.out.println("num1 = " + num1 + ",num2 = " + num2); //num1 = 10,num2 = 20
//方式一:定义临时变量的方式
//推荐的方式
int temp = num1;
num1 = num2;
num2 = temp;
//方式二:好处:不用定义临时变量
//弊端:① 相加操作可能超出存储范围 ② 有局限性:只能适用于数值类型
//num1 = num1 + num2;
//num2 = num1 - num2;
//num1 = num1 - num2;
//方式三:使用位运算符
//有局限性:只能适用于数值类型
//num1 = num1 ^ num2;
//num2 = num1 ^ num2;
//num1 = num1 ^ num2;
System.out.println("num1 = " + num1 + ",num2 = " + num2);//num1 = 20,num2 = 10
1.3 基本类型的默认字面类型(5条)
1.3.1 整数字面类型(默认值)是int类型
int a = 9999999999;//错,右侧是int类型,但是超出范围
1.3.2 byte,short,char三种比int小的整数可以用范围内的值直接赋值
byte b=127;//对
byte b=128;//错,右面已经超过byte范围是int类型的数据
超过范围的相加 加2次最大值等于它本身(所有的基本类型)
1.3.3 浮点数的字面值是double类型
double a=3.14;//对
float a=3.14;//错,右面是double,float是四字节double是八字节存不下
1.3.4 字面值后缀l f d
//因为它默认的是int类型虽然可以自动转,但是它超出本身的范围了。所以加上一个L 表示long 类型。
//这个整数默认是int类型,但是超出了int范围,还想使用怎么办?
//加后缀L,用来把字面值是int类型的数据,提升成long类型
L –long 如:long a = 99999999999;//错,超出范围,解决方案加L
//后缀f,用来把默认的double类型的小数,转成float类型
F –float 如:float a = 3.14;//错,右面是double类型,解决方案加F或者(float)
//后缀d,用来把字面值是int类型的3,转成double类型
D –double 如:double a=3;//错,右面是int,解决方案加D或者改成3.0
//后缀一般默认是大写,因为小写有时候想数字1不好区分。
注意不加也不报错,因为3在double类型的取值范围之内。
1.3.5 进制前缀
0x - 16进制
0 -8进制
\u -char类型,16进制
0b -2进制 0b0011
1.4 基本类型的类型转换
注意事项:
1.不能对布尔值进行转换。(char类型可以,因为它对应的编码表为数字)
2.不能把对象类型转换为不相干的类型。
3.在把高容量转换为低容量时需要强制类型转换。
4.小类型转大类型会自动转换。
5.转换时可能出现内存溢出或者精度问题。
1.4.1 小到大(隐式转换)
不需要强制类型转换
//自动类型转换
Byte a =120;
Int b=a;//直接转
整形可以转换为浮点型
char可以直接转化为int类型
1.4.2 大到小(显式转换)
需要强制类型转换
//强制类型转换
int xx = 356;
byte y=(byte) xx;
//内存溢出问题
int i=128;
byte b=(byte)i;//-128 内存溢出,byte范围为-128~127
//精度问题:小数转成整数,小数直接舍弃。
double y = 9.1;
int x = (int)y;//右侧的y是大类型,给小类型x赋值时,需要强转、
System.out.println(x);//9,丢弃小数部分
//不管0.1还是0.9全都舍弃
//char类型的转换
char c='a'; //97
int d=c+1;
System.out.println(d);//98
System.out.println((char)d);//b
1.5 运算规则(5条)
1.5.1 计算结果是数据类型,与最大类型一致
3/2 得1 ,而不是1.5,结果是int类型
3d/2 得1.5,相当于double/int,结果是double类型
1.5.2 byte,short,char三种比int小的整数,运算时会先自动转换成int
byte a=3;
byte b=4;
byte c=a+b;//错,运行时,byte会先自动转成int再运算,int+int还是int
byte c = (byte)(a+b);
//右侧的a+b运算时,会自动变成int类型,是大类型。给左面的c小类型赋值??--不能直接赋值需要强转
1.5.3 整数运算溢出
整数运算,类似于一个钟表,转到最大时,再转会回到最小。
注意:在操作比较大的数时,注意溢出问题.
解决方案:提前扩大变量值得范围,把int字面值加L后缀扩大,变成long类型、一般是第一个数后加L。
//jdk1.7新特性:数字之间可以用下划线分割,输出时不会影响。
int money=10_0000_0000;
int years=20;
int total=money*years; //内存溢出 -1474836480
long total2=money*years; //内存溢出,计算完后默认是int类型,转换为long之前就出现问题了。 -1474836480
long total3=(long)money*years;//20000000000
System.out.println(total);
System.out.println(total2);
System.out.println(total3);
//计算:光速运行一年的长度是多少米
System.out.println(300000000*60*60*24*365);
System.out.println(300000000l*60*60*24*365);
//运算结果,字面值就是int类型。但是,已经超出了int取值范围,就会整数运算溢出现象
//解决方案:把int字面值加L后缀扩大,变成long类型、一般是第一个数后加L。
1.5.4 浮点数运算不精确
原因:浮点型数字特点是 有限 ,离散的,会有舍入误差,结果只能是一个约数,接近但不等于。
解决:java提供了解决方案,后面就会讲到,BigDecimal。
System.out.println(1-0.8);//0.19999999999999996
System.out.println(4.35*100);//434.99999999999994
//最好完全避免使用浮点数进行比较
float f= 0.1f;//0.1
double d=1.0/10;//0.1
System.out.println(f==d);//false
1.5.5 浮点数的特殊值
Infinity 无穷大 3.14/0
Nan not a number 0/0.0
//输出结果不能出现这种情况,一旦出现检查代码(分母为0或分子分母都为0)
1.6 拓展
1.6.1 char 型变量中能不能存储一个中文汉字,为什么?
char 类型可以存储一个中文汉字,因为 Java 中使用的编码是 Unicode(不选择任何特定的编码,直接使用字符在字符集中的编号,这是统一的唯一方法),一个 char 类型占 2 个字节(16 比特),所以放一个中文是没问题的。
1.6.2 用户交互Scanner
注意:
- String对应的是Line,其它的都是首字母大写.
- 对于char型的获取,Scanner没有提供相关的方法。只能获取一个字符串。如果非要用char类型来接收可以调用 gender.charAt(0)方法。
import java.util.Scanner;
/*
如何从键盘获取不同类型的变量:需要使用Scanner类
具体实现步骤:
1.导包:import java.util.Scanner;
2.Scanner的实例化:Scanner scan = new Scanner(System.in);可以写一块
3.调用Scanner类的相关方法(next() / nextXxx()),来获取指定类型的变量
注意:
需要根据相应的方法,来输入指定类型的值。如果输入的数据类型与要求的类型不匹配时,会报异常:InputMisMatchException
导致程序终止。
*/
public class Test1_个人信息 {
public static void main(String[] args) {
System.out.println("姓名:");
String name= new Scanner(System.in).nextLine();//写一块的写法
//注意:String对应的是Line
System.out.println("性別:");
String gender= new Scanner(System.in).nextLine();
System.out.println("年龄:");
//其它的都是首字母大写
int age= new Scanner(System.in).nextInt();
System.out.println("您输入的个人信息是:");
System.out.println("姓名:"+name);
System.out.println("性別:"+gender);
System.out.println("年龄:"+age);
//对于char型的获取,Scanner没有提供相关的方法。只能获取一个字符串
System.out.println("请输入你的性别:(男/女)");
String gender = scan.next();//"男"
char genderChar = gender.charAt(0);//获取索引为0位置上的字符
System.out.println(genderChar);
}
}
输出结果为:hello
输出:hello world
原因:
如果是数字的话用对应的nextxxx()方法进行判断:
package lianxi;
import java.util.Scanner;
public class Ta {
public static void main(String[] args) {
Scanner scanner =new Scanner(System.in);
//从键盘接收数据
int i=0;
float f=0.0f;
System.out.println("请输入整数:");
if(scanner.hasNextInt()) {
/*
* 如果什么也不写默认为true(老手写法)
* if(scanner.hasNextInt()==true) { 新手写法
*/
i= scanner.nextInt();
System.out.println("整数数据"+i);
}else {
System.out.println("输入的不是整数数据");
}
scanner.close();
}
}
2 Day03–运算符+分支结构+循环
2.1 运算符
2.1.1 概述:常用运算符
2.1.2 位运算符
除了常用运算符外还有位运算符:
如何区分&,|,^
何时是逻辑运算符何时是位运算符???
当符号两侧是逻辑运算符且结果为布尔类型,则为逻辑运算符。若符号两侧为整数且结果为整数,则是位运算符。
案例1:
/*
A = 0011 1100
B = 0000 1101
------------------
A&B = 0000 1100 上下2个都是1才为1,否则为0
A/B = 0011 1101 上下2个都是0才为0,否则为1
A^b = 0011 0001 上下2个位置相同则为0,否则则为1.
~B = 1111 0010 取反
2*8 = 16 2*2*2*2
效率极高!!!
<< *2 左移扩大
>> /2 右移缩小
0000 0000 0
0000 0001 1
0000 0010 2
0000 0011 3
0000 0100 4
0000 1000 8
0001 0000 16
*/
System.out.println(2<<3);//16
案例2:
package lianxi;
import java.util.Arrays;
/*
运算符之五:位运算符 (了解)
结论:
1. 位运算符操作的都是整型的数据
2. << :在一定范围内,每向左移1位,相当于 * 2
>> :在一定范围内,每向右移1位,相当于 / 2
面试题:最高效方式的计算2 * 8 ? 2 << 3 或 8 << 1
*/
class BitTest {
public static void main(String[] args) {
int i = 21;
i = -21;
System.out.println("i << 2 :" + (i << 2));//i << 2 :-84 不改变符号
System.out.println("i << 3 :" + (i << 3));//i << 3 :-168
System.out.println("i << 27 :" + (i << 27));//i << 27 :1476395008
int m = 12;
int n = 5;
System.out.println("m & n :" + (m & n));//m & n :4
System.out.println("m | n :" + (m | n));//m | n :13
System.out.println("m ^ n :" + (m ^ n));//m ^ n :9
}
}
2.2 运算符优先级
口诀:单目乘除为关系,逻辑三目后赋值。
单目运算符:一次作用一个变量的运算符,又叫一元运算符
单目:单目运算符+ –(正负数) ,++ –,!(逻辑非),~(按位取反)
乘除:算数运算符:* / % + - (* / %优先级肯定是大于+-的)
为:位运算符:~(按位取反)<<(左移) >>(右移),^(也可以位运算,二进制异或)
关系:关系运算符:> < >= <= == !=
逻辑:逻辑运算符(除!)&& || & | ^
三目:条件运算符A > B ? X : Y
后:无意义,仅仅为了凑字数
赋值:= += -= *= /= %= |= &= ^=
说明:前优先级大于后,比如单目运算符~也是位运算符,~的优先级是单目级别的。至于赋值运算符中没有见过的自行测试
PS:大家没必要去死记运算符的优先级顺序,实际开发中,一般会使用小括号辅助进行优先级管理。如:
2.3 案例练习
2.3.1 练习1:平年闰年
输入年号,判断是否是闰年。两个条件:
1、能被4整除,并且不能被100整除
2、或者能被400整除
package day0203_平年闰年;
import java.util.Scanner;
public class Test1 {
public static void main(String[] args) {
System.out.println("年号:");
int y = new Scanner(System.in).nextInt(); //1,接受用户输入的年号
String r="平年"; //默认都是平年
//2,判断,这个年号到底是平年还是闰年
if(y%4==0){
if(y%100!=0){
r="闰年";
}
}
if(y%400==0){
r="闰年";
}
或者
//说明:
//两个大条件之间是或者的关系,为了高效,用双或
//大条件1有两个小条件,两个小条件之间是并且的关系,为了高效,用双与
//能否被整除,要取余数,余数为0就是能整除。余数不是0就是不能整除。
if( ( year % 4 == 0 && year % 100 != 0 ) || year % 400 == 0){
//如果年号,能满足判断条件,会进来修改r的默认值为闰年。如果没满足,就一直是默认值平年
r = "闰年";//修改r的值为闰年
if((y%4==0&&y%100!=0)||y%400==0){
r="闰年";
}
System.out.println(y+"年是"+r);
}
}
2.3.2 练习2:自增自减
package com.jia.jian;
public class JiaJian {
public static void main(String[] args) {
//++,--代表自身加一和减一,运算结果与符号顺序有关。
//情况1:单独使用时,++ --无论放在变量前还是变量后,结果都是一样的
int number1 = 10;
//输出方式一: 输出number1++
//System.out.println(number1++);//10
//输出方式二: 输出number1
number1++;
System.out.println(number1);//11
//总结执行过程:符号在后,先使用后变化(先使用:number1++变为10,后变化:number1自身变为11),
//所以输出number1++为10,输出number1为11.
int number2 = 10;
//输出方式一:输出++number2
//System.out.println(++number2);//11
//输出方式二:输出number2
++number2;
System.out.println(number2);//11
//总结执行过程:符号在前,先变化后使用(先变化:++number2变为11,后使用:number2自身变为11),
//所以输出number2++为11,输出number2为11.
int number3 = 10;
number3--;
System.out.println(number3);//9
int number4 = 10;
--number4;
System.out.println(number4);//9
//情况2:参与操作时,符号在后:先使用后变化
//执行过程:符号在后,先执行运算(先把10赋值给num2),后变化(num1++,num1变为11)
int num1 = 10;
int num2 = num1++;
System.out.println("num1:"+num1+",num2:"+num2);//num1:11,num2:10
//情况3:参与操作时,符号在前:先变化后使用
//执行过程:符号在前,先变化(++num3,num3变为11),后执行运算(在把11赋值给num4),
int num3 = 10;
int num4 = ++num3;
System.out.println("num3:"+num3+",num4:"+num4);//num3:11,num4:11
}
}
2.3.3 练习3:求两个数里的大值
/*
三元运算符:
1.结构:(条件表达式)? 表达式1 : 表达式2
2. 说明
① 条件表达式的结果为boolean类型
② 根据条件表达式真或假,决定执行表达式1,还是表达式2.
如果表达式为true,则执行表达式1。
如果表达式为false,则执行表达式2。
③ 表达式1 和表达式2要求是一致的。
④ 三元运算符可以嵌套使用
3.
凡是可以使用三元运算符的地方,都可以改写为if-else
反之,不成立。
4. 如果程序既可以使用三元运算符,又可以使用if-else结构,那么优先选择三元运算符。原因:简洁、执行效率高。
*/
package cn.tedu.basic;
import java.util.Scanner;
//这个类用来测试两个数里的大值
public class Test3_Max {
public static void main(String[] args) {
//1,接受键盘输入的两个整数
//注意:scanner可以直接写,然后三目运算符boolean是他的返回值,前面可以写其他的类型来接受
int a = new Scanner(System.in).nextInt();
int b = new Scanner(System.in).nextInt();
//2,比大小 1 ? 2 :3 ,1判断完如果成立,得到的结果就是2
//a > b成立的话,把a交给max记录,否则,把b交给max记录
int max = a > b ? a : b ;
System.out.println(max);
}
}
2.3.4 练习4:求三个数的最大值
package day0203_平年闰年;
import java.util.Scanner;
public class Test1_三个数的最大值 {
public static void main(String[] args) {
System.out.println("整数a:");
int a = new Scanner(System.in).nextInt();
System.out.println("整数b:");
int b = new Scanner(System.in).nextInt();
System.out.println("整数c:");
int c = new Scanner(System.in).nextInt();
int max = a>b?a:b;
max=max>c?max:c; //分开写
或者
int max = a>b?(a>c?a:c):(b>c?b:c); //合一块写
System.out.println(max);
}
}
2.3.5 练习5:幂运算
//2^3 2*2*2=8 很多运算我们会借助一些工具类来操作。
double pow=Math.pow(3,2);
System.out.println(pow);
2.3.6 练习6:复合赋值运算符
偷懒写法,自带强转功能。
例1:
int a=10;
int b=20;
a+=b; //a=a+b;
a-=b; //a=a-b
System.out.println(a);//30
例2:
byte a = 1;
// a=(byte) (a+4);//右侧int,左侧byte,大转小,强转。
// a=(byte) (a+4);//右侧int,左侧byte,大转小,强转。
a+=4;//会自动完成数据类型的转换
//注意:a=a+4和a+=4是有区别的!!
System.out.println(a);
2.3.7 练习7:字符串连接符 “+”
//字符串连接符:若+一端为字符串,则会转化为Sring类型并进行拼接。
int a=10;
int b=20;
System.out.println(" "+a+b);//1020
System.out.println(a+b+" ");//30
2.3.8 练习8:测试逻辑运算符短路问题
逻辑运算符:&和&&,|与||之间的关系。
当一个&表达式在求值的时候,两个操作数都会被求值,&&更像 是一个操作符的快捷方式。当一个&&表达式求值的时候,先计算第一个操作数,如果它返回true才会计算第二个操作数。如果第一个操作数 取值为fale,第二个操作数就不会被求值。
一般在程序中想要表示true或者false,可以用1表示true,用0表示false
单与:& -- 表示并且的关系
1 & 2 -- 1和2都为true,结果为true
单或:| -- 表示或者的关系
1 | 2 -- 1和2有一个为true,结果为true
双与/短路与:&& -- 表示并且的关系,高效
1 && 2 -- 2会被短路,前提是1为false
双或/短路或:|| -- 表示或者的关系,高效
1 || 2 -- 2会被短路,前提是1为true
真 & 真 -》真
真 & 假 -》假
假 & 真 -》假
假 & 假 -》假
假 | 假 -》假
假 | 真 -》真
真 | 假 -》真
真 | 真 -》真
package lianxi;
import java.util.Arrays;
/*
运算符之四:逻辑运算符
& && | || ! ^
说明:
1.逻辑运算符操作的都是boolean类型的变量
*/
class LogicTest {
public static void main(String[] args) {
//区分& 与 &&
//相同点1:& 与 && 的运算结果相同
//相同点2:当符号左边是true时,二者都会执行符号右边的运算
//不同点:当符号左边是false时,&继续执行符号右边的运算。&&不再执行符号右边的运算。
//开发中,推荐使用&&
boolean b1 = true;
b1 = false;
int num1 = 10;
if(b1 & (num1++ > 0)){
System.out.println("我现在在北京");
}else{
System.out.println("我现在在南京");
}
System.out.println("num1 = " + num1); //我现在在南京 num1 = 11
boolean b2 = true;
b2 = false;
int num2 = 10;
if(b2 && (num2++ > 0)){
System.out.println("我现在在北京");
}else{
System.out.println("我现在在南京");
}
System.out.println("num2 = " + num2); //我现在在南京 num2 = 10
// 区分:| 与 ||
//相同点1:| 与 || 的运算结果相同
//相同点2:当符号左边是false时,二者都会执行符号右边的运算
//不同点3:当符号左边是true时,|继续执行符号右边的运算,而||不再执行符号右边的运算
//开发中,推荐使用||
boolean b3 = false;
b3 = true;
int num3 = 10;
if(b3 | (num3++ > 0)){
System.out.println("我现在在北京");
}else{
System.out.println("我现在在南京");
}
System.out.println("num3 = " + num3);//我现在在北京 num3 = 11
boolean b4 = false;
b4 = true;
int num4 = 10;
if(b4 || (num4++ > 0)){
System.out.println("我现在在北京");
}else{
System.out.println("我现在在南京");
}
System.out.println("num4 = " + num4);// 我现在在北京 num4 = 10
}
}
2.4 分支结构1:if
2.4.1 概述
问题:顺序结构的程序虽然能解决计算、输出等问题,但不能做判断再选择。对于要先做判断再选择的问题就要使用分支结构。
总结:
任何复杂的程序逻辑都可以通过三种结构来实现:
1)顺序结构:从上往下逐行执行,每句必走
2)分支结构:有条件的执行某语句 一次,并非每句必走
3)循环结构:有条件的执行某语句多次,并非每句必走
2.4.2 形式
单分支:满足判断条件,则执行大括号里面的内容。
注意:判断条件又叫条件表达式
条件表达式:结果是boolean。
if(判断条件/条件表达式){
代码。。。
}
双分支:
if(判断条件){
代码1。。。
}else{
代码2。。。
}
多分支:
if(判断条件1){
代码1。。。
}else if(条件2){
代码2。。。
} else if(判断条件3){
代码3。。。
}else{
代码4。。。
}
嵌套分支:
if(判断条件){
if(判断条件){
代码
}
}
注意事项:
- if语句至多有一个else语句,else语句在所有的else if语句之后。
- if语句可以有若干个else if 语句,它们必须在else语句之前。
- 一旦其中一个else语句检测为true,则其它的else if语句以及else语句都不在在执行。
- 对于条件结构中,如果省略了大括号,则只会对第一句代码生效(及:如果没有大括号到第一个分号结束)换句话说:如果条件结构中只有一句代码,则大括号可以省略。但是不建议省略。
- else是可选的。
- if分支可以嵌套
2.4.3 练习1:商品打折
接收用户输入的原价。满1000打9折。满2000打8折。满5000打5折。
注意:java中的多个条件不能写成如:a>b>c 而是要用逻辑运算符a>b&&b>c来输出。
原因:因为比较运算符的结果是boolean类型,布尔类型无法比较大小。
package day999;
import java.util.Scanner;
public class ttt {
public static void main(String[] args) {
/*
说明:
1. else 结构是可选的。
2. 针对于条件表达式:
> 如果多个条件表达式之间是“互斥”关系(或没有交集的关系),哪个判断和执行语句声明在上面还是下面,无所谓。
> 如果多个条件表达式之间有交集的关系,需要根据实际情况,考虑清楚应该将哪个结构声明在上面。
> 如果多个条件表达式之间有包含的关系,通常情况下,需要将范围小的声明在范围大的上面。否则,范围小的就没机会执行了。
*/
System.out.println("输入总原价");
//1,接受用户输入的原价
double price = new Scanner(System.in).nextDouble();
//2,计算折后价,并输出
double now = price;//记录折后价
//注意java中的多个条件不能写成如:a>b>c 而是要用逻辑运算符a>b&&b>c来输出。
if( price >= 5000 ) {//满5000
now = price * 0.5 ;//now记录5折的价
}else if( price >= 2000 ) {//满2000
now = price * 0.8 ;//now记录8折的价
}else if( price >= 1000 ) {//满1000
now = price * 0.9 ;//now记录9折的价
}
或者
if( price >= 1000 && price < 2000) {//满5000
now = price * 0.9 ;//now记录9折的价
}else if( price >= 2000 && price < 5000 ) {//满2000
now = price * 0.8 ;//now记录8折的价
}else if( price >= 5000 ) {//满1000
now = price * 0.5 ;//now记录5折的价
}
System.out.println("原价是:"+price+",折后价是:"+now);
}
}
2.4.4 练习2:统计学员得分
90分以上 优秀
80~89 良好
70~79 中等
60~69 及格
60分以下 不及格
package game;
import java.util.Scanner;
public class aa {
public static void main(String[] args) {
double score = new Scanner(System.in).nextDouble();
//!!!用来增强代码的健壮性
if (score >= 100 || score <= 0) {
System.out.println("请输入0~100以内的值");
return; //结束程序
}
if (score > 90 && score <= 100) {
System.out.println("优秀");
} else if (score >= 80 && score <= 90) {
System.out.println("良好");
} else if (score >= 70 && score <= 79) {
System.out.println("中等");
} else if (score >= 60 && score <= 69) {
System.out.println("及格");
}else if (score < 60) {
System.out.println("不及格");
}
}
}
//优化
String desc = "优秀";
if(score >= 90) {//90分以上 优秀
desc = "优秀";
}else if(score >= 80 && score < 90 ) {//80~89 良好
desc = "良好";
}else if(score >= 70 && score < 80 ) {//70~79 中等
desc = "中等";
}else if(score >= 60 && score < 70 ) {//60~69 及格
desc = "及格";
}else if(score < 60) {//60分以下 不及格
desc = "不及格";
}
System.out.println("得分是:"+score+",属于:"+desc);
2.4.5 练习3:用if 比较3个数的大小
/*
编写程序:由键盘输入三个整数分别存入变量num1、num2、num3,
对它们进行排序(使用 if-else if-else),并且从小到大输出。
说明:
1. if-else结构是可以相互嵌套的。
2. 如果if-else结构中的执行语句只有一行时,对应的一对{}可以省略的。但是,不建议大家省略。
*/
import java.util.Scanner;
class IfTest2 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入第一个整数:");
int num1 = scanner.nextInt();
System.out.println("请输入第二个整数:");
int num2 = scanner.nextInt();
System.out.println("请输入第三个整数:");
int num3 = scanner.nextInt();
if(num1 >= num2){
if(num3 >= num1)
System.out.println(num2 + "," + num1 + "," + num3);
else if(num3 <= num2)
System.out.println(num3 + "," + num2 + "," + num1);
else
System.out.println(num2 + "," + num3 + "," + num1);
}else{
if(num3 >= num2)
System.out.println(num1 + "," + num2 + "," + num3);
else if(num3 <= num1)
System.out.println(num3 + "," + num1 + "," + num2);
else
System.out.println(num1 + "," + num3 + "," + num2);
}
}
}
2.5 [了解]分支结构2:switch
2.5.1 概述
当一个case成立,从这个匹配到的case向后穿透所有case,包括default,直到程序结束或者遇到break程序才结束。
优点:效率高、结构清晰
缺点:只适用于 整数、相等
2.5.2 形式
switch(expr1)中,expr1是一个整数表达式, 整数表达式可以是int基本类型或Integer包装类型,由于byte,short,char都可以隐含转换为int,所以也支持。
注意:
- case标签必须为字符串常量或字面量, 不能声明范围。
- 注意是表达式而不是条件表达式(条件表达式:结果是boolean)。
- switch结构中的表达式,只能是如下的6种数据类型之一:
byte 、short、char、int、枚举类型(JDK5.0新增)、String类型(JDK7.0新增) - break,可以使用在switch-case结构中,表示一旦执行到此关键字,就跳出switch-case结构
- break关键字是可选的。
- default:相当于if-else结构中的else.
default结构是可选的,而且位置是灵活的,写在最后不需要加break。
switch(变量或者表达式){
case 1:
break;
case 2:
break; //break: 跳出switch循环,可选。
case 3:
break;
case 4:
break;
default: //default 加个保险也可以不写,当前面都没有匹配到的时候相当于加个保险走默认的。
}
2.5.3 练习1:数字匹配
package cn.tedu.ifdemo;
//测试switch语法
public class Test7_Switch {
public static void main(String[] args) {
测试1:
int i = 2;
// i 的类型 也就是括号里表示的类型 -- byte short int char jdk1.7新增了String
switch( i ) {
case 1 :
System.out.println(1);
break;
case '1' :
System.out.println('1');
break;
/*1, 当匹配到case时,程序会继续向后穿透所有case包括default,即
*满足一个case条件时会把剩余所有case包括default里面的内容都会
*进行输出,直到程序结束或者遇到break程序才结束。
*/
case 2 :
System.out.println(2);
break;
//2, break用来结束程序
case 3 :
System.out.println(3);
break;
case 4 :
System.out.println(4);
break;
case 5 :
System.out.println(5);
break;
case 6 :
System.out.println(6);
break;
default:
System.out.println(0);//default之后不需要再写break
}
//如果输出的条件一样则可以简写为如:
case 0:
case 1:
case 2:
case 3:
System.out.println("小明");
break;
测试2:
String season = "summer";
switch (season) {
case "spring":
System.out.println("春暖花开");
break;
case "summer":
System.out.println("夏日炎炎");
break;
case "autumn":
System.out.println("秋高气爽");
break;
case "winter":
System.out.println("冬雪皑皑");
break;
default:
System.out.println("季节输入有误");
break;
}
测试3:
//**************如下的两种情况都编译不通过*********************
//情况一:表达式为布尔类型
/*
boolean isHandsome = true;
switch(isHandsome){
case true:
System.out.println("我好帅啊~~~");
break;
case false:
System.out.println("我好丑啊~~~");
break;
default:
System.out.println("输入有误~~~");
}
*/
//情况二:case值不是常量
/*
int age = 10;
switch(age){
case age > 18:
System.out.println("成年了");
break;
default:
System.out.println("未成年");
}
*/
}
}
2.5.4 练习2:case的简写
/*
例题:对学生成绩大于60分的,输出“合格”。低于60分的,输出“不合格”。
说明:如果switch-case结构中的多个case的执行语句相同,则可以考虑进行合并。
*/
class SwitchCaseTest1 {
public static void main(String[] args) {
/*
int score = 78;
switch(score){
case 0:
case 1:
case 2:
...
case 100:
}
*/
/*
int score = 78;
if(score >= 60){
}else{
}
*/
int score = 78;
switch(score / 10){
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
System.out.println("不及格");
break;
case 6:
case 7:
case 8:
case 9:
case 10:
System.out.println("及格");
break;
}
//更优的解决方案:
switch(score / 60){
case 0:
System.out.println("不及格");
break;
case 1:
System.out.println("及格");
break;
}
}
}
2.6 if与switch的对比
/*
从键盘分别输入年、月、日,判断这一天是当年的第几天
注:判断一年是否是闰年的标准:
1)可以被4整除,但不可被100整除
或
2)可以被400整除
说明:
1. 凡是可以使用switch-case的结构,都可以转换为if-else。反之,不成立。
2. 我们写分支结构时,当发现既可以使用switch-case,(同时,switch中表达式的取值情况不太多),
又可以使用if-else时,我们优先选择使用switch-case。原因:switch-case执行效率稍高。
*/
import java.util.Scanner;
class SwitchCaseExer {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("请输入year:");
int year = scan.nextInt();
System.out.println("请输入month:");
int month = scan.nextInt();
System.out.println("请输入day:");
int day = scan.nextInt();
//定义一个变量来保存总天数
int sumDays = 0;
switch(month){
case 12:
sumDays += 30;
case 11:
sumDays += 31;
case 10:
sumDays += 30;
case 9:
sumDays += 31;
case 8:
sumDays += 31;
case 7:
sumDays += 30;
case 6:
sumDays += 31;
case 5:
sumDays += 30;
case 4:
sumDays += 31;
case 3:
//sumDays += 28;
//判断year是否是闰年
if((year % 4 == 0 && year % 100 != 0 ) || year % 400 == 0){
sumDays += 29;
}else{
sumDays += 28;
}
case 2:
sumDays += 31;
case 1:
sumDays += day;
}
System.out.println(year + "年" + month + "月" + day + "日是当年的第" + sumDays + "天");
}
}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!