第2章 变量,类型和运算符
1. 变量
1.1 变量的概念
变量来源于数学,是计算机语言中能储存计算结果或能表示值抽象概念。可以理解为为某块内存起个名字,通过这个名字找到内存中存放的数据。这块内存的名字一般被称为叫变量名。
示例1:存放整数数据的变量
int a = 30;
int: 表示声明了一个可以存放整数的内存
a: 变量名(内存的名字)
=: 赋值,将等号右侧的数据放入左侧。 此处将数字30放入a的内存中
30: 数值
示例2 :计算两个整数的和
int a = 30;
int b = 25;
int c = a + b;
变量在声明时,也可以不赋值
int a;
int x,y,z;
1.2 变量的命名规则
- 不能与已有的变量名重复
- 变量名必须已英文字母或者$开头
- 变量名的其余字符可以是英文,数字,下划线和$,中间不能有空格
- 变量名不能使用Java中的关键字和保留字
java中的两个保留字分别是const和goto
1.3 变量的命名规范
使用的是“驼峰原则”
- 使用英文单词(名词)做为变量名
- 首字母如果是英文,应该是小写字母。比如:name,studentName
- 如果由多个单词组成,第二个单词起,首字母要大写,其余全小写。
- 尽量不要使用无意义的单独字母,如果使用最好写好注释
2. 类型
Java语言是一门强类型的编程语言,声明某个变量时必须指定变量存储类型。
Java中的类型一共有两种
- 基本数据类型(8种)
- 引用数据类型(可以理解为自定义类型 -- 面向对象)
2.1 基本数据类型
分为三大类八种
2.1.1 数值类型
-
整数类型:表述一个整数
Byte与bit及10进制与2进制的转换
类型 | 占用空间 | 位空间 | 取值范围 |
---|---|---|---|
byte | 1Byte | 8bit | [-27,27-1] |
short | 2Byte | 16bit | [-215,215-1] |
int(默认) | 4Byte | 32bit | [-231,231-1] |
long | 8Byte | 64bit | [-263,263-1] |
- 浮点数类型:表述一个浮点数(小数)
float 4Byte
double(默认) 8Byte
示例3: 声明一个浮点数3.14
double d = 3.14;
- 数字进制的转换
-
10进制和2进制的正数之间
10->2 除2取余法
2->10 按位计算求和
参照上方图片理解 -
10进制和2进制的负数之间
反码: 所有位上取反 0->1 1->0
补码: 反码+1
二进制的负数是以它的正数的补码形式存在内存中
10 -> 2比如将-73转换成二进制
求得73的二进制为 01001001 (第一位是符号位)
求得73的二进制的反码 10110110 (第一位是符号位)
求得73的二进制的补码 10110111 (第一位是符号位)
10110111即为-73的二进制表示形式2 -> 10
比如将10110111转换成10进制
二进制减1得到10110110
取反得到01001001
转换为10进制73
原二进制数字的符号位1,为负数,结果为-73 -
10进制和8进制的正数之间
10 -> 8
除8取余法将97(10)转换成8进制数字
97 / 8 = 12 余 1
12 / 8 = 1 余 4
8进制的结果应该是1418 -> 10
位数相加法将174(8)转换成10进制数字
1x82+7x81+4x80 = 64+56+4=124 -
10进制和16进制的正数之间
10 -> 16
除16取余法将794(10)转换成16进制数字
794 / 16 = 49 余 10 (A)
49 / 16 = 3 余 1
16进制的结果应该是31A16 -> 10
位数相加法将2CF(16)转换成10进制数字
2x162+12x161+15x160=512+192+15=719
10进制的结果就是719
- 使用各种进制数值对int型赋值
int a = 30; //10进制赋值
int b = 0b1001; //2进制 以0b开头
int c = 075; //8进制 以0开头
int d = 0xFc21; //16进制 以0x开头
2.1.2 字符类型
char表述一个字符(无论英文,数字 ,汉字,符号都算一个字符)
Java中一个字符使用单引号表示'A','2','好','+'
示例4:声明一个字符‘A’
char c = 'A';
2.1.3 布尔类型
boolean表述逻辑的“真”或“假”
- 真 true
- 假 false
示例5:声明boolean类型的变量
boolean b = true; //表示真
boolean o = false; //表示假
2.1.4 基本数据类型的转换
- 自动转换
规则:
- 范围小的类型向范围大的类型
- 整数向浮点数类型
- char型向int型
- 布尔值不能进行任何的转换
示例6: 自动转换
byte b = 28;
int a = b; //自动转换OK 范围小->范围大
System.out.println(a);
long o = 1222;
float f = o; //自动转换OK 正数->浮点数
System.out.println(f);
char c = '啊';
int x = c; //自动转换OK char -> int
System.out.println(x); //ASC码
- 强制转换
当需要反向类型转换时,需要利用强制转换,强制有可能造成数据的精度丢失。
精度丢失:数据丢失了位数据或者浮点数部分
示例7:强制转换
//强制转换成功
int a = 97;
byte b = (byte) a;
System.out.println(b);
//精度丢失
int x = 200; // 11001000 -> -56
byte y = (byte) x;
System.out.println(y);
//精度丢失
double d = 3.14; //丢失浮点数部分
int z = (int) d;
System.out.println(z);
//int -> char 可以正常转换
int i = 65;
char j = (char)i;
System.out.println(j);
3. 运算符和表达式
3.1 算术运算符
进行四则运算的符号,主要包含的操作是加减乘除和取余。
- +号 表示加法 5+3
- -号 表示减法或者负数 5-3或-5
- *号 表示乘法 5*3或5*x相当于5x (不建议省略*号)
- /号 表示除法 5/2 (除数不能为0的,执行时程序会报错)
整数除法的特点:得到的还是整数 - %号 表示取余 5%2 取余运算的结果和符号问题与MySQL讲解Mod函数的规则是一致的。(正负号与被除数一致)
优先级:乘除和取余的操作优先级高于加减,如果弄不清楚,可以加括号
浮点数的乘法和除法时,会有精度问题
示例1:
double d1 = 10.0;
double d2 = 3.0;
System.out.println(d1/d2);
运算结果是
结尾的5是有问题的
由于浮点数运算可能会有精度问题,尽可能的避免使用浮点数的运算结果做为程序的判断依据。
如果必须浮点数做为程序的判断依据,需要使用高精度浮点数BigDecimal类
//整数与浮点数的运算
int a = 5;
double d = 2.5;
double x1 = a+d;
double x2 = a/d;
System.out.println(a+d);
System.out.println(a/d);
//同类型数据的加法
byte s1 = 35; //35 是 int
short s2 = 37; //37 是 int
int s3 = s1+s2; //s1 + s2 = int
System.out.println(s3);
//溢出 Integer.MAX_VALUE表示int类型的最大值 最大值+1之后变成最小值
int y1 = 1;
int y2 = Integer.MAX_VALUE;
int y3 = y1 + y2;
System.out.println(Integer.MAX_VALUE);
System.out.println(y3);
程序结果
3.2 赋值运算符
对变量进行复制的操作符
- = 赋值 将等号右侧的数据或者变量值赋值给等号左侧
- += 将等号右侧的数据或者变量值以增量的方式赋值给等号左侧
int a = 3;
int b = 5;
b += a; //运算结果相当于 b = b+a;
b结果是8
- -= 将等号右侧的数据或者变量值以增量(减法)的方式赋值给等号左侧
int a = 3;
int b = 5;
b -= a; //运算结果相当于 b = b-a;
b的结果是2
- *= 将等号右侧的数据或者变量值以增量(乘法)的方式赋值给等号左侧
int a = 3;
int b = 5;
b *= a; //运算结果相当于 b = b*a;
b的结果是15
- /= 将等号右侧的数据或者变量值以增量(除法)的方式赋值给等号左侧
int a = 3;
int b = 5;
b /= a; //运算结果相当于 b = b/a;
b的结果是1
- %= 将等号右侧的数据或者变量值以增量(取余)的方式赋值给等号左侧
int a = 3;
int b = 5;
b %= a; //运算结果相当于 b = b%a;
b的结果是2
示例2:以下代码是否有错误
short s = 35;
s = s + 1; //报错, s+1被认为是int类型 不能向short类型直接转换
short s = 35;
s += 1; //OK, +=含有类型转换的功能
3.3 比较运算符
用于对数据进行比较的操作符,它的运算结果是boolean类型
- == 判断两端的数据是否“相等”
int a = 5;
int b = 3;
boolean c = (a == b);
c的结果是false
- != 判断两端的数据是否“不相等”
int a = 5;
int b = 3;
boolean c = (a != b);
c的结果是true
-
和>= 判断左侧是否大于(大于等于)右侧
int a = 5;
int b = 3;
boolean c = (a > b);
c的结果是true
- <和<= 判断左侧是否小于(小于等于)右侧
int a = 5;
int b = 3;
boolean c = (a < b);
c的结果是false
3.4 单目运算符
用于控制整数自增和自减
- ++
用于表示某个整数变量进行自增1的操作
如果++在整数变量的后面,表示变量值先参与表达式运算,再自增1
int i =5 ;
int j = (i++)+(i++);
5 6
j 是 11
如果++在整数变量的前面,表示变量值先自增1,再参与表达式运算
int i = 5;
int j = (++i)+(++i);
6 7
j 是 13
- --
用于表示某个整数进行自减1的操作
为一个变量+1的方法有哪些?
- a = a + 1; 效率最低
- a += 1; 含有类型转换
- a++;或++a; 使用++进行自增1操作是效率最高
推荐++的方式完成变量的自增或自减操作
3.5 逻辑运算符
表示两个逻辑类型(boolean)类型的逻辑操作
- 与 && 如果A&&B 要求必须满足A和B两个条件
- 或 || 如果A||B 至少满足A和B两个条件其一
- 非 ! 如果!A 表示A的逻辑取反
示例3:逻辑运算
int a = 5;
int b = 3;
int c = 2;
boolean x1 = (a > b) && (b > c);
boolean x2 = (a > b) && (b < c);
boolean x3 = (a > b) || (b > c);
boolean x4 = (a > b) || (b < c);
boolean x5 = (a < b) || (b < c);
System.out.println(x1);
System.out.println(x2);
System.out.println(x3);
System.out.println(x4);
System.out.println(x5);
System.out.println("=======================");
boolean x6 = !(a > b);
System.out.println(x6);
运算结果
逻辑运算符存在“短路”现象
&& | true | false |
---|---|---|
true | true | false |
false | false | false |
|| | true | false |
---|---|---|
true | true | true |
false | true | false |
短路产生的原因
短路产生的原因
示例4:短路
int i = 5;
// &&或者|| 与 ++或-- 放在一起 十有八九就是考短路
boolean x = (i++ > 5) && (++i < 6);
//i++ > 5 相当于 5 > 5 false
//x = false (++i < 6)被短路,不会被执行
// i只自增了1次 i的值是6
System.out.println(x);
System.out.println(i);
3.6 位(bit)运算符
- 与 & 两个位上有一个是0,结果就是0
- 或 | 两个位上有一个是1,结果就是1
- 非 ! 0和1互相取反
- 异或 ^ 两个位上数字一致为0,不一致为1
面试题: &与&&的区别? |与||的区别?
答案:&可以进行位运算和逻辑运算,它不是短路的。&&只能进行逻辑运算,它是短路的。
移位运算符
- << 左移 左移几次相当于乘以2的几次幂
- >> 右移 右移几次相当于除以2的几次幂 (符号位不会参与移动)
- >>> 无符号右移 会将符号位数字当做普通数字进行移位
面试题/笔试题:求得2的n次幂最快的方式
利用2<<(n-1)即可求得2的n次幂,或1<<n也可以求得2的n次幂
3.7 三目运算符
由2个符号共同组成的一个含有逻辑的运算
int x = (逻辑运算) ? a : b;
当逻辑运算结果为true时,x=a;
当逻辑运算结果为false时,x=b;
a和b的类型必须与x的类型一致
示例4:判断输入的数据是否是偶数
//允许用户在控制台上输入
Scanner sc = new Scanner(System.in);
System.out.println("请输入数字:");
int i = sc.nextInt();
//判断用户输入的数字是否是偶数 i % 2 == 0
char c = (i % 2 == 0) ? '是' : '否';
System.out.println(c);