一、数据的表示详解
昨天我们学习了变量,我们知道变量可以用来记录数据的。那么数据在计算机底层是以什么形式表示的呢?下面我们就学习一下数据在计算机中的底层原理。
1.1 整数在计算机中的存储原理
其实任何数据在计算机中都是以二进制表示的。那这里肯定有人问,什么是二进制啊?所谓二进制其实就是一种数据的表示形式,它的特点是逢2进1。
数据的表示形式除了二进制(逢2进1),八进制(逢8进1)、还有十进制(逢10进1)、十六进制(逢10进1)等。
对于二进制绝大多数同学,应该是非常陌生的。 没关系!来,大家跟着我的思路,你就知道二进制是怎么表示数据的了。
1.二进制中只有0和1两个数
首先十进制的0和二进制的0是一样的,十进制的1和二进制的1也是 一样的。但是十进制中 有2,但是二进制中就没有2了
2.那么二进制是如何表示十进制的2呢?
1
+ 1
——————————
10 这里两个1相加,结果为2,由于二进制满2进1,所以最终结果10
3.那么二进制是如何表示十进制的3呢?
前面我们已经知道二进制10表示十进制的2,那么二进制10+1就表示十进制的3啊!
10
+ 1
—————————
11 十进制的3对应的二进制是11
4.那么二进制是如何表示十进制4的呢?
前面我们已经知道二进制11表示十进制的4,那么11+1就表示十进制的5啊
11
+ 1
—————————
100 十进制的5对应的二进制是100
你找到规律了吗? 你能不能依次写出5的二进制、6的二进制?
前面每算一个二进制数据都是采用+1的方式,逢2进1,一个一个算出来的。有没有更快的算出十进制对应二进制的方法呢? 这里学习一种方式:叫做除2取余法。
- 除2取余法
1.怎么做呢?
答:让十进制数据连续除以2,直到商为0,余数反转
2.举例1:把十进制6转换为二进制
商 余数
6/2 3 0
3/2 1 1
1/2 0 1
然后把余数反转:6对应的二进制是110
3.举例2: 把十进制13转换为二进制
商 余数
13/2 6 1
6/2 3 0
3/2 1 1
1/2 0 1
然后把余数反转:10对应的二进制是1101
4.练习1:你能把十进制7转换为二进制吗?
自己试试吧!
关于变量记录的数据在计算机中如何表示我们就先学习到这里。
- 计算机的最小存储单位
前面我们已经知道计算机表示数据是用二进制来的, 这里我又要抛出一个问题来了! 我现在想要在计算机中存储一个整数6,转换为二进制是110,那么计算机中只是存110吗三位数字吗? 其实不是的,计算机中最小的存储单位是字节(Byte),一个字节占8位(bit),也就是说即使这个数据不足8位也需要用8位来存储。
我们随便找到一个文件,看文件的属性,可以看到文件的大小都是以字节为单位的。
1.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 对应的十进制整数依次往后顺延
需要注意的是,在ASCII编码表中是不包含汉字的。汉字在其他编码表中,后面我们会单独介绍。关于字符在计算机中的存储学到这就可以了。
1.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张以上,由于人眼存在视觉暂留现象,人眼感受不到画面切换的时间间隔,就认为是连续的视频了。
- 声音的存储
了解过物理的同学肯定知道,声音是以波的形式传播的。我们可以把声波在表示在一个坐标系上,然后在坐标系上取一些点,把这些点的坐标值以二进制的形式存储到计算机中,这就是声音的存储原理。
1.4 数据的其他表示形式
- 二进制到十进制的转换
前面我们学习了十进制可以转二进制,采用的是除2取余法,那么我们反过来能不能把二进制转换为十进制呢?
这里给大家介绍一种计算方式叫做:8421码
为了便于理解,我们先在看一下十进制怎么转十进制,主要是为了让大家看到演化过程。
1.十进制转十进制
比如我们把12345进行分解:
12345 = 10000 + 2000 + 300 + 40 + 5
= 1*10^4 + 2*10^3 + 3*10^2 + 5*10^0
我们发现:
在十进制中如果把十进制的每一位从右往左从0开始编一个号,假设这一位数字是a, 那么这一位数表示的值就是:a*10^n;
----------------------------------------------------------------------二2.二进制转十进制:
类比十进制:
如果把二进制的每一位从从右往左0开始编一个号用n表示,假设二进制的每一位是a,
那么这一位表示的十进制值是:a*2^n
1)假设二进制的每一位都是1:
128 64 32 16 8 4 2 1 每一位表示的十进制:a*2^n
7 6 5 4 3 2 1 0 编号:n
1 1 1 1 1 1 1 1 二进制的每一位:a
二进制 十进制
11111111 = 1*2^7 + 1*2^6 + 1*2^5 + ... + 1*2^0
= 128 + 64 + 32 + ... + 1
= 255
2)假设二进制的为0010001
128 64 32 16 8 4 2 1 每一位表示的十进制:a*2^n
7 6 5 4 3 2 1 0 编号:n
0 0 1 0 0 0 0 1 二进制的每一位:a
二进制 十进制
00001101 = 0*2^7 + 0*2^6 + 1*2^5 + ... + 1*2^0
= 0 + 0 + 32 + ... + 1
= 33
3)8421码:从右往左给二进制的每一位数依次按照1 2 4 8...标记
128 64 32 16 8 4 2 1
0 0 1 0 0 0 0 1
-----------------------------
只需要将1位上的数字加起来,就是二进制对应的十进制
二进制 十进制
00001101 = 8+4+1
= 13
0000111 = 4+2+1
= 7
0001111 = 8+4+2+1
= 25
- 二进制转八进制
前面我们说计算机中数据都是采用二进制来存储的,但是二进制阅读和编写起来都不太方便。为了便于阅读和书写,又推出了八进制、十六进制。
1.运算规则:
把二进制的每三位一组合,然后对每三位用8421码进行计算,最后拼接到一起
原因:因为111,的值是7, 再大满7就需要往进位了。
2.把二进制11001110转换为八进制数据
01 100 001 二进制每三位一组合
1 4 1 每一组进行8421码运算
----------
八进制:141
- 二进制转十六进制
1.运算规则:
把二进制的每四位一组合,然后对每四位用8421码进行计算,最后拼接到一起
原因:因为1111,的值是15, 再大1满16了就需要往进位了。
2.举例:把二进制11001110转换为十六进制数据
0110 0001 二进制每四位一组合
6 1 每一组进行8421码运算
----------
十六进制:61
3.练习:把111100转换为十六进制
0011 1100
3 12 由于十六进制中有a,b,c,d,e,f分别表示10,11,12,13,14,15
-----------
十六进制:3c
1.5 不同进制在Java程序中的书写格式
System.out.pirntln('a'+1); //98
System.out.pirntln(0b01100001); //97
System.out.pirntln(0141); //97
System.out.pirntln(0x61); //97
二、数据类型详解
在前面的课程中,我们学过了变量的定义,在定义变量时我们是要声明数据类型的,这里的数据类型是用来规定变量存储什么类型的数据。
比如int a = 10;
这里的int
就是限制变量只能存储整数; 除了int这种数据类型Java还提供了很多其他的数据类型。Java的数据类型整体上来说分为两大类: 基本数据类型、引用数据类型。
我们今天主要学习基本数据类型,基本数据类型一共有4类8种,每一种数据类型占用的内存空间不一样,能够表示的数据范围也不一样。如下图所示
需要我们注意的是,随便写一个整数或者小数的字面量,它也是有默认数据类型的
- 比如23,它默认就为int类型;如果加上后缀L,则为long类型;
- 比如23.8,它默认为double类型;如果加上后缀F,则为float类型;
下面定义各种类型的变量,将这8种基本数据类型都用一下。
public class TypeDemo1 {
public static void main(String[] args) {
// 目标:掌握8种基本数据类型,用来定义变量。
// 1、整型
byte number = 98;
System.out.println(number);
short number2 = 9000;
int number3 = 12323232; // 默认
// 注意:随便写一个整型字面量,默认是int类型的,73642422442424虽然没有超过long的范围,但是它超过了本身int的范围了。
// 如果希望随便写一个整型字面量是long类型的,需要在其后面加上L/l
long number4 = 73642422442424L;
// 2、浮点型
//注意:
//随便写一个小数字面量,默认当成double类型对待的,
//如果希望这个小数是float类型的,需要在后面加上:F/f
float score1 = 99.5F;
double score2 = 99.8; // 默认定义方案。
// 3、字符型
char ch1 = 'a';
char ch2 = '中';
char ch3 = '国';
// 4、布尔型
boolean b1 = true;
boolean b2 = false;
// 引用数据类型:String.
// String代表的是字符串类型,定义的变量可以用来记住字符串。
String name = "黑马";
System.out.println(name);
}
}
三、数据类型转换
3.1 自动类型转换
各位同学,接下来我们来学习类型转换的知识。为什么要学习类型转换呢?因为在我们实际开发中可能存在将某种类型变量的值,赋值给另一个类型的变量;也可能存在多种数据类型的数据一起运算的情况。
在以上情况中,其实都会涉及到类型转换。类型转换的形式总体分为2种,一种是自动类型转换,一种是强制类型转换。 这里先学习自动类型转换
- 什么是自动类型转换呢?
答:自动类型转换指的是,数据范围小的变量可以直接赋值给数据范围大的变量
byte a = 12;
int b = a; //这里就发生了自动类型转换(把byte类型转换int类型)
- 自动类型转换的原理是怎样的?
答:自动类型转换其本质就是在较小数据类型数据前面,补了若干个字节
除了byte和int之间的转换之外,其他类型也可以转换,转换顺序如下图所示
下面我们通过代码演示一下,自动类型转换的各种形式。
public class TypeConversionDemo1 {
public static void main(String[] args) {
// 目标:理解自动类型转换机制。
byte a = 12;
int b = a; // 发生了自动类型转换了
System.out.println(a);
System.out.println(b);
int c = 100; // 4
double d = c;// 8 发生了自动类型转换了
System.out.println(d);
char ch = 'a'; // 'a' 97 => 00000000 01100001
int i = ch; // 发生了自动类型转换了 => 00000000 00000000 00000000 01100001
System.out.println(i);
}
}
- 表达式的自动类型转换
自动类型转换还有另外一种形式,就是表达式的自动类型转换。所谓表达式指的是几个变量或者几个数据一起参与运算的式子。
如果同一个表达式中,出现不同类型的变量或者数据一起运算,这种情况下运算结果是一个什么数据类型呢?需要遵守下面的两条运算规则:
1.多种数据类型参与运算,其结果以大的数据类型为准
2.byte,short,char 三种类型数据在和其他类型数据运算时,都会转换为int类型再运算
接下来我们来看代码演示,自己试一试
public class TypeConversionDemo2 {
public static void main(String[] args) {
// 目标:掌握表达式的自动类型转换机制。
byte a = 10;
int b = 20;
long c = 30;
long rs = a + b + c;
System.out.println(rs);
double rs2 = a + b + 1.0;
System.out.println(rs2);
byte i = 10;
short j = 30;
int rs3 = i + j;
System.out.println(rs3);
// 面试笔试题: 即使两个byte运算,结果也会提升为int
byte b1 = 110;
byte b2 = 80;
int b3 = b1 + b2;
System.out.println(b3);
}
}
3.2 强制类型转换
前面我们学习了自动类型转换,我们知道可以将数据类型小的数据可以直接赋值给数据范围大的变量。 那反过来,能不能将数据范围大的数据直接赋值给数据范围小的变量呢? 答案是会报错。
因为数据范围大的数据,赋值给数据范围小的变量,它有可能装不下;就像把一个大桶的水倒入一个小桶中,有溢出的风险。
- 什么是强制类型转换
但是你强行将范围大的数据,赋值给范围小的变量也是可以的,这里就需要用到强制类型转换。下面是强制类型转换的格式
目标数据类型 变量名 = (目标数据类型)被转换的数据;
下面是强制类型转换的代码演示
public class TypeConversionDemo3 {
public static void main(String[] args) {
// 目标:掌握强制类型转换。
int a = 20;
byte b = (byte) a; // ALT + ENTER 强制类型转换。
System.out.println(a);
System.out.println(b);
int i = 1500;
byte j = (byte) i;
System.out.println(j);
double d = 99.5;
int m = (int) d; // 强制类型转换
System.out.println(m); // 丢掉小数部分,保留整数部分
}
}
强制类型转换的原理
强制类型转换的原理,其实就是强行把前面几个字节砍掉,但是有数据丢失的风险。
到这有关数据类型和数据类型转换的内容,我们就学习完了。大家能够知道什么时候会发生自动类型转换,以及如何进行强制类型转换就可以了。