a.
常量
就是在程序过程中不可改变的值。
常量的分类:
字面值常量
自定义常量(自己起名字)
字面值常量分类(6种):
1.字符串常量: 被双引号引起来的常量, 如:"abc"和 ""。
2.字符常量: 被单引号引起来的内容,里面只能放单个数字,单个字母,单个符号。
如: '10'不合格,不符合单个数字的规则,只有'1~9'合格。
如: ''也不合格,因为里面什么都没有放,因为代表不了任何字符,
' '合格,因为代表空格字符。
3.小数常量: 所有小数, 如: 1.2
4.整数常量: 所有整数, 如:123
5.布尔常量: 只有true 和 false, 默认false。
6.空常量: null
b.
进制
对于进制,有四种表现形式:
二进制: 0-1 满2进1
八进制: 0-7 满8进1,由0开头表示,如:012
十进制: 0-9 满10进1
十六进制:0-9 A-F 满16进1 有0x开头表示,如:0x4A2C
就是进位制,是人们规定的一种进制方法, 就是对于任何一位的进制--x进制,就表示某一位置上的数运算时,逢x进一位, 二进制就是逢2进1, 八进制就是逢8进1, 十进制就是逢10进1,十六进制就是逢16进1,比如: 一个星期有7天,就是一个星期,逢7进1,就是第二个星期的星期1,七进制。 每年12个月,当第13个月时,就是下一个年份的1月份开始,十二进制。
二进制
八个开关,表示计算机中的最小单位:byte,即一个字节(byte),每个开关表示1一个比特位(bit);
开和关有两种状态,用0和1表示。
即:1byte = 8bit;
1k = 1024byte;
1m = 1024k;
1g = 1024m;
1t = 1024g;
....
计算机中的硬盘结算方法:
比如一个厂家想生产一个500g的硬盘, 以厂商的计算规则都是 *1000,而计算机中的计算规则拿到厂商计算到的结果是 / 1024:
即: 500 = 500 * 1000 * 1000 * 1000 / 1024 /1024 /1024 = 465.661287... 约等于 465g,所以说一个计算机中的硬盘只有465g。
因为这种方式计算繁琐,所以又出现了一种计算方法:
八进制: 每3位为一组。
把 10101010 拆分为3份,前面不足一位用0来补充: 010101010,即三个数字变一位。
010 010 010
x y z
十六进制: 每4位为一组。
1010 1010
a b
规则:进制越大,表现形式越短。
c.
各种进制的表现形式:
二进制:
由0,1组成,0b开头,b(大小写均可),jdk1.7版本后可以表示为二进制。
八进制:
由0~7组成,以0开头。
十进制:
由0~9组成,整数默认都是十进制。
十六进制:
由0~9 ,a~f(大小写均可),以0x开头。
案例演示:
输出不同进制表现100的数据。
二进制: 0b100 结果:4
八进制: 0100 结果:64
十进制: 100 结果:100
十六进制:0x100 结果:256
任意进制到十进制之间的转换
规则:
系数:表示每一位上的数,如:1,2,3,4,5;
基数:x进制,基数就是x,比如8进制转10进制,x就是8。
权: 在最右边,从0开始,对应位上的编号就是该位的权。
结果: 把系数*基数的权次幂相加即可。
n*y^z
十进制到十进制之间的转换:
12345 = 10000 + 2000 + 300 + 40 + 5
= 1*10^4 + 2*10^3+3*10^2+4*10^1+5*10^0
= 10000 + 2000 +300 + 40 + 5
= 12345
例子:
二进制转十进制:
0b100 = 1*2^2 + 0*2^1 + 0*2^0
= 4 + 0 + 0
= 4
八进制转十进制:
0100 = 1*8^2 + 0*8^1 + 0*8^0
= 64 + 0 + 0
= 64
十六进制转十进制:
0x100 = 1*16^2 + 0*16^1 +0*16^0
= 256 + 0 + 0
= 256
十进制转任意进制:
规则:
除积倒去余
十进制转换为十进制(任意进制);
一个十进制的数:12345 转换为十进制,就是除于10,倒着取余数;
例子:
参考图片。
快速的进制转换:
8421码
二进制到八进制的简易方式
60转为八进制:
先将60转换为2进制:111100, 因为八进制是每三位为一组,所以使用8421码的快速转换结果为:
111 100
——— ———
421 4
八进制结果为: 74
二进制到十六进制的简易方式
60转为八进制:
先将60转换为2进制:111100,因为八进制是每四位为一组,所以使用8421码的快速转换结果为,位数不足,用0补齐,最左边补两个0:
0011 1100
———— ————
21 84
十六进制结果为: 3C ,因为84的结果为12,而在十六进制中c代表12, 所以结果为3C
60用快速转换法转换为二进制:
因为快速转换规则是:
八个比特位先用1来代替,每个1都代表一个数字,当该位上的数字不满足时,用0表示。
【【【【【【【【【【【【【【【【【【【【【【【【【【【
1 1 1 1 1 1 1 1
128 64 32 16 8 4 2 1
】】】】】】】】】】】】】】】】】】】】】】】】】】】】
所以60的二进制快速转换结果为:
0 0 1 1 1 1 0 0 也可以是: 111100 因为左边的0可以省略
100用快速转换法转换为二进制:
0 1 1 0 0 1 0 0 也可以是: 1100100 因为左边的0可以省略
72用快速转换法转换为二进制:
0 1 0 0 1 0 0 0 也可以是: 1001000
d.
原码, 反码, 补码
原码:
是二进制的定位表示法, 即最高位为符合位,“0”表示正,“1”表示负,其他位表示数值的大小。,
反码:
正数的反码与原码相同, 负数的反码是对原码符号位除外,原码逐位取反。
补码:
正数的补码与原码相同, 负数的补码是在反码的末位加1。
计算机运算时都是以补码的方式运算的。
口诀:
正数的原反补都是本身,负数的补码是在反码的末位加1,负数的反码是符号位不变,原码逐位取反。
反码的出现,就是为了求补码,从反码推出补码。
例子:
反码
0 0000111 +7(反码) 因为正数的原反补相同,所以还是其原码,也就是反码。
1 0000111 -7(原码)
1 1111000 -7(反码) 负数的反码是对原码符号位不变,原码逐位取反。
补码
0 0000111 +7(补码)
1 1111000 -7(反码)
1 1111001 -7(补码)
因为计算机都是通过补码来运算的,且采用的二进制(逢2进1)的方式来计算的,所以:
0 0000111 +7(补码)
+1 1111001 -7(补码)
——————————————————————
10 0000000 因为每8个比特位是一个字节,所以1不要,结果就是0。
案例:
A:已知原码求补码
* 0b10110100
因为补码是通过反码推出来的,所以先求其反码。
0b 1 0110100 (该原码是一个负数的二进制)
0b 1 1001011 (反码) 负数的反码是对原码符号位除外,原码逐位取反。
0b 1 1001100 (补码)
1 1001011
0 0000001(+1的动作)
___________
1 1001100
B:已知补码求原码
* 0b11101110
因为0b11101110 是一个负数的补码,
0 0000001(-1的动作)
---------------------
11101101(反码)
10010010(原码)
e.
变量
在程序执行过程中,某个范围可以改变的值。
内存中的一个存储区域,该区域有注解的名称(变量名)和类型(数据类型),该区域的数据可以在同一个类型范围内不断的变化。
特点
变量其实就是将不确定的数据进行存储,也就是需要在内存中开辟一个空间。
变量名
合法的标识符。
变量值
给变量赋予的值。
变量格式:
数据类型 变量名 = 变量值。
int num = 7;
作用:
用来不断存放用一种数据类型的常量, 并且可以重复使用。
f.
数据类型
java属于强类型语言,所以对于每一种数据都定义了明确的数据类型。并且在内存中也分配了不同的大小的内存空间。
java中数据类型的分类:
基本数据类型
引用数据类型(到面向对象再说):String, class, interface, 数组等。
基本数据类型(4类8种):
整数型:
byte 占1个字节,即8个比特位, 取值范围 【-128~127】 他的范围要记住。 ( -128~127 )
short 占2个字节, 取值范围 -2^15~2^15-1 (-32768~32768)
int 占4个字节, 取值范围 -2^31~2^31-1 (-2147483647~2147483647)
long 占8个字节, 取值范围 -2^63~1^63-1 (-9223372036854775808~9223372036854775808)
p.s. 整数默认 int
【【(这样记: byte short int long 分别是 1,2,4,8个字节,跟进制的快速运算法8421码刚好反过来)】】
浮点型:
float 占4个字节 (32位)的内存空间 且是单精度浮点数。 (取值范围-3.403E38~3.403E38)
double 占8个字节,(64位)的内存空间,且是双精度浮点数。 (取值范围-1.798E308~1.798E308)
p.s. 浮点型默认 double (double类型的小数的精确度被float类型的小数更高)
字符型:
char 占2个字节 【0~65535】 他的范围要记住。 (取值范围0~65535) 默认值:空字符,即 '\u0000'
布尔型:
boolean
理论上占8分之1个字节,因为一个开关不是false(默认)就是true,但是在java中没有明确指出他的大小。
例子:
整数类型:
1.
long x = 77777777,因为会将77777777编译【成默认类型int】,但是非要指定该值是long类型,所以就必须明确指出该值是long类型,在该值后面加L:
long x = 77777777L(加一个L,大小写都可)
2.
System.out.println(12345+54321); 说出结果?
结果为:66666,这里的“+”号,是运算的意思, 因为该值是没有被双引号引起来。
。如果是:System.out.printl("12345+12345");的话,结果是 12345+12345,因为被双引号引起来的内容不做处理。
浮点类型:
float f = 12.3 编译不通过, 因为默认的浮点类型是double, 大(double)的数据类型往小(float)的数据类型中放,会损失精度,所以要明确该float类型,所以要在该值后面加f,即,float f = 12.3f;
【记住: 大(默认double)的数据类型想要小(float)的数据类型中放,会损失精度,所以要明确指出float类型,在float值的后面加f/F】
float c = 1;
System.out.println(c); 结果: 1.0
float f = 12.4;
System.out.println(f); 结果: 编译不通过,必须在12.4后面加f才能编译通过。
【当float类型的值是小数时,必须要加f,整数可加,可不加】
字符型:
用单引号引起来的单个数字,字母,符号。
char r = '%#';
System.out.println(r); 不合格
char r = '%';
System.out.println(r); 合格
char r = '23';
System.out.println(r); 不合格
char r = '3';
System.out.println(r); 合格
char r = 'sd';
System.out.println(r); 不合格
char r = 'd';
System.out.println(r); 合格
布尔型:
默认false
变量的注意事项:
在同一个区域{}内不能使用同一个变量名。
初始化问题:
局部变量必须先赋值后使用。
一个语句可以有多个变量:
int a,b,c...
数据类型的隐式转换:
如:
int a = 1;
byte b = 2;
a = a + b;
System.out.println(a); 结果3;
分析:
首先b是byte类型,即占1个字节,也就是1个8的比特位,即: 00000010
a是int类型,即占4个字节,也就是4个8的比特位,即:00000000 00000000 00000000 00000001
因为byte是小的数据类型,而int是大的数据类型,因为最终a = a + b,所以要将小的数据类型提升为大的数据类型。
即 byte b =2, 就变成了 00000000 00000000 00000000 00000010
所以a = a + b结果就是:
a: 00000000 00000000 00000000 0 0000001
b: 00000000 00000000 00000000 0 0000010
——————————————————————————————————————
a: 00000000 00000000 00000000 0 0000011
结果就是:3
数据类型的强制转换:
如:
int a = 3;
byte b = 4;
//b = a + b; 因为左边的b是最终的数据类型即小的数据类型,所以在使用时,必须要将右边都变成小的小的数据类型,所以要强转:b = (byte)(a+b)。
//System.out.println(b); 编译错误。
b = (byte)(a + b); //因为最终b(小的数据类型)来接收结果,所以将(a+b)先给括起来,前面用一个(byte)强制转换符,你想转换为什么类型,就加什么强制转换符,即byte。
System.out.println(b);
【【大int[4个字节]的能往小byte[1个字节]的里放,而小byte[1个字节的不能往大int[4个字节]的里放,如果要发,需要将小变成和大的一样才能放,这就需要强制类型转换】】
分析:
首先b是byte类型,即占1个字节,也就是1个8的比特位,即: 00000100,
因为a是int类型,即占4个字节,也就是4个8的比特位,即:00000000 00000000 00000000 00000011
又因为 a + b 是int类型的a和byte类型的b相加,所以要先将b提升为int类型,即:00000000 00000000 00000000 00000100
要得出(a+b)的结果,那么就是:00000000 00000000 00000000 00000111
因为最终是用byte的b来接受结果的,且这个结果同时在int和byte的取值范围,所以将00000000 00000000 00000000 00000111的前三个8的比特位给砍掉,即:00000111,这样将3个8的比特位给砍掉的过程,就是强制类型转换的过程,结果是:7,但这样做会损失精度。
强制类型的注意事项:
如果超出了被赋值的数据类型的取值范围,那么最终得到的结果就会与你期望的结果不同。
因为砍掉的那3个8的比特位中还有结果,所以
如:
1.
byte b = 125 + 5; //超出byte的取值范围了,即byte的取值范围是-128~127
System.out.println(b); //编译不通过,
分析:
因为125+5是一个int结果的130,赋值不了给byte的b,因为byte的取值范围是-128~127。
但是呢,可以将125+5 扩起来,通过强制类型转换(byte)(125+5) ,再赋值给b,但是呢结果不是130,而是130的二进制,但结果是-126的反码,因为-126是补码,所以要求出原码,原码的推出规则是,先求补码,即需要在末位-1,
130的二进制是: 00000000 00000000 00000000 1 0000010
减1: 00000000 00000000 00000000 0 0000001 (-1求反码)
___________________________________________________
1 0000001 (-126的补码)
反码: 符号位不变,其他位逐位取反,即-126: 1 1111110 (-126的原码) 最前面的1表示符号位,1表示负数。
2.
byte b2 = (byte)300; //该结果值不正确,因为已经损失了精度。
System.out.println(b);
// 300的二进制为:00000000 0000000 00000001 00101100
// 因为b2是byte类型,所以要砍掉前3个8位:结果为:00101100,也就是44
// 16+8+4 =44
//所以说【向下强转会损失精度,且该值不是我们想要的。】
3.
byte b3 = (byte)315;
System.out.println(b3); //该结果值不正确,因为已经损失了精度。
// 315的二进制为: 00000000 0000000 00000001 00111011
// 因为b3是byte类型,所以要砍掉前3个8位:结果为: 00111011,也就是:59
// 32+16+8+2+1 = 59【所以向下强转会损失精度,而且改值也与自己期望的值不同】
p.s.
显示类型转换和强转类型转换的要点:
要看最终接受的那个值的类型,
如果是 大 = 大+小,就无需强转类型转换,
如果是 小 = 大+小,就必须强转类型转换,即最终为: 小 = (小)(大+小);
例子:
* 面试题:看下面的程序是否有问题,如果有问题,请指出并说明理由。
* byte b1 = 3;
* byte b2 = 4;
* byte b3 = b1 + b2;
有两个方面的问题,
编译不通过。
1)b1,b2两个byte类型的值在参与运算时,会直接提升为int类型(因为整数类型默认就是int类型),b3是byte类型,所以int类型的值赋值给b3会损失精度。
【byte和short,char分别参与运算时,都会先提升为int类型后,才参与运算。因为byte(1个字节),short(2个字节),char(2个字节)的取值范围都没有int(4个字节)大】
2)b1和b2都是变量,变量存储的值都是会变化的,所以在编译时jvm时无法判断里面具体的值,同样b1+b2的值可以会超出byte的取值范围。
* byte b4 = 3 + 4;
运行通过。
因为java编译器有常量优化机制,就是说在编译时直接算出了3+4的结果,而且判断了该值是否超出了byte的取值范围,结果是7没有超出byte(-128~127)的取之范围。
基本数据类型的取值范围(谁大谁小)
在参与混合运算时,byte,short,charb不会相互转化,而是自动提升为int类型,其他数据类型进行混合运算时,小的数据类型会提升为大的数据类型,才能运算。
运算大小范围:
byte,short,char -- int -- long -- float -- double
问?
float(4个字节)的取值范围要比long(8个字节)要小,但是在运算时为什么float比long大?
* 两个类型的底层存储结构不同。
long :2^63-1
float:2*2^114
所以long < float
int a=10;
byte b=20;
a = b; //小的可以直接放大里放, 这种情况叫:基本数据类型的自动类型提升。
b = a; //大的给小的,会损失进度,必须强转,即 b=(byte)(a);
例子说明:
float x = 12.3f;
long l = 12345;
//x = l; // 12345.0 因为小的long可以给大的float 隐式转换 byte,short,char -- int -- long -- float -- double
//System.out.println(x);
//l =x;
//System.out.println(l); // 编译通过,运行不通过,因为x是float类型,大(float)的不能给小(long)的,需要将float强制为long类型。
l = (long)x;
System.out.println(l); //12 将小数点后面的数给砍掉了。
g.
字符和字符串参与运算;
任意数据类型的与字符串紧挨着混合运算时,都会变成一个新的字符串。
例子+详解:
1) System.out.println('a'); //a 因为只是单个字符,所以直接输出a。
2) System.out.println('a'+1); //98 因为1是int(默认类型)类型,'a'是字符,当字符与int类型的值参与混合相加时,a字符就会被提升成int类型,而字符'a'在ASCII码表中对应的ASCII是97,所以97+1就是98。
了解:计算机中只识别0和1,但是后期为了方便就将字母和数字分别用二进制表示,而且有了一一对应的关系,这种关系被定义为了:ASCII码表。
3)System.out.println("hello"+'a'+1); //helloa1 因为前者hello是字符串,当字符串与任意数据类型混合运算时都会变成一个新的字符串,即:"helloa",而 "helloa"又是一个新的字符串,与1混合运算时,变成了最终的"helloa1"
4) System.out.println("hello"+'a'+'a'); //helloaa 前者字符串跟后者字符混合运算,变成一个新的字符串,而这个新的字符串"helloa"和后者字符混合运算,变成最终字符串"helloaa"
5) System.out.println('a'+"hello"+97); //ahello97
6) System.out.println('a'+"hello"+5+5); //ahello55 前者字符与后者字符串相加变成一个新的字符串,而新的字符串"ahello"与5相加,又变成一个新的字符串,而新的字符串"ahello5"与5混合运算,变成最终字符串"ahello55"
7) System.out.println('a'+1+"hello"); //98hello 根据从左到右运算的原则,字符a与1相加,a就提升为int类型,与1参与运算,变成98,98与字符串hello混合运算,变成最终结果:98hello
8)System.out.println("5+5="+5+5); //5+5=55 //首先字符串中的数据不变,即5+5=,这个字符串"/5+5="与5混合运算变成新字符串:"5+5=5",而这个新字符串与最后一个5参与运算,就变成了5+5=55
9) System.out.println("5+5="+(5+5)); //5+5=10 因为小括号将后面5+5的运算结果扩起来了,所以在java中括号有提升运算的优先级,所以字符串中的不做改变,即5+5=与后面的10混合运算就变成了:5+5=10
10) System.out.println(5+5+"=5+5"); 10="5+5" 因为前者5+5是int类型的值相加运算结果为10与后面的字符串"=5+5",变成最终结果的字符串:10=5+5
h.
char类型
char的特殊性:当char赋值【数字】时无需用单引号扩起来,结果是ASCII中的结果。如果用单引号引起来了该结果不变, 且他的取值范围0~65535之间的,且在127(ASCII中最大的就是127所对应的值)之下的,都能够翻译成ASCII中所对应的字符。
如:
char c=98;
//System.out.println("c"); //b ASCII对应的值。
char h4=4;
System.out.println(h4); //"方片" ASCII对应的值。
//char c2 = a;
//System.out.println(c2); //编译错误,必须单引号引起来。
//char ar4 = -97;
//System.out.println(ar4); //编译不通过 因为-97没有在char的取值范围内。
byte te = 97;
System.out.println(te); //97 因为在byte的取值范围
char ar5 = 128;
System.out.println(ar5); //? ar5为什么要赋值128呢?因为对应着ASCII码表中的最大127,所以想看看128所对应的值。
char ar6 = 129;
System.out.println(ar6); //? ar6为什么要赋值129呢?因为对应着ASCII码表中的最大127,所以想看看128所对应的值。
char ar7 = 63;
System.out.println(ar7); //? 63是正常的ASCII码表中的值。
byte te = 97;
System.out.println(te); //97 因为在byte的取值范围
char r1= 3; //红心 在char的取值范围内,且又对应ASCII码表中的值。
char r2= 4; //方片
char r3= 5; //梅花
char r4= 6; //桃花
System.out.println(r1+" "+r2+" "+r3+" "+r4+" ");
char h3 = '^';
System.out.println(h3); //^
char h5 = '4';
System.out.println(h5); //4
char h4 = (char)(-4);
System.out.println(h4);// ? 编译不通过 h6为什么要赋值-4呢?因为对应着ASCII码表中的最大127,所以想看看128所对应的值。
//char类型是否可以存储中文?
char h = '文';
System.out.println(h); //文 可以存储中文,但是只能是一个中文,因为java采用的Unicode编码,该编码中每个字符占用两个字节,而中文也是占用2个字节的。
i.
运算符
对常量和变量进行操作的符号。
分类(6种):
算术运算符,赋值运算符,比较(关系条件)运算符,逻辑运算符,位运算符,三元运算符。
算术运算符:
+ - * / %(取磨[余数]) ++ --
注意事项:
1) +: 在java中有三个作用,a.表示正号 b.字符串的连接符 c.做加法运算。
2) 整数相除只能是整数,如果想得到小数,需将其中一个变成小数,另外一个会自动类型提升。
3) /是除法后的商,%是除法后的余数。
%运算符:
当左边的绝对值小于右边的绝对值,结果是左边。
当左边的绝对值大于右边的绝对值,结果是余数。
%运算符结果的符号只和左边有关系,与右边无关。
【当左边的绝对值等于右边或右边的倍数,结果是0。】
【任何一个整数%2结果不是0就是1,可以当以后的判断条件。】 【只要是基数%2,都是1。偶数%2,都是0】
例子:
整数相除只能是整数
System.out.println(15/5); //3
如果想得到小数,需将其中一个变成小数,另外一个会自动类型提升
System.out.println(15.0/7); //2.142857142857143
当左边的绝对值小于右边的绝对值,结果是左边
System.out.println(3%5); //3
System.out.println(2%5); //2
System.out.println(-2%5); //-2
当左边的绝对值大于右边的绝对值,结果是余数
System.out.println(-12%5); //-2
当左边的绝对值等于右边或右边的倍数,结果是0
System.out.println(-15%5); //0
System.out.println(-10%5); //0
System.out.println(15%5); //0
任何一个整数%2结果不是0就是1,可以当以后的判断条件【只要是基数%2,都是1。偶数%2,都是0】
System.out.println(0%2); //0
System.out.println(3%2); //1
System.out.println(2%2); //0
%运算符结果的符号只和左边有关系,与右边无关
System.out.println(-1%3);//-1
System.out.println(1%3);//1
System.out.println(1%-3);//1
j.
++和--
单独使用:
放在操作数的前面后或后面结果都是一样的,都是做加1或减1操作。
参与运算使用:
放在操作数的后面,先参与运算(就是先将值取出做赋值操作),后自身加1或自身减1。
放在操作数的前面,先自身加1或自身减1,然后将结果赋值 【后参与运算(就是讲值取出做赋值操作)】。
例子:
放在操作数的前面后或后面结果都是一样的,都是做加1或减1操作。
int a = 3;
a++;
System.out.println(a); //4
int b = 4;
++b;
System.out.println(b); //5
int c = 2;
--c;
System.out.println(c); //1
int d = 7;
d--;
System.out.println(d); //6
放在操作数的后面,先参与运算(就是先将值取出做赋值操作),后自身加1或自身减1。
int a2 = 3;
int b2=a2++;
System.out.println(b2); //3
System.out.println(a2); //4
int c2 = 5;
int d2 = c2--;
System.out.println(c2); //4
System.out.println(d2); //5
放在操作数的前面,先自身加1或自身减1,然后将结果赋值 【后参与运算(就是讲值取出做赋值操作)】。
int e = 9;
int f = --e;
System.out.println(e); //8
System.out.println(f); //8
int e2 = 12;
int f2 = ++e2;
System.out.println(e2); //13
System.out.println(f2); //13
面试题1
请分别计算出a,b,c的值?
int a = 10;
int b = 10;
int c = 10;
a = b++; // a=10,b=11;
c = --a; // a=9,c=9;
b = ++a; // a=10,b=10;
a = c--; // c=8,a=9;
System.out.println(a); //a=9
System.out.println(b); //b=10
System.out.println(c); //c=8
int e = 7;
int f = 7;
int g = 7;
e = f++; //e=7,f=8
g = --e; //e=6,g=6
f = ++e; //e=7,f=7
e = g--; //e=6,g=5
System.out.println(e); //6
System.out.println(f); //7
System.out.println(g); //5
面试题2
//请分别计算出x,y的值?
int x = 4;
int y = (x++)+(++x)+(x*10);
// 4 6 6*10
// y=70
int x2 = 6;
int y2 = (++x2)+(x2++)+(x2*5);
//7 + 7 + 8*5;
// y2 =54
System.out.println("y2 = "+y2); //54
int x3 = 3;
int y3 = (x3--)+(--x3)-(x3++)+(--x3)+5+(--x3);
// 3 + 1-1+1+5+0
// y3=9,x3=0;
System.out.println("x3 = "+ x3 +"y3 = "+y3); //9
面试题3
//问哪句会报错,为什么
byte b = 10;
b++; // 相当于 b = (byte)(b+1),不会报错。
b = b + 1; //会出错,因为 b+1,1是int类型,b和1参与运算,b也会自动提升为int类型,但是byte的b来接受的,所以
//要将(b+1)强制转换为byte类型,即:byte b = (byte)(b+1)才行。
k.
赋值运算符
分为两种:
基本的赋值运算符: =
扩展的赋值运算符 +=, -=, *=, /=, %=
面试题1
看下面的程序是否有问题,如果有问题,请指出并说明理由。
short s=1;s = s+1; //s=1没有问题,s=s+1有问题,因为s+1中的1是int类型,当short类型的s与int类型参与混合运算时,会将short提升为int类型, 但赋值的s是short类型,两个int类型的值的和赋值给short会损失精度。
short s=1;s+=1; //s=1没有错误,s+=1 相当于 s=(short)(s+1),底层做了自动类型转换 ,所以不会报错。
l.
关系运算符
==, !=, >, >=, <, =<
无论最终结果是什么,都是Boolean类型。
不能将 '==' 写成 '='
常量
就是在程序过程中不可改变的值。
常量的分类:
字面值常量
自定义常量(自己起名字)
字面值常量分类(6种):
1.字符串常量: 被双引号引起来的常量, 如:"abc"和 ""。
2.字符常量: 被单引号引起来的内容,里面只能放单个数字,单个字母,单个符号。
如: '10'不合格,不符合单个数字的规则,只有'1~9'合格。
如: ''也不合格,因为里面什么都没有放,因为代表不了任何字符,
' '合格,因为代表空格字符。
3.小数常量: 所有小数, 如: 1.2
4.整数常量: 所有整数, 如:123
5.布尔常量: 只有true 和 false, 默认false。
6.空常量: null
b.
进制
对于进制,有四种表现形式:
二进制: 0-1 满2进1
八进制: 0-7 满8进1,由0开头表示,如:012
十进制: 0-9 满10进1
十六进制:0-9 A-F 满16进1 有0x开头表示,如:0x4A2C
就是进位制,是人们规定的一种进制方法, 就是对于任何一位的进制--x进制,就表示某一位置上的数运算时,逢x进一位, 二进制就是逢2进1, 八进制就是逢8进1, 十进制就是逢10进1,十六进制就是逢16进1,比如: 一个星期有7天,就是一个星期,逢7进1,就是第二个星期的星期1,七进制。 每年12个月,当第13个月时,就是下一个年份的1月份开始,十二进制。
二进制
八个开关,表示计算机中的最小单位:byte,即一个字节(byte),每个开关表示1一个比特位(bit);
开和关有两种状态,用0和1表示。
即:1byte = 8bit;
1k = 1024byte;
1m = 1024k;
1g = 1024m;
1t = 1024g;
....
计算机中的硬盘结算方法:
比如一个厂家想生产一个500g的硬盘, 以厂商的计算规则都是 *1000,而计算机中的计算规则拿到厂商计算到的结果是 / 1024:
即: 500 = 500 * 1000 * 1000 * 1000 / 1024 /1024 /1024 = 465.661287... 约等于 465g,所以说一个计算机中的硬盘只有465g。
因为这种方式计算繁琐,所以又出现了一种计算方法:
八进制: 每3位为一组。
把 10101010 拆分为3份,前面不足一位用0来补充: 010101010,即三个数字变一位。
010 010 010
x y z
十六进制: 每4位为一组。
1010 1010
a b
规则:进制越大,表现形式越短。
c.
各种进制的表现形式:
二进制:
由0,1组成,0b开头,b(大小写均可),jdk1.7版本后可以表示为二进制。
八进制:
由0~7组成,以0开头。
十进制:
由0~9组成,整数默认都是十进制。
十六进制:
由0~9 ,a~f(大小写均可),以0x开头。
案例演示:
输出不同进制表现100的数据。
二进制: 0b100 结果:4
八进制: 0100 结果:64
十进制: 100 结果:100
十六进制:0x100 结果:256
任意进制到十进制之间的转换
规则:
系数:表示每一位上的数,如:1,2,3,4,5;
基数:x进制,基数就是x,比如8进制转10进制,x就是8。
权: 在最右边,从0开始,对应位上的编号就是该位的权。
结果: 把系数*基数的权次幂相加即可。
n*y^z
十进制到十进制之间的转换:
12345 = 10000 + 2000 + 300 + 40 + 5
= 1*10^4 + 2*10^3+3*10^2+4*10^1+5*10^0
= 10000 + 2000 +300 + 40 + 5
= 12345
例子:
二进制转十进制:
0b100 = 1*2^2 + 0*2^1 + 0*2^0
= 4 + 0 + 0
= 4
八进制转十进制:
0100 = 1*8^2 + 0*8^1 + 0*8^0
= 64 + 0 + 0
= 64
十六进制转十进制:
0x100 = 1*16^2 + 0*16^1 +0*16^0
= 256 + 0 + 0
= 256
十进制转任意进制:
规则:
除积倒去余
十进制转换为十进制(任意进制);
一个十进制的数:12345 转换为十进制,就是除于10,倒着取余数;
例子:
参考图片。
快速的进制转换:
8421码
二进制到八进制的简易方式
60转为八进制:
先将60转换为2进制:111100, 因为八进制是每三位为一组,所以使用8421码的快速转换结果为:
111 100
——— ———
421 4
八进制结果为: 74
二进制到十六进制的简易方式
60转为八进制:
先将60转换为2进制:111100,因为八进制是每四位为一组,所以使用8421码的快速转换结果为,位数不足,用0补齐,最左边补两个0:
0011 1100
———— ————
21 84
十六进制结果为: 3C ,因为84的结果为12,而在十六进制中c代表12, 所以结果为3C
60用快速转换法转换为二进制:
因为快速转换规则是:
八个比特位先用1来代替,每个1都代表一个数字,当该位上的数字不满足时,用0表示。
【【【【【【【【【【【【【【【【【【【【【【【【【【【
1 1 1 1 1 1 1 1
128 64 32 16 8 4 2 1
】】】】】】】】】】】】】】】】】】】】】】】】】】】】
所以60的二进制快速转换结果为:
0 0 1 1 1 1 0 0 也可以是: 111100 因为左边的0可以省略
100用快速转换法转换为二进制:
0 1 1 0 0 1 0 0 也可以是: 1100100 因为左边的0可以省略
72用快速转换法转换为二进制:
0 1 0 0 1 0 0 0 也可以是: 1001000
d.
原码, 反码, 补码
原码:
是二进制的定位表示法, 即最高位为符合位,“0”表示正,“1”表示负,其他位表示数值的大小。,
反码:
正数的反码与原码相同, 负数的反码是对原码符号位除外,原码逐位取反。
补码:
正数的补码与原码相同, 负数的补码是在反码的末位加1。
计算机运算时都是以补码的方式运算的。
口诀:
正数的原反补都是本身,负数的补码是在反码的末位加1,负数的反码是符号位不变,原码逐位取反。
反码的出现,就是为了求补码,从反码推出补码。
例子:
反码
0 0000111 +7(反码) 因为正数的原反补相同,所以还是其原码,也就是反码。
1 0000111 -7(原码)
1 1111000 -7(反码) 负数的反码是对原码符号位不变,原码逐位取反。
补码
0 0000111 +7(补码)
1 1111000 -7(反码)
1 1111001 -7(补码)
因为计算机都是通过补码来运算的,且采用的二进制(逢2进1)的方式来计算的,所以:
0 0000111 +7(补码)
+1 1111001 -7(补码)
——————————————————————
10 0000000 因为每8个比特位是一个字节,所以1不要,结果就是0。
案例:
A:已知原码求补码
* 0b10110100
因为补码是通过反码推出来的,所以先求其反码。
0b 1 0110100 (该原码是一个负数的二进制)
0b 1 1001011 (反码) 负数的反码是对原码符号位除外,原码逐位取反。
0b 1 1001100 (补码)
1 1001011
0 0000001(+1的动作)
___________
1 1001100
B:已知补码求原码
* 0b11101110
因为0b11101110 是一个负数的补码,
0 0000001(-1的动作)
---------------------
11101101(反码)
10010010(原码)
e.
变量
在程序执行过程中,某个范围可以改变的值。
内存中的一个存储区域,该区域有注解的名称(变量名)和类型(数据类型),该区域的数据可以在同一个类型范围内不断的变化。
特点
变量其实就是将不确定的数据进行存储,也就是需要在内存中开辟一个空间。
变量名
合法的标识符。
变量值
给变量赋予的值。
变量格式:
数据类型 变量名 = 变量值。
int num = 7;
作用:
用来不断存放用一种数据类型的常量, 并且可以重复使用。
f.
数据类型
java属于强类型语言,所以对于每一种数据都定义了明确的数据类型。并且在内存中也分配了不同的大小的内存空间。
java中数据类型的分类:
基本数据类型
引用数据类型(到面向对象再说):String, class, interface, 数组等。
基本数据类型(4类8种):
整数型:
byte 占1个字节,即8个比特位, 取值范围 【-128~127】 他的范围要记住。 ( -128~127 )
short 占2个字节, 取值范围 -2^15~2^15-1 (-32768~32768)
int 占4个字节, 取值范围 -2^31~2^31-1 (-2147483647~2147483647)
long 占8个字节, 取值范围 -2^63~1^63-1 (-9223372036854775808~9223372036854775808)
p.s. 整数默认 int
【【(这样记: byte short int long 分别是 1,2,4,8个字节,跟进制的快速运算法8421码刚好反过来)】】
浮点型:
float 占4个字节 (32位)的内存空间 且是单精度浮点数。 (取值范围-3.403E38~3.403E38)
double 占8个字节,(64位)的内存空间,且是双精度浮点数。 (取值范围-1.798E308~1.798E308)
p.s. 浮点型默认 double (double类型的小数的精确度被float类型的小数更高)
字符型:
char 占2个字节 【0~65535】 他的范围要记住。 (取值范围0~65535) 默认值:空字符,即 '\u0000'
布尔型:
boolean
理论上占8分之1个字节,因为一个开关不是false(默认)就是true,但是在java中没有明确指出他的大小。
例子:
整数类型:
1.
long x = 77777777,因为会将77777777编译【成默认类型int】,但是非要指定该值是long类型,所以就必须明确指出该值是long类型,在该值后面加L:
long x = 77777777L(加一个L,大小写都可)
2.
System.out.println(12345+54321); 说出结果?
结果为:66666,这里的“+”号,是运算的意思, 因为该值是没有被双引号引起来。
。如果是:System.out.printl("12345+12345");的话,结果是 12345+12345,因为被双引号引起来的内容不做处理。
浮点类型:
float f = 12.3 编译不通过, 因为默认的浮点类型是double, 大(double)的数据类型往小(float)的数据类型中放,会损失精度,所以要明确该float类型,所以要在该值后面加f,即,float f = 12.3f;
【记住: 大(默认double)的数据类型想要小(float)的数据类型中放,会损失精度,所以要明确指出float类型,在float值的后面加f/F】
float c = 1;
System.out.println(c); 结果: 1.0
float f = 12.4;
System.out.println(f); 结果: 编译不通过,必须在12.4后面加f才能编译通过。
【当float类型的值是小数时,必须要加f,整数可加,可不加】
字符型:
用单引号引起来的单个数字,字母,符号。
char r = '%#';
System.out.println(r); 不合格
char r = '%';
System.out.println(r); 合格
char r = '23';
System.out.println(r); 不合格
char r = '3';
System.out.println(r); 合格
char r = 'sd';
System.out.println(r); 不合格
char r = 'd';
System.out.println(r); 合格
布尔型:
默认false
变量的注意事项:
在同一个区域{}内不能使用同一个变量名。
初始化问题:
局部变量必须先赋值后使用。
一个语句可以有多个变量:
int a,b,c...
数据类型的隐式转换:
如:
int a = 1;
byte b = 2;
a = a + b;
System.out.println(a); 结果3;
分析:
首先b是byte类型,即占1个字节,也就是1个8的比特位,即: 00000010
a是int类型,即占4个字节,也就是4个8的比特位,即:00000000 00000000 00000000 00000001
因为byte是小的数据类型,而int是大的数据类型,因为最终a = a + b,所以要将小的数据类型提升为大的数据类型。
即 byte b =2, 就变成了 00000000 00000000 00000000 00000010
所以a = a + b结果就是:
a: 00000000 00000000 00000000 0 0000001
b: 00000000 00000000 00000000 0 0000010
——————————————————————————————————————
a: 00000000 00000000 00000000 0 0000011
结果就是:3
数据类型的强制转换:
如:
int a = 3;
byte b = 4;
//b = a + b; 因为左边的b是最终的数据类型即小的数据类型,所以在使用时,必须要将右边都变成小的小的数据类型,所以要强转:b = (byte)(a+b)。
//System.out.println(b); 编译错误。
b = (byte)(a + b); //因为最终b(小的数据类型)来接收结果,所以将(a+b)先给括起来,前面用一个(byte)强制转换符,你想转换为什么类型,就加什么强制转换符,即byte。
System.out.println(b);
【【大int[4个字节]的能往小byte[1个字节]的里放,而小byte[1个字节的不能往大int[4个字节]的里放,如果要发,需要将小变成和大的一样才能放,这就需要强制类型转换】】
分析:
首先b是byte类型,即占1个字节,也就是1个8的比特位,即: 00000100,
因为a是int类型,即占4个字节,也就是4个8的比特位,即:00000000 00000000 00000000 00000011
又因为 a + b 是int类型的a和byte类型的b相加,所以要先将b提升为int类型,即:00000000 00000000 00000000 00000100
要得出(a+b)的结果,那么就是:00000000 00000000 00000000 00000111
因为最终是用byte的b来接受结果的,且这个结果同时在int和byte的取值范围,所以将00000000 00000000 00000000 00000111的前三个8的比特位给砍掉,即:00000111,这样将3个8的比特位给砍掉的过程,就是强制类型转换的过程,结果是:7,但这样做会损失精度。
强制类型的注意事项:
如果超出了被赋值的数据类型的取值范围,那么最终得到的结果就会与你期望的结果不同。
因为砍掉的那3个8的比特位中还有结果,所以
如:
1.
byte b = 125 + 5; //超出byte的取值范围了,即byte的取值范围是-128~127
System.out.println(b); //编译不通过,
分析:
因为125+5是一个int结果的130,赋值不了给byte的b,因为byte的取值范围是-128~127。
但是呢,可以将125+5 扩起来,通过强制类型转换(byte)(125+5) ,再赋值给b,但是呢结果不是130,而是130的二进制,但结果是-126的反码,因为-126是补码,所以要求出原码,原码的推出规则是,先求补码,即需要在末位-1,
130的二进制是: 00000000 00000000 00000000 1 0000010
减1: 00000000 00000000 00000000 0 0000001 (-1求反码)
___________________________________________________
1 0000001 (-126的补码)
反码: 符号位不变,其他位逐位取反,即-126: 1 1111110 (-126的原码) 最前面的1表示符号位,1表示负数。
2.
byte b2 = (byte)300; //该结果值不正确,因为已经损失了精度。
System.out.println(b);
// 300的二进制为:00000000 0000000 00000001 00101100
// 因为b2是byte类型,所以要砍掉前3个8位:结果为:00101100,也就是44
// 16+8+4 =44
//所以说【向下强转会损失精度,且该值不是我们想要的。】
3.
byte b3 = (byte)315;
System.out.println(b3); //该结果值不正确,因为已经损失了精度。
// 315的二进制为: 00000000 0000000 00000001 00111011
// 因为b3是byte类型,所以要砍掉前3个8位:结果为: 00111011,也就是:59
// 32+16+8+2+1 = 59【所以向下强转会损失精度,而且改值也与自己期望的值不同】
p.s.
显示类型转换和强转类型转换的要点:
要看最终接受的那个值的类型,
如果是 大 = 大+小,就无需强转类型转换,
如果是 小 = 大+小,就必须强转类型转换,即最终为: 小 = (小)(大+小);
例子:
* 面试题:看下面的程序是否有问题,如果有问题,请指出并说明理由。
* byte b1 = 3;
* byte b2 = 4;
* byte b3 = b1 + b2;
有两个方面的问题,
编译不通过。
1)b1,b2两个byte类型的值在参与运算时,会直接提升为int类型(因为整数类型默认就是int类型),b3是byte类型,所以int类型的值赋值给b3会损失精度。
【byte和short,char分别参与运算时,都会先提升为int类型后,才参与运算。因为byte(1个字节),short(2个字节),char(2个字节)的取值范围都没有int(4个字节)大】
2)b1和b2都是变量,变量存储的值都是会变化的,所以在编译时jvm时无法判断里面具体的值,同样b1+b2的值可以会超出byte的取值范围。
* byte b4 = 3 + 4;
运行通过。
因为java编译器有常量优化机制,就是说在编译时直接算出了3+4的结果,而且判断了该值是否超出了byte的取值范围,结果是7没有超出byte(-128~127)的取之范围。
基本数据类型的取值范围(谁大谁小)
在参与混合运算时,byte,short,charb不会相互转化,而是自动提升为int类型,其他数据类型进行混合运算时,小的数据类型会提升为大的数据类型,才能运算。
运算大小范围:
byte,short,char -- int -- long -- float -- double
问?
float(4个字节)的取值范围要比long(8个字节)要小,但是在运算时为什么float比long大?
* 两个类型的底层存储结构不同。
long :2^63-1
float:2*2^114
所以long < float
int a=10;
byte b=20;
a = b; //小的可以直接放大里放, 这种情况叫:基本数据类型的自动类型提升。
b = a; //大的给小的,会损失进度,必须强转,即 b=(byte)(a);
例子说明:
float x = 12.3f;
long l = 12345;
//x = l; // 12345.0 因为小的long可以给大的float 隐式转换 byte,short,char -- int -- long -- float -- double
//System.out.println(x);
//l =x;
//System.out.println(l); // 编译通过,运行不通过,因为x是float类型,大(float)的不能给小(long)的,需要将float强制为long类型。
l = (long)x;
System.out.println(l); //12 将小数点后面的数给砍掉了。
g.
字符和字符串参与运算;
任意数据类型的与字符串紧挨着混合运算时,都会变成一个新的字符串。
例子+详解:
1) System.out.println('a'); //a 因为只是单个字符,所以直接输出a。
2) System.out.println('a'+1); //98 因为1是int(默认类型)类型,'a'是字符,当字符与int类型的值参与混合相加时,a字符就会被提升成int类型,而字符'a'在ASCII码表中对应的ASCII是97,所以97+1就是98。
了解:计算机中只识别0和1,但是后期为了方便就将字母和数字分别用二进制表示,而且有了一一对应的关系,这种关系被定义为了:ASCII码表。
3)System.out.println("hello"+'a'+1); //helloa1 因为前者hello是字符串,当字符串与任意数据类型混合运算时都会变成一个新的字符串,即:"helloa",而 "helloa"又是一个新的字符串,与1混合运算时,变成了最终的"helloa1"
4) System.out.println("hello"+'a'+'a'); //helloaa 前者字符串跟后者字符混合运算,变成一个新的字符串,而这个新的字符串"helloa"和后者字符混合运算,变成最终字符串"helloaa"
5) System.out.println('a'+"hello"+97); //ahello97
6) System.out.println('a'+"hello"+5+5); //ahello55 前者字符与后者字符串相加变成一个新的字符串,而新的字符串"ahello"与5相加,又变成一个新的字符串,而新的字符串"ahello5"与5混合运算,变成最终字符串"ahello55"
7) System.out.println('a'+1+"hello"); //98hello 根据从左到右运算的原则,字符a与1相加,a就提升为int类型,与1参与运算,变成98,98与字符串hello混合运算,变成最终结果:98hello
8)System.out.println("5+5="+5+5); //5+5=55 //首先字符串中的数据不变,即5+5=,这个字符串"/5+5="与5混合运算变成新字符串:"5+5=5",而这个新字符串与最后一个5参与运算,就变成了5+5=55
9) System.out.println("5+5="+(5+5)); //5+5=10 因为小括号将后面5+5的运算结果扩起来了,所以在java中括号有提升运算的优先级,所以字符串中的不做改变,即5+5=与后面的10混合运算就变成了:5+5=10
10) System.out.println(5+5+"=5+5"); 10="5+5" 因为前者5+5是int类型的值相加运算结果为10与后面的字符串"=5+5",变成最终结果的字符串:10=5+5
h.
char类型
char的特殊性:当char赋值【数字】时无需用单引号扩起来,结果是ASCII中的结果。如果用单引号引起来了该结果不变, 且他的取值范围0~65535之间的,且在127(ASCII中最大的就是127所对应的值)之下的,都能够翻译成ASCII中所对应的字符。
如:
char c=98;
//System.out.println("c"); //b ASCII对应的值。
char h4=4;
System.out.println(h4); //"方片" ASCII对应的值。
//char c2 = a;
//System.out.println(c2); //编译错误,必须单引号引起来。
//char ar4 = -97;
//System.out.println(ar4); //编译不通过 因为-97没有在char的取值范围内。
byte te = 97;
System.out.println(te); //97 因为在byte的取值范围
char ar5 = 128;
System.out.println(ar5); //? ar5为什么要赋值128呢?因为对应着ASCII码表中的最大127,所以想看看128所对应的值。
char ar6 = 129;
System.out.println(ar6); //? ar6为什么要赋值129呢?因为对应着ASCII码表中的最大127,所以想看看128所对应的值。
char ar7 = 63;
System.out.println(ar7); //? 63是正常的ASCII码表中的值。
byte te = 97;
System.out.println(te); //97 因为在byte的取值范围
char r1= 3; //红心 在char的取值范围内,且又对应ASCII码表中的值。
char r2= 4; //方片
char r3= 5; //梅花
char r4= 6; //桃花
System.out.println(r1+" "+r2+" "+r3+" "+r4+" ");
char h3 = '^';
System.out.println(h3); //^
char h5 = '4';
System.out.println(h5); //4
char h4 = (char)(-4);
System.out.println(h4);// ? 编译不通过 h6为什么要赋值-4呢?因为对应着ASCII码表中的最大127,所以想看看128所对应的值。
//char类型是否可以存储中文?
char h = '文';
System.out.println(h); //文 可以存储中文,但是只能是一个中文,因为java采用的Unicode编码,该编码中每个字符占用两个字节,而中文也是占用2个字节的。
i.
运算符
对常量和变量进行操作的符号。
分类(6种):
算术运算符,赋值运算符,比较(关系条件)运算符,逻辑运算符,位运算符,三元运算符。
算术运算符:
+ - * / %(取磨[余数]) ++ --
注意事项:
1) +: 在java中有三个作用,a.表示正号 b.字符串的连接符 c.做加法运算。
2) 整数相除只能是整数,如果想得到小数,需将其中一个变成小数,另外一个会自动类型提升。
3) /是除法后的商,%是除法后的余数。
%运算符:
当左边的绝对值小于右边的绝对值,结果是左边。
当左边的绝对值大于右边的绝对值,结果是余数。
%运算符结果的符号只和左边有关系,与右边无关。
【当左边的绝对值等于右边或右边的倍数,结果是0。】
【任何一个整数%2结果不是0就是1,可以当以后的判断条件。】 【只要是基数%2,都是1。偶数%2,都是0】
例子:
整数相除只能是整数
System.out.println(15/5); //3
如果想得到小数,需将其中一个变成小数,另外一个会自动类型提升
System.out.println(15.0/7); //2.142857142857143
当左边的绝对值小于右边的绝对值,结果是左边
System.out.println(3%5); //3
System.out.println(2%5); //2
System.out.println(-2%5); //-2
当左边的绝对值大于右边的绝对值,结果是余数
System.out.println(-12%5); //-2
当左边的绝对值等于右边或右边的倍数,结果是0
System.out.println(-15%5); //0
System.out.println(-10%5); //0
System.out.println(15%5); //0
任何一个整数%2结果不是0就是1,可以当以后的判断条件【只要是基数%2,都是1。偶数%2,都是0】
System.out.println(0%2); //0
System.out.println(3%2); //1
System.out.println(2%2); //0
%运算符结果的符号只和左边有关系,与右边无关
System.out.println(-1%3);//-1
System.out.println(1%3);//1
System.out.println(1%-3);//1
j.
++和--
单独使用:
放在操作数的前面后或后面结果都是一样的,都是做加1或减1操作。
参与运算使用:
放在操作数的后面,先参与运算(就是先将值取出做赋值操作),后自身加1或自身减1。
放在操作数的前面,先自身加1或自身减1,然后将结果赋值 【后参与运算(就是讲值取出做赋值操作)】。
例子:
放在操作数的前面后或后面结果都是一样的,都是做加1或减1操作。
int a = 3;
a++;
System.out.println(a); //4
int b = 4;
++b;
System.out.println(b); //5
int c = 2;
--c;
System.out.println(c); //1
int d = 7;
d--;
System.out.println(d); //6
放在操作数的后面,先参与运算(就是先将值取出做赋值操作),后自身加1或自身减1。
int a2 = 3;
int b2=a2++;
System.out.println(b2); //3
System.out.println(a2); //4
int c2 = 5;
int d2 = c2--;
System.out.println(c2); //4
System.out.println(d2); //5
放在操作数的前面,先自身加1或自身减1,然后将结果赋值 【后参与运算(就是讲值取出做赋值操作)】。
int e = 9;
int f = --e;
System.out.println(e); //8
System.out.println(f); //8
int e2 = 12;
int f2 = ++e2;
System.out.println(e2); //13
System.out.println(f2); //13
面试题1
请分别计算出a,b,c的值?
int a = 10;
int b = 10;
int c = 10;
a = b++; // a=10,b=11;
c = --a; // a=9,c=9;
b = ++a; // a=10,b=10;
a = c--; // c=8,a=9;
System.out.println(a); //a=9
System.out.println(b); //b=10
System.out.println(c); //c=8
int e = 7;
int f = 7;
int g = 7;
e = f++; //e=7,f=8
g = --e; //e=6,g=6
f = ++e; //e=7,f=7
e = g--; //e=6,g=5
System.out.println(e); //6
System.out.println(f); //7
System.out.println(g); //5
面试题2
//请分别计算出x,y的值?
int x = 4;
int y = (x++)+(++x)+(x*10);
// 4 6 6*10
// y=70
int x2 = 6;
int y2 = (++x2)+(x2++)+(x2*5);
//7 + 7 + 8*5;
// y2 =54
System.out.println("y2 = "+y2); //54
int x3 = 3;
int y3 = (x3--)+(--x3)-(x3++)+(--x3)+5+(--x3);
// 3 + 1-1+1+5+0
// y3=9,x3=0;
System.out.println("x3 = "+ x3 +"y3 = "+y3); //9
面试题3
//问哪句会报错,为什么
byte b = 10;
b++; // 相当于 b = (byte)(b+1),不会报错。
b = b + 1; //会出错,因为 b+1,1是int类型,b和1参与运算,b也会自动提升为int类型,但是byte的b来接受的,所以
//要将(b+1)强制转换为byte类型,即:byte b = (byte)(b+1)才行。
k.
赋值运算符
分为两种:
基本的赋值运算符: =
扩展的赋值运算符 +=, -=, *=, /=, %=
面试题1
看下面的程序是否有问题,如果有问题,请指出并说明理由。
short s=1;s = s+1; //s=1没有问题,s=s+1有问题,因为s+1中的1是int类型,当short类型的s与int类型参与混合运算时,会将short提升为int类型, 但赋值的s是short类型,两个int类型的值的和赋值给short会损失精度。
short s=1;s+=1; //s=1没有错误,s+=1 相当于 s=(short)(s+1),底层做了自动类型转换 ,所以不会报错。
l.
关系运算符
==, !=, >, >=, <, =<
无论最终结果是什么,都是Boolean类型。
不能将 '==' 写成 '='