目录
默认值
关于默认值 1,2 默认类型是int
long a = 8888888888;//错误 默认为int类型, 报错为:Integer number too large
long a = 8888888888L;//通过给整数字面量加后缀L或l(建议L)声明字面量为l
3.0、2.1 默认类型为double
float b = 3.0F;//3.0在float范围之内,加F后缀,声明小数字面量的类型为float类型
double c = 314.0;
c = 3.14e2;//2.14 *10^2
System.out.println(c);//314.0
关于字符的问题
编码表,一个字符要被保存到计算机中,只能以数值形式保存
一个数值对应一个数值,对应关系为ASCII码表
System.out.println('a');//a
System.out.println('a' + 1);// 98 字符先被转化为int类型数据,'a' 97
System.out.println((char)('a' + 1));// 98
运算符
算数运算符
1. 加法、正号
// 字符串拼接 "Hello" + "World" = "HelloWorld"
//操作数1 + 操作数2 两个操作数中,只要有至少一个是字符串,+ 操作执行的就是字符串拼接
System.out.println("hello" + 'a' + 1); //helloa1
System.out.println('a' + 1 + "hello");//98hello 'a' -> 97 + 1 = 98拼接hello
System.out.println("5+5=" + 5 + 5);//5+5=55
System.out.println(5 + 5 + "5+5");//105+5
2. 除法
int a = 3;
int b = 2;
//当参与除法运算的除数和被除数,都是整数的时候,此时运算结果会丢弃小数部分,只保留证整数部分
int c = a / b;
double d = a / b;//因为a 和 b都是整数 将结果1进行隐式类型转换为double类型:1 -> 1.0
System.out.println(c);//1;
System.out.println(d);//1.0
double e = 1.0 * a / b;//隐式类型转换为小数后在进行运算
System.out.println(e);//1.5
3. 取余
int f = 5 % 3;
System.out.println(f);// 2
4. 自增++、自减--
++:让一个变量自增1 a++ -> a = a + 1
--:让一个变量自减1 b-- -> b = b + 1
注意事项
1) ++、-- 他们既可以放在变量之后(a++ b--),也可以放在变量之前(++a --b)
2) 当++或--,不参与任何其他运算的时候,++或--,在变量前或者变量后是没有区别的。例如:a++;++a;
当++或--,参与其他运算的时候 对于++而言:
++在后 a++ + 1,当++在后参与运算,首先a原本的值参与运算后,a的值在自增1
++在前 ++a + 1,当++在前参与运算,首先a的值自增1,在参与运算
对于--而言:同++
// ++
int a = 1;
a++;
System.out.println(a);
// --
int b = 2;
b--;
System.out.println(b);
//++ 在前后的区别
a = 1;
int result = a++ + 1;//result = (a=)1 + 1; a++;
System.out.println(result);//2
System.out.println(a);//2
a = 1;
int result2 = ++a + 1;// a++;result = (a=)2 + 1;
System.out.println(result2);//3
System.out.println(a);//2
a = 4;
// 4 + 6 + 60
b = (a++) + (++a) + (a * 10);
// 4; a++; a++; 6; 6 * 10;
System.out.println(b);//70
赋值运算符
=、+=、-=、*=、/=、%=
a += 3 -> a = a + 3
关系运算符
逻辑运算符
与 &、&&:有一个false结果就是false,都是true才是true
或 |、||:有一个true结果就是true
非 !:取反
异或 ^:相同为false,不同为true true^true = fasle、false^false= fasle、true^false= true
&&与&有什么区别(|与||相同)?
&&运算符发现第一个操作数是false,第二个操作数(对应的表达式)不再运算,结果直接为false
&运算符计算所有操作数,再进行 与运算,得到最终结果
int a = 2;
int b = 3;
boolean c = a > b & a++ == 0;//a > b 为 false 如果a为3,后面就做了运算
System.out.println(a);// 3
a = 2;
c = a > b & a++ == 0;//a > b 为 false 如果a为2,后面就没有做运算
System.out.println(a);// 2
a = 2;
c = a < b || a++ == 0;//a < b 为 true 如果a为2,后面就没有做运算
System.out.println(a);// 2
范围表示
a = 3;
//判断a的值是否在[1,10) 1 <= a < 10
//c = 1 <= a < 10;//错误 布尔类型不能参与运算
//改进 拆分公式为 1 <= a 和 a < 10 两个,同时成立则成立
c = 1 <= a && a < 10;
System.out.println(c);// true
位运算符
(针对变量的二进制位进行运算的)
移位运算
a.左移运算符:3 << 2 = 3 * 2 * 2 = 3 * 2^2
00000000,00000000,00000000,00000011(int类型有4个字节,32位) 0000000,00000000,00000000,000000110(移动一位,补0) 000000,00000000,00000000,0000001100(移动一位,补0)-> 12
左移一位相当于对操作数 * 2(前提是左移之后的结果仍然在相应数据类型的范围之内)
b.带符号的移位:-2 >> 1, 相当于给操作数除以2(只针对未溢出且可以被除尽的数)
原码 10000000,00000000,00000000,00000010
取反 11111111,11111111,11111111,11111101
+1 补码 11111111,11111111,11111111,11111110
右移一位 111111111,11111111,11111111,1111111
(带符号位右移最高位补0还是1?补符号位)
补码 10000000,00000000,00000000,00000001 = -1 (逗号只是为了方便,其实不存在)
除不尽情况 000000000,00000000,00000000,00000011->(右移)
0000000000,00000000,00000000,0000001
c.无符号右移:移位动作和带符号数一模一样,右移之后,高位直接填0
通常用来处理正整数,无符号右移一位相当于除以2
a = 3;
System.out.println(a << 2);// 12
a = -2;
System.out.println(a >> 1);// -1
a = 3;
System.out.println(a >> 1);// 1
a = -2;
//11111111,11111111,11111111,11111110 -> 无符号右移一位 011111111,11111111,11111111,1111111
System.out.println(a >>> 1);// 2147483647
&:只针对二进制位的一位 0或者1 只有两个都为1,结果才为1,其余全为0
0 & 1 = 0 0 & 0 = 0 1 & 0 = 0 1 & 1 = 1
|:只有两位结果全为0,结果才为0 0 | 1 = 1 0 | 0 = 0 1 | 0 = 1 1 | 1 = 1
^:相同为0,不同为1(满足交换律) 0 ^ 1 = 1 0 ^ 0 = 0 1 ^ 0 = 1 1 ^ 1 = 0
^性质:
-
一个数和它自己异或运算的结果:a ^ a = 0
-
0和任何事做异或运算:0 ^ a = a ~:按位取反(包括符号位) ~6 = -7 00000000,00000000,00000000,00000110(补码,正数 原码补码相同) 11111111,11111111,11111111,11111001(~取反) -> 10000000,00000000,00000000,00000111(补码的补码)
数据溢出
//01111111,11111111,11111111,11111111 代表int类型最大正整数值(最高位为符号位)
//0111 1111,1111 1111,1111 1111,1111 1111 为了书写方便,用16进制表示来四位一分
// 7 f f f f f f f
int a = 0x7fffffff; //最大正整数 + 1 -> 负数
System.out.println(a); //2147483647
//0111 1111,1111 1111,1111 1111,1111 1111
// +1
//1000 0000,0000 0000,0000 0000,0000 0000
System.out.println(a + 1);//-2147483648 数据溢出
//10000000,00000000,00000000,00000000 代表int类型最小负数
//1000 0000,0000 0000,0000 0000,0000 0000 为了书写方便,用16进制表示来四位一分
a = 0x80000000;
System.out.println(a);// -2147483648
题目:
-
请按最有效率的方式写出计算2 乘以 8 的结果
-
请自己实现两个整数变量的交换
答案:
1、位运算是最有效率的运算
//2 * 8 = 2 * 2 ^ 3
System.out.println(2 << 3);
2、
//1、第三方变量:常用【代码可读性好】
int a = 10;
int b = 200;
int tmp = a;
a = b;
b = tmp;
System.out.println("a=" + a + " b=" + b);// a=200 b=10
//2、加法方式【不推荐,开发中会被怼】
a = 10;
b = 200;
a = a + b;
b = a - b;//a + b - b = a
a = a - b;//a + b - a = b
System.out.println("a=" + a + " b=" + b);// a=200 b=10
//3、异或位运算方式
a = a ^ b;
b = a ^ b;
a = a ^ b;
三目运算符
格式: 关系表达式 ? 表达式1:表达式2
关系表达式结果为 true 则为表达式1,结果为 false 则为表达式2
int a;
int b;
Scanner sc = new Scanner(System.in);
a = sc.nextInt();
b = sc.nextInt();
String s = a == b ? "两数相等" : "两式不相等";
System.out.println(s);
练习:3数取大
int a;
int b;
int c = 100;
Scanner sc = new Scanner(System.in);
a = sc.nextInt();
b = sc.nextInt();
//两数取大,第三个数和两数中的大者比较,取它们的大者就是最大值
int result = (a > b ? a : b) > c ? (a > b ? a : b) : c;
System.out.println(result);
键盘录入数据
//键盘录入数据必须通过Scanner对象来使用其功能
Scanner sc = new Scanner(System.in);//提示红色错误:Cannot Resolve Symbol 'Scanner' 因为没有导包
//鼠标放在红色字母上按Alt + Enter选择第一个util
Scanner strSc = new Scanner(System.in);
//通过对象使用Scanner的功能接收键盘输入
int i = sc.nextInt();//输入整数 默认以空格分割不同输入
System.out.println(i);
boolean b = sc.nextBoolean();//输入布尔型:true false 默认以空格分割不同输入
System.out.println(b);
//这样会有错
//String s = sc.nextLine();输入字符串 以回车作为数据的分隔符 会读到回车 输出空字符串,如果放第一个就没事
//System.out.println("s="+s);
//改进
String s = strSc.nextLine();//输入字符串 以回车作为数据的分隔符
System.out.println("s="+s);
//用完之后要关闭
sc.close();
//推荐做法,如果既要读取普通数据,也要读取nextLine,用两个Scanner对象
输入顺序及回车空格
int i = sc.nextInt();
boolean b = sc.nextBoolean();
String s = sc.nextLine();
true后 输入回车,s会读到回车 输出空字符串
true后 输入空格正常
回车表示输入的结束,空格不会结束