一、进制
1.1四种进制的介绍
- 二进制
0,1 ,满 2 进 1.以 0b 或 0B 开头。
- 十进制
0-9 ,满 10 进 1。
- 八进制
0-7 ,满 8 进 1. 以数字 0 开头表示。
- 十六进制
0-9 及 A(10)-F(15),满 16 进 1,以 0x 或 0X 开头表示。此处的 A-F 不区分大小写。
1.2案例演示
public class Demo01 {
public static void main(String[] args) {
//演示四种进制
//n1 二进制
int n1 = 0b1010;
//n2 10 进制
int n2 = 1010;
//n3 8 进制
int n3 = 01010;
//n4 16 进制
int n4 = 0X10101;
//输出
System.out.println("n1=" + n1);//n1 =10
System.out.println("n2=" + n2);//n2 =1010
System.out.println("n3=" + n3); //n3= 520
System.out.println("n4=" + n4); // n4 =65793
System.out.println(0x23A);
}
}
1.4进制转换
- 第一组(转十)
- 二进制转十进制
原理
从最低位(最右边)开始,将每个位上的数提取出来,乘以2的(位数-1)次方
案例
0b1011 =8+2+1=11
- 八进制转十进制
原理
从最低位(最右边)开始,将每个位上的数提取出来,乘以8的(位数-1)次方
案例
0234=124+24+4=156
- 十六进制转十进制
原理
从最低位(最右边)开始,将每个位上的数提取出来,乘以16的(位数-1)次方
案例
0X23A=512+48+10=570
- 第二组(十转)
- 十进制转二进制
原理
将该数不断除以2,直到商为0为止,然后将每步得到的余数倒过来
案例
34=0b00100010
为什么前面会多两个0?
数据保存在一个字节中,而一个字节有八位,所有高位补0,补齐八位,在数据表示中还会讲解
- 十进制转八进制
原理
将该数不断除以8,直到商为0为止,然后将每步得到的余数倒过来
案例
131=0203
3.十进制转十六进制
原理
将该数不断除以16,直到商为0为止,然后将每步得到的余数倒过来
案例
237=0XED
- 第三组(二转)
- 二进制转八进制
原理
从低位开始,将二进制数每3位为一组,(拼接)转成对应的八进制数
案例
0b11010101 = 0325
2.二进制转十六进制
原理
从低位开始,将二进制数每4位为一组,(拼接)转成对应的十六进制数
案例
0b 11010101=0XD5 (方法与二转八一样)
- 第四组(转2)
- 八进制转二进制
规则
将八进制数每 1 位,转成对应的一个 3 位的二进制数即可。
案例
请将 0237 转成二进制
0 2(010)3(011)7(111) = 0b10011111
2.十六进制转二进制
规则
将十六进制数每 1 位,转成对应的 4 位的一个二进制数即可。
案例
请将 0x23B 转成二进制
0x 2(0010)3(0011)B(1011) = 0b001000111011
1.5原码、反码、补码
- 二进制在运算中说明
-
进制是逢二进位制,0、1是基本算符
-
现代的电子计算机技术全部采用的是二进制,因为它只使用0、1两个数字符号,非常简单方便,易于用电子方式实现。计算机内部处理的信息,都是采用二进制数来表示 的。二进制(Bingary)数用0、1两个数字及其组合表示任何数字进位规则是”逢二进一”,数字1在不同的位上代表不同的值,按照从右至左的次序,这个值都是以二倍递增。
- 原码、反码、补码
1.二进制的最高位是符号位:1表示负数,0表示正,0的表示不唯一
2 .在Java中,1代表真,0代表假
3.正数的原码、反码、补码都一样(三码合一)
4.负数的反码=它的原码符号位不变,其他位取反
(想知道反码就得先知道原码)5.负数的补码=它的反码+1
(若想知道负数的补码就得先知道它的反码)6.负数的反码=负数的补码-1
7.0的反码、补码都是0
8.在计算机运算的时候,都是一补码的方式进行运算的
9.当我们看运算结果时,要看它的原码(注意)
二、数据的表示(存储)
2.1整数在计算机中的存储原理
(1)其实任何数据在计算机中都是以二进制表示的。
(2)计算机的最小存储单位
前面我们已经知道计算机表示数据是用二进制来的。
日常疑问:我现在想要在计算机中存储一个整数(十进制)6,转换为二进制是110,那么计算机中只是存110吗三位数字吗?
日常解答:其实不是的,计算机中最小的存储单位是字节(Byte),一个字节占8位(bit),也就是说即使这个数据不足8位也需要用8位来存储。
计算机中数据最小的组成单元:使用8个二进制位为一组,称之为一个字节(byte,简称B) 1B = 8b。
在B的基础上,计算机发展出了KB、MB、GB、TB、…. 这些数据单位。
1B = 8b
1KB = 1024B1MB = 1024KB
1GB = 1024MB1TB = 1024GB
我们随便找到一个文件,看文件的属性,可以看到文件的大小都是以字节为单位的
总结提问:
1、数据在计算机底层都是怎么存储的?
都是采用二进制:使用0、1,按照逢2进1的规则表示数据来存储。
2、数据在计算机底层存储的最小单位是什么?
字节,一个字节等于8个二进制位:1B=8b
3.以下三种方式又是如何存储?
2.2字符在计算机中的存储原理
其实字符并不是直接存储的,而是把每一个字符编为一个整数,存储的是字符对应整数的二进制形式。美国人搞了一套字符和整数的对应关系表,叫做ASCII编码表。
- ASCII编码表中字符编码的规律
1.字符0对应48,后面的1,2,3,4…9 对应的十进制整数依次往后顺延
2.字符a对应97,后面的b,c,d,e…z 对应的十进制整数依次往后顺延
3.字符A对应65,后面的B,C,D,E…Z 对应的十进制整数依次往后顺延
Ps:在ASCII编码表中是不包含汉字的。汉字在其他编码表中,后面我们会单独介绍。关于字符在计算机中的存储学到这就可以了。
2.3图片视频声音的存储原理
- 图片存储
如果你把一张图片不断的放大,你会看到有马赛克的效果。你会发现图片中的每一个细节是由一个一个的小方格组成的,每一个小方格中其实就是一种颜色。任何一种颜色可以使用三原色来表示,简称RGB,其中R(红色),G(绿色),B(蓝色),而RGB中每一种颜色又用一个字节的整数来表示,最小值是0最大值是255。
RGB(0,0,0)表示黑色
RGB(255,255,255)表示白色
RGB(255,0,0) 表示红色
RGB(255,255,0) 表示红色和绿色混合为黄色
RGB(255,0,255) 表示红色和蓝色混合为紫色
...
你在画图板的颜色编辑器中可以通过指定RGB的值,来调整得到任意的颜色。一张图片实际上就是有很多个小方块的颜色组成的,而每一种颜色又是由RGB三原色的整数表示的,整数最终会转换为二进制进行存储。
- 视频存储
实际上视频和图片是一样的,把多张图片连续播放,在一秒钟内连续播放24张以上,由于人眼存在视觉暂留现象,人眼感受不到画面切换的时间间隔,就认为是连续的视频了。
- 声音存储
了解过物理的同学肯定知道,声音是以波的形式传播的。我们可以把声波在表示在一个坐标系上,然后在坐标系上取一些点,把这些点的坐标值以二进制的形式存储到计算机中,这就是声音的存储原理。
三、数据类型
在定义变量时我们是要声明数据类型的,这里的数据类型是用来规定变量存储什么类型的数据。基本数据类型一共有4类8种,每一种数据类型占用的内存空间不一样,能够表示的数据范围也不一样。如下图所示
需要我们注意的是,随便写一个整数或者小数的字面量,它也是有默认数据类型
- 比如23,它默认就为int类型;如果加上后缀L,则为long类型;
- 比如23.8,它默认为double类型;如果加上后缀F,则为float类型;
-
代码演示八种数据类型
/* 目标:掌握8种基本数据类型定义变量 1.整型 2.浮点型 3.字符型 4.布尔型 */ public class DataType01 { public static void main(String[] args) { // 1.整型 byte b = 12; // -128 到 127 System.out.println(b); short s = 30000; // -32768 到 32767 // -2147483648 到 2147483647 默认就是int int i = 999999; // 123456789098超出了int范围需要添加L/l long l = 123456789098L; // 2.浮点型 double d = 99.9; // 小数默认是double float f = 99.9F; // float需要添加F/f // 3.字符型 char c1 = 'a'; char c2 = '中'; char c3 = '国'; // 4.布尔型 boolean b1 = true; boolean b2 = false; } }
四、类型转换
为什么要学习类型转换呢?因为在我们实际开发中可能存在将某种类型变量的值,赋值给另一个类型的变量;也可能存在多种数据类型的数据一起运算的情况。
在以上情况中,其实都会涉及到类型转换。类型转换的形式总体分为2种,一种是自动类型转换,一种是强制类型转换。 这里先学习自动类型转换
4.1自动类型转换
- 什么是自动类型转换呢?
答:自动类型转换指的是,数据范围小的变量可以直接赋值给数据范围大的变量
byte a = 12;
int b = a; //这里就发生了自动类型转换(把byte类型转换int类型)
- 自动类型转换的原理是怎样的?
答:自动类型转换其本质就是在较小数据类型数据前面,补了若干个字节
除了byte和int之间的转换之外,其他类型也可以转换,转换顺序如下图所示
下面我们通过代码演示一下,自动类型转换的各种形式。
/*
目标:理解自动类型转换机制
使用=赋值,范围小的自动赋值给范围大的
char
↓
byte -> short -> int -> long -> float -> double
*/
public class DataConvert01 {
public static void main(String[] args) {
byte b = 12;
int i = b; // 自动类型转换 byte -> int
System.out.println(b);
System.out.println(i);
int i2 = 100;
double d = i2; // 自动类型转换 int -> double
System.out.println(d);
char c = 'a';
int ch = c; // 自动类型转换 char -> int
System.out.println(ch);
//byte、short、char、之间不会自动转换
byte b1 = 10;
char c1 = b1;//错误,原因:byte不能自动转成char
//bollean不参与转换
}
}
- 表达式的自动类型转换
自动类型转换还有另外一种形式,就是表达式的自动类型转换。所谓表达式指的是几个变量或者几个数据一起参与运算的式子。
如果同一个表达式中,出现不同类型的变量或者数据一起运算,这种情况下运算结果是一个什么数据类型呢?需要遵守下面的两条运算规则:
1.多种数据类型参与运算,其结果以大的数据类型为准
2.byte,short,char 三种类型数据在和其他类型数据运算时,都会转换为int类型再运算
- 代码演示
package com.itheima._03dataconvert;
/*
目标:理解表达式的自动类型转换
变量参与运算,以范围最大的为主
char
↓
byte -> short -> int -> long -> float -> double
在表达式中,小范围类型的变量,会自动转换成表达式中较大范围的类型,再参与运算
在表达式中byte、short、char是直接转换成int类型参与运算的
*/
public class DataConvert02 {
public static void main(String[] args) {
byte a = 10;
int b = 20;
long c = 30;
// 在表达式中,小范围类型的变量,会自动转换成表达式中较大范围的类型,再参与运算
long ret1 = a + b + c;
System.out.println(ret1);
double d = 3.3;
double ret2 = a + b + d;
System.out.println(ret2);
// 面试题: 两个byte运算,用什么接收
// 在表达式中byte、short、char是直接转换成int类型参与运算的
byte b1 = 1;
byte b2 = 1;
int b3 = b1 + b2;
}
}
总结
自动提升原则:表达式结果的类型自动提升为操作数中最大的类型
1.有多种类型的数据混合运算时,系统首先自动将所有数据类型换成数据范围最大的那种数据类型,然后在进行运算。
2.当我们把范围大的赋值给范围小的的数据类型时,会报错,反之就会自动类型转换
3.byte、short、char之间不会自动转换
4.short、byte、char,他们三者可以计算,在计算式首先转换成int类型
5.boolean不参与转换
4.2强制类型转换
前面我们学习了自动类型转换,我们知道可以将数据类型小的数据可以直接赋值给数据范围大的变量。 那反过来,能不能将数据范围大的数据直接赋值给数据范围小的变量呢? 答案是会报错。
因为数据范围大的数据,赋值给数据范围小的变量,它有可能装不下;就像把一个大桶的水倒入一个小桶中,有溢出的风险。
- 什么是强制类型转换
但是你强行将范围大的数据,赋值给范围小的变量也是可以的,这里就需要用到强制类型转换。下面是强制类型转换的格式
目标数据类型 变量名 = (目标数据类型)被转换的数据;
- 代码演示
package com.itheima._03dataconvert;
/*
目标:掌握强制类型转换
*/
public class DataConvert03 {
public static void main(String[] args) {
int i = 20;
byte b = (byte) i; // alt + 回车 -> Cast to
System.out.println(i);
System.out.println(b);
int i2 = 1500;
byte b2 = (byte) i2;
System.out.println(b2); // -36 数据丢失
double d = 99.5;
int i3 = (int) d;
System.out.println(i3); // 99 丢失小数部分
}
}
- 强制类型转换的原理
强制类型转换的原理,其实就是**强行把前面几个字节砍掉,但是有数据丢失的风险**。
- 总结
1.当进行数据的大小,大-》小,就需要使用强制转换
2.强制转换只针对最近的操作数据有效,往往会使用到小括号来提升优先级
例如:int x = (int)(10*3.5+6*1.5);
无效的:int x = (int)1 0*3.5+6*1.5;
3.char 类型可以保存int的常量值,但不能保存int的变量值,需要强转
例如:char c1 = 100;//ok
int i1 = 99;//ok
char c2 = i1;//no
char c3 = (char)i2;//ok
五、运算符
接下来,给同学们讲解一个在开发中用得很多的一块内容,叫做运算符。
大家知道计算机是用来处理数据的,处理数据就少不了对数据的计算,想要对数据进行计算就必须用到运算符。
运算符就是参与运算的符号。Java提供的运算符有很多种,可以分为算术下面几种
- 基本算术运算符
- 自增自减运算符
- 赋值运算符
- 关系运算符
- 逻辑运算符
- 三元运算符
5.1算术运算符
-
取余介绍
(1)本质
a % b =a - (int) a/b * b
(2) 案例
/*ps: -当a %b,a是小数时,公式= a -(int)a/b * b -运算结果的正负数取决于%左边 -当%左边小于右边时,结果直接是左边的数(正负数一致) */ 2%3 = 2 -99 %100=-99 10 % 2 =0 10 -10/2 * 2=10- (5)*2=0 10 % 3=1 10 - 10/3 *3 = 10-(3)*3=1 -7 % 3 =-1 -7 -(-7)/3*3 = -7+(2)*3=-1 10.5 % 3 =1.5 10.5 - 10.5/3 *3 = 10.5 -9 =1.5
-
案例演示
/*
目标1:掌握基本的算术运算符的使用
目标2:掌握算术细节
(1) /: 两个整数相除,结果也是一个整数
(2) +符号除了用于加法运算,还可以作为连接符。
(3)+符号与字符串运算的时候是用作连接符的,其结果依然是一个字符串**。
*/
public class Operator01 {
public static void main(String[] args) {
int a = 10;
int b = 2;
System.out.println(a + b);//12
System.out.println(a - b);//8
System.out.println(a * b); // 20
System.out.println(a / b); // 5
System.out.println(5 / 2); // 2=> 整数相除结果为整数,会丢弃小数
System.out.println(5.0 / 2); // 2.5=>加了小数点后就提升为double
System.out.println(1.0 * 5 / 2); // 2.5
// % 两个数相除,取余数
System.out.println(a % b); // 0
System.out.println(5 % 2); // 1
System.out.println("------------------------");
// 使用+符号做连接符的情况: 能算则算,不能算就在一起
int a2 = 5;
System.out.println("abc" + a2); // "abc5"
System.out.println(5 + a2); // 10
System.out.println("itheima" + a2 + 'a'); // "itheima5a"
System.out.println(a2 + 'a' + "itheima"); // 102itheima
}
}
5. 2 自增自减运算符
接下来,学习一种比较常用的运算符:++
和--
++
读作自增,--
读作自减; 运算规则如下
- 注意
自增自减只能对变量进行操作,不能操作字面量。具体使用时也分为两种情况,如下:
1.单独使用:++或者--放在变量前面没有区别
int a =10;
a++; //11
--a; //10
System.out.println(a); //10
2.混合使用:++或者--放在变量或者前面运算规则稍有不通过
//++在后:先做其他事情,再做自增和自减
int a = 10;
int b = a++; //等价于 int b = a; a++;
//++在前:先自增或者自减,再做其他运输
int x = 10;
int y = --x; //等价于x--; int y = x;
- 代码演示++
和
–的用法
/*
目标:掌握自增自减运算符的使用
单独使用:++/--放在变量前后没有区别
混合使用:++或者--放在变量或者前面运算规则稍有不通过
++在后:先做其他运算,再做自增
++在前:先自增,再做其他运算
自增自减只能操作变量不能操作字面量的,会报错!
*/
public class Operator02 {
public static void main(String[] args) {
// 单独使用:++/--放在变量前后没有区别
int a = 10;
// a++; // a = a + 1;
++a;
System.out.println(a);
// a--; // a = a - 1;
--a;
System.out.println(a);
System.out.println("--------------------------------------");
// 混合使用:++在前:先自增,再做其他运算
int i = 10;
int ret1 = ++i; // 先加后用
System.out.println(i);
System.out.println(ret1);
System.out.println("--------------------------------------");
// 混合使用:++在后:先做其他运算,再做自增
int j = 10;
int ret2 = j++; // 先用后加
System.out.println(j);
System.out.println(ret2);
// 自增自减只能操作变量不能操作字面量的,会报错!
// System.out.println(10++);
}
}
5.3 赋值运算符
接下来,我们学习赋值运算符。基本的赋值运算符其实就是=
号,意思就是把右边的数据赋值给左边的变量。
int a = 10; //将数据10赋值给左边的变量a
除了基本的赋值运算符,我们这里主要学习一下扩展的赋值运算符。有+= -= *= /= %=
我们以+=
为例来看一下它的运算规则,其他的运算符运算同理分析即可
int a = 10;
//+=解析:在a原来记录值10的基础上累加5,将结果重新赋值给a;
a+=5;
//最终打印a的值为15
System.out.println(a);
- 案例
/*
目标:掌握扩展赋值运算符的使用
以发红包为例子
*/
public class Operator03 {
public static void main(String[] args) {
// 需求:收红包
int a = 1314;
int b = 520;
a += b;
System.out.println(a);
// 需求:发红包
double i = 100;
double j = 88.48;
i -= j; // i = (double)(i - j);
System.out.println(i);
int m = 10;
int n = 5;
// m *= n; // 等价形式: m = (int)(m * n)
// m /= n; // 等价形式: m = (int)(m / n)
m %= n; // 等价形式: m = (int)(m % n)
System.out.println(m);
}
}
学完扩展赋值运算符的基本使用之后,接下来我们看一个面试题
问题1:下面的代码否有问题?
byte x = 10;
byte y = 30;
x = x + y; //这句代码有问题,因为两个byte类型数据相加,会提升为int类型;
问题2:下面的代码是否有问题?
byte x = 10;
byte y = 30;
x+=3; //这句代码没有问题,因为这里有隐含的强制类型转换
//x+=3; 等价于 byte x = (byte)(x+y);
- 总结
1.基本赋值运算符:
=符号含义: 把右边的值赋值给左边的变量
2.扩展赋值运算符:
+= -= *= /= %=符号含义:将右边的数据和左边的变量相加、相减、相乘、相除、取余数后,将结果重新赋值给左边的变量。
5.4 关系运算符
下图是每一种关系运算符的符号及作用,每一个关系运算符的结果都是false
- 代码演示
/*
目标:掌握关系运算符的基本使用
*/
public class Operator04 {
public static void main(String[] args) {
int a = 10;
int b = 5;
boolean rs = a > b;
System.out.println(rs);
System.out.println(a >= b); // a大于或者a等于b
System.out.println(2 >= 2); // true
System.out.println(a < b);
System.out.println(a <= b); // false
System.out.println(2 <= 2); // true
System.out.println(a == b); // false
System.out.println(5 == 5); // true
// System.out.println(a = b); // 注意了:判断是否相等一定是用 == ,=是用来赋值的。
System.out.println(a != b); // true
System.out.println(10 != 10); // false
}
}
关于关系运算符的实际运用需要在后面学习了流程控制语句才能实际用到。
关系运算符在程序中常用于条件判断,根据条件判断的结果是true还是false,来决定后续该执行哪些操作。
5.5 逻辑运算符
逻辑运算符是用来将多个条件放在一起运算,最终结果是true或者false
- 代码演示
/*
目标:掌握逻辑运算符的使用
需求1:要求女朋友满足身高170CM 并且 体重小于55公斤.
需求2:要求女朋友满足身高170CM 或者 体重小于55公斤.
*/
public class Operator05 {
public static void main(String[] args) {
int height = 175;
int weight = 50;
// 需求1:要求女朋友满足身高170CM 并且 体重小于55公斤.
// &:两个都为true结果才是true
boolean ret1 = height >= 170 & weight <= 55;
System.out.println(ret1);
// 需求2:要求女朋友满足身高170CM 或者 体重小于55公斤.
// |: 有一个为true结果为true
boolean ret2 = height >= 170 & weight <= 55;
System.out.println(ret2);
// ^: 异或 相同为false不同为true
// 去民政局领结婚证(异性相吸)
System.out.println(true ^ true); // false
System.out.println(true ^ false); // true
System.out.println(false ^ true); // true
System.out.println(false ^ false); // false
// !: 非(取反) 非礼(没有礼貌) (常用)
System.out.println(!true); // false
System.out.println(!false); // true
// &&: 左边为false,右边不执行。
int i = 10;
int j = 20;
// System.out.println(i > 100 && ++j > 99);
System.out.println(i > 100 & ++j > 99);
System.out.println(j);
// ||: 左边是true,右边就不执行。
int m = 10;
int n = 30;
// System.out.println(m > 3 || ++n > 40);
System.out.println(m > 3 | ++n > 40);
System.out.println(n);
}
}
至于逻辑运算符的实际运用,需要在学习了流程控制语句之后,才能实际用到。
逻辑运算符在程序中常用于组合几个条件判断,根据条件判断的结果是true还是false,来决定后续该执行哪些操作。
5.6 三元运算符
先认识一下三元运算符的格式:
关系表达式? 值1 : 值2;
三元运算的执行流程:首先计算关系表达式的值,如果关系表达式的值为true,则返回值1;如果关系表达式的值为false, 则返回值2;
如下图所示:判断学生的成绩是否>=60,如果为true,就考试通过;如果为false,就成绩不合格。
- 代码演示
/*
目标:掌握三元运算符的基本使用
1.判断成绩是否及格
2.找两个数的较大值
*/
public class Operator06 {
public static void main(String[] args) {
// 1.判断成绩是否及格
double score = 66;
String ret1 = score >= 60 ? "及格" : "不及格";
System.out.println(ret1);
// 2.找两个数的较大值
int a = 10;
int b = 20;
int ret2 = a > b ? a : b;
System.out.println(ret2);
}
}
3.7 运算优先级
从图中我们发现,&&运算比||运算的优先级高,所以&&和||同时存在时,是先算&&再算||;
比如下面的代码
// 这里&&先算 相当于 true || false 结果为true
System.out.println(10 > 3 || 10 > 3 && 10 < 3); // true
最后给大家说一下,在实际开发中,其实我们很少考虑运算优先级, 因为如果你想让某些数据先运算,其实加()
就可以了,这样阅读性更高。
//有括号先算 相当于 true && false 结果为false
System.out.println((10 > 3 || 10 > 3) && 10 < 3); // false
六、位运算
java 中有 7 个位运算(&、|、 ^ 、~、>>、<<和 >>>)
这里需要运用到进制转换、原码、反码、补码和整数在计算机中的存储原理以及逻辑运算符的知识,没弄懂的可以往上在看一遍
6.1按位与(&)
- 原理
两边为1是1,否则为0(一边假为假)
案例
-
案例
2&3
- 推导
得到其补码在进行运算,运算后在将补码转成原码进行显示
步骤1:先得到2的补码
(1)2的原码:00000000 00000000 00000000 00000010
知识点:
计算机运算时以补码方式进行运算的
但想要知道2的补码就要知道2的原码
因为2是int 类型,int占四个字节,每个字节占八位,没满的补0,所以原、反、 补码都是八位一组
(2)2的补码:00000000 00000000 00000000 00000010
知识点:
原码0表示整数。1表示负数
正数三码合一
步骤2:3的补码
(1)3的原码:00000000 00000000 00000000 00000011
(2)3的补码:00000000 00000000 00000000 00000011
步骤3:按位于(&)
(1)2的补码:00000000 00000000 00000000 00000010
(2)3的补码:00000000 00000000 00000000 00000011
(3) 看真假:00000000 00000000 00000000 00000010
ps:但需要将运算完成的补码转成原码,因为运算结果要看它的原码,又因为正数三码合一,所以原码和补码相同。
6.2取反(~)
- 原理
0->1,1->0 (假变真,真变假)
- 案例
System.out.println(~-2);
- 推导
//得到其补码在进行运算,运算后在将补码转成原码进行显示
步骤一:先得到-2的补码
(1)-2的原码:10000000 00000000 00000000 00000010
知识点:
计算机运算时以补码方式进行运算的
但想要知道-2的补码就要知道-2的原码,-2是负数,所以第一位符号位是1
因为-2是int 类型,int占四个字节,每个字节占八位,没满的补0,所以原、反、 补码都是八位一组
(2) -2的反码:11111111 11111111 11111111 11111101
知识点:
负数的反码=它的原码符号位不变,其他位取反
(3) -2的补码:11111111 11111111 11111111 11111110
知识点:
负数的补码=它的反码+1
逢二进一
步骤2:取反(~)
取反运算:000000000 00000000 00000000 00000001(运算后的补码)
知识点:
计算机运算时以补码方式进行运算的,所以取反操作也是对补码进行取反的。
步骤3:转换成原码
因为取反后成了正数,所以就是三码合一,不用进行转换
快速案例:
案例1:~2
补码:00000000 00000000 00000000 00000010
取反:11111111 11111111 11111111 11111101
反码:11111111 11111111 11111111 11111100
原码:10000000 00000000 00000000 00000011
输出-3
案例2:1|2
1的补码:00000000 00000000 00000000 00000001
2的补码:00000000 00000000 00000000 00000010
1|2:00000000 00000000 00000000 00000011
其他的原理都是一样的,希望能举一反三
七、案例技术:获取用户键盘输入的数据
最后给大家讲一个案例技术,这个技术现在其实有一些超前,因为需要用到后面学习的知识。但是在这里讲可以让我们的学习体验度更好一点,前面案例中参与运算的数据都是在程序中写死的,下面我们想让自己键盘录入数据,然后参与程序的运行。
键盘录入这个事情,其实并不是我们自己做的,而是Java本身就提供了这样的功能,我们按照它的要求,去调用就行。
我们在安装JDK的时候,其实JDK中就已经包含了一些Java写好的代码,我们把Java写好的代码直接拿过来用就行。
比如:Scanner就是Java提供给我们用于键盘录入数据的类,为了录入不同类型的数据,还提供了不同的功能,每一个功能会有不同的名称,我们只需要调用Scanner提供的功能就可以完成键盘录入数据。
大家只需要按照下面的步骤编写代码,就可以键盘录入数据了
【第1步】:在class类上导包:一般不需要我们自己做,idea工具会自动帮助我们 导包的。
import java.util.Scanner;
【第2步】:得到一个用于键盘扫描器对象(照抄代码就行,固定格式)
//Scanner是键盘扫描器对象(你就把它理解成一个东西),这个东西有录入的功能
//sc是给这个东西取的名字
Scanner sc = new Scanner(System.in);
【第3步】:开始调用sc的功能,来接收用户键盘输入的数据。
//sc这个东西有键盘录入整数的功能,这个功能的名字叫nextInt()
//.表示表示调用的意思
int age = sc.nextInt();
System.out.println("我的年龄是:"+age);
//sc这个东西还有键盘录入字符串的功能,这个功能的名字叫next
String name = sc.next();
System.out.println("我的姓名是:"+name);
- 代码演示
package com.itheima._05scanner;
import java.util.Scanner;
/*
目标:掌握Scanner的基本使用
*/
public class Scanner01 {
public static void main(String[] args) {
// 1.导包:一般不需要我们自己做,idea工具会自动帮助我们 导包的。
// 2.抄写代码:得到一个键盘扫描器对象(东西)
Scanner sc = new Scanner(System.in);
System.out.println("请您输入您的年龄:");
// 3.接收用户键盘输入的int数据
int age = sc.nextInt(); // 执行到这儿,会开始等待用户输入一个整数,直到用户按了回车键,才会拿到数据。
System.out.println("您的年龄是:" + age);
System.out.println("请您输入您的名字:");
// 4.接收用户键盘输入的String数据
String name = sc.next(); // 执行到这儿,会开始等待用户输入一个字符串,直到用户按了回车键,才会拿到数据
System.out.println(name + "欢迎您进入系统~~");
}
}
八、自测选择题
题目1(单选):
下列属于正确的自增自减运算符的是( )
选项 :
A. ++和–
B.+和-
C.+++和—
D.-和/
答案: A
题目2(单选):
下列代码的运行结果是( )
int x = 10;
int y = x++;
int z = ++x;
System.out.println(x);
System.out.println(y);
System.out.println(z);
选项 :
A. 12 10 12
B. 10 11 12
C. 11 11 10
D. 12 10 11
答案:A
题目3(单选):
下列关于自减运算符描述正确的是( )
选项 :
A. --可以使用在常量中
B.–如果放在变量的后面,是先参与操作,然后再自减
C.–如果放在变量的前面,是先参与操作,然后再自增
D.–如果放在变量的后面,是先执行自减,然后再参与操作
答案:B
题目4(单选):
下列代码的运行结果是()
public class Test {
public static void main(String[] args) {
double a = 12.3;
int b = a;
System.out.println(b);
}
}
选项 :
A. 12
B. 12.3
C. 12.0
D. 编译错误
答案: D
题目5(单选):
下列代码的运行结果是( )
public class Test {
public static void main(String[] args) {
int a = 10;
double b = 12.3;
a += b;
System.out.println(a);
}
}
选项 :
A. 编译错误, 没有做强转
B. 22.3
C. 22
D. 22.0
答案:C
题目6(单选):
下列代码的运行结果是( )
public class Test {
public static void main(String[] args) {
int a = 1;
int b = 2;
boolean result = a++ > 3 && --b < 4;
System.out.println(a);
System.out.println(b);
System.out.println(result);
}
}
选项 :
A. 1 2 false
B. 2 2 false
C. 1 2 true
D. 2 2 true
答案:B
题目7(多选):
下列对于逻辑赋值运算符特点描述正确的是( )
选项 :
A. &符号遇false则false
B. |符号遇true则true
C. && 具有短路效果, 左边为false, 右边不执行
D. || 具有短路效果, 左边为true, 右边不执行
答案:ABCD
题目8(多选):
下列关于if语句的描述, 说法正确的是( )
选项 :
A. if 语句的 () 和 {} 之间可以编写分号, 对程序没有任何影响
B. if 语句的 {} 中如果只有一条语句, {} 可以省略不写
C. if 语句的 () 中, 最终产生的是一个boolean类型结果, 根据这个结果决定程序的走向
D. if 语句的 {} 无论何时都不能省略
答案:BC
题目9(单选):
下列代码的运行结果是( )
public class Test {
public static void main(String[] args) {
int a = 1;
int b = 1;
int c = 0;
if (a > b) {
c = 10;
}else if(a < b){
c = 20;
}
System.out.println(c);
}
}
选项 :
A. 编译错误, 缺少最后的else代码块
B. 0
C. 10
D. 20
答案: B
题目10(单选):
键盘录入数据为200, 下列代码的运行结果是( )
public class Test {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入成绩:");
int score = sc.nextInt();
if (score >= 0 && score <= 100) {
if (score >= 95 && score <= 100) {
System.out.println("山地自行车一辆");
} else if (score >= 90 && score <= 94) {
System.out.println("游乐场玩一次");
} else if (score >= 80 && score <= 89) {
System.out.println("变形金刚玩具一个");
} else {
System.out.println("挨顿揍");
}
}
}
}
选项 :
A. 编译错误
B. 挨顿揍
C. 程序正常运行, 但是没有任何结果输出
D. 以上说法都不对
答案:C
九、操作题
题目1(训练)
身高是具有遗传性的,子女的身高和父母的身高有一定的关系。假定,父母和子女的身高遗传关系如下:
儿子身高(厘米)=(父亲身高+母亲身高) ×1.08÷2
女儿身高(厘米)=(父亲身高×0.923+母亲身高) ÷2
现有父亲身高177CM,母亲身高165CM。求子女身高分别预计为多少?
训练提示
-
已知的父母身高如何用代码体现?
-
题目中的公式如何转化为代码?
解题方案
- 使用变量的定义和算术运算符完成本题
操作步骤
-
定义小数变量代表父亲身高
-
定义小数变量代表母亲身高
-
通过儿子身高计算方式计算儿子身高
-
通过女儿身高计算方式计算女人身高
参考答案
public class Demo01 {
public static void main(String[] args) {
//1.定义父亲身高
double father = 177;
//2.定义母亲身高
double mother = 165;
//3.利用公式计算儿子身高
double son = (father + mother) * 1.08 / 2;
//4.利用公式计算女儿身高
double daughter = (father * 0.923 + mother) / 2;
//5.打印结果
System.out.println("儿子预计身高" + son + "厘米");
System.out.println("女儿预计身高" + daughter + "厘米");
}
}
题目2(训练)
红茶妹妹有21元钱,她攒了几天钱之后自己的钱比原来的两倍还多三块。绿茶妹妹有24元钱,她攒了几天钱之后自己的钱正好是原来的两倍。那么红茶和绿茶现在的钱一样多,请问对么?
训练提示
- 用什么知识点来计算她们现在的钱有多少?
- 如何对比两个人的钱数?
解题方案
- 使用赋值运算符和算术运算符计算各自的钱,使用比较运算符对比大小
操作步骤
- 定义红茶妹妹原来的钱为整数变量
- 定义绿茶妹妹原来的钱为整数变量
- 使用赋值运算符和算术运算符计算其现有的钱
- 使用比较运算符对数值做出比较
参考答案
public class Demo2 {
public static void main(String[] args) {
//1.定义红茶妹妹原来的钱
int red = 21;
//2.定义绿茶妹妹原来的钱
int green = 24;
//3.求红茶妹妹现有的钱
red = red * 2 + 3;
//4.求绿茶妹妹现有的钱
green *= 2;
//5.判断并输出两个人的钱是否相等
System.out.println(red == green);
}
}
题目3(综合)
某小伙想定一份外卖,商家的优惠方式如下:鱼香肉丝单点24元,油炸花生米单点8元,米饭单点3元。订单满30元8折优惠。鱼香肉丝优惠价16元,但是优惠价和折扣不能同时使用。那么这个小伙要点这三样东西,最少要花多少钱?
训练提示
- 有两种购买方式,一种是不使用优惠价,另一种是使用优惠价。分别计算花费后,对两种方式的花费作对比。
解题方案
- 使用算术运算符、赋值运算符和三元运算符联合完成本题
操作步骤
- 使用算术运算符求出不使用优惠时的总价
- 使用三元运算符判断总价是否满足打折条件,并求出折后总价
- 使用算术运算符求出使用优惠价时的总价
- 使用三元运算符判断最终更合算的购买方式和花费
参考答案
public class Demo3 {
public static void main(String[] args) {
//1.求不使用优惠时的总价
double money1 = 24 + 8 + 3;
//2.判断折后总价
money1 = (money1 >= 30 ? money1 * 0.8 : money1);
//3.求使用优惠时的总价
double money2 = 16 + 8 + 3;
//4.判断两种花费哪个更少
double money = money1 < money2 ? money1 : money2;
//5.打印最终花费
System.out.println(money);
}
}
儿子预计身高" + son + “厘米”);
System.out.println(“女儿预计身高” + daughter + “厘米”);
}
}
## 题目2(训练)
红茶妹妹有21元钱,她攒了几天钱之后自己的钱比原来的两倍还多三块。绿茶妹妹有24元钱,她攒了几天钱之后自己的钱正好是原来的两倍。那么红茶和绿茶现在的钱一样多,请问对么?
### 训练提示
1. 用什么知识点来计算她们现在的钱有多少?
2. 如何对比两个人的钱数?
### 解题方案
1. 使用赋值运算符和算术运算符计算各自的钱,使用比较运算符对比大小
### 操作步骤
1. 定义红茶妹妹原来的钱为整数变量
2. 定义绿茶妹妹原来的钱为整数变量
3. 使用赋值运算符和算术运算符计算其现有的钱
4. 使用比较运算符对数值做出比较
### 参考答案
```java
public class Demo2 {
public static void main(String[] args) {
//1.定义红茶妹妹原来的钱
int red = 21;
//2.定义绿茶妹妹原来的钱
int green = 24;
//3.求红茶妹妹现有的钱
red = red * 2 + 3;
//4.求绿茶妹妹现有的钱
green *= 2;
//5.判断并输出两个人的钱是否相等
System.out.println(red == green);
}
}
题目3(综合)
某小伙想定一份外卖,商家的优惠方式如下:鱼香肉丝单点24元,油炸花生米单点8元,米饭单点3元。订单满30元8折优惠。鱼香肉丝优惠价16元,但是优惠价和折扣不能同时使用。那么这个小伙要点这三样东西,最少要花多少钱?
训练提示
- 有两种购买方式,一种是不使用优惠价,另一种是使用优惠价。分别计算花费后,对两种方式的花费作对比。
解题方案
- 使用算术运算符、赋值运算符和三元运算符联合完成本题
操作步骤
- 使用算术运算符求出不使用优惠时的总价
- 使用三元运算符判断总价是否满足打折条件,并求出折后总价
- 使用算术运算符求出使用优惠价时的总价
- 使用三元运算符判断最终更合算的购买方式和花费
参考答案
public class Demo3 {
public static void main(String[] args) {
//1.求不使用优惠时的总价
double money1 = 24 + 8 + 3;
//2.判断折后总价
money1 = (money1 >= 30 ? money1 * 0.8 : money1);
//3.求使用优惠时的总价
double money2 = 16 + 8 + 3;
//4.判断两种花费哪个更少
double money = money1 < money2 ? money1 : money2;
//5.打印最终花费
System.out.println(money);
}
}