CPU

是啥:CPU是能够让你的计算机叫计算机的核心组件,但是它却不能代表你的电脑,CPU与计算机的关系就相当于大脑和人的关系。

核心:CPU的核心是从程序或应用程序获取指令执行计算。此过程可以分为三个关键阶段:提取,解码和执行

功能:从系统的内存中提取指令,然后解码该指令的实际内容,然后再由CPU的相关部分执行该指令。<u>(后续详细介绍,先知道有这个东西,到时候再往回看......)</u>

image-20200725003709553

机器语言

我们现在使用的是电子计算机,对于电子计算机来说,他是由电子器件来构成的,这也就决定了他只能识别高低电平。

对于每一种处理器CPU来说, 由于硬件设计和内部结构的不同, 就需要用不同的电平脉冲来控制, 使它工作。 所以每一种CPU都有自己的机器指令集, 也就是机器语言

为了方便控制计算机工作,人类采用0,1分别代替低电平和高电平。对于0和1来说,由于长度不定,和排列组合方式不同,可以产生很多种不同的串。这些不同的串也就是上述说的机器语言,用来控制CPU的工作。

假如我想通过8086CPU完成运算s=768+12288-1280,他的机器语言如下:

101110000000000000000011
000001010000000000110000
001011010000000000000101

机器语言的缺点很明显。

①要完成一个很简单的运算却需要写这么多的0和1,一旦有一个写错了,可能会导致不能得到正确结果,而且很难debug

②而且由于他的CPU相关性,也就是说不可移植,我在我这台电脑写的程序可以运行,但是另外一台电脑不一定能运行!也就是说存在兼容性问题。什么是CPU相关性?上述已经说到,由于CPU硬件设计和内部结构的不同, 就需要用不同的电平脉冲来控制。CPU的机器语言和CPU的型号是息息相关的,同一个机器语言在不同的CPU含义可能不一样

汇编语言

为了解决机器语言存在的第一个问题“这么多的0和1”,汇编语言出现了。(注意:对于汇编语言还是不可移植性的。)

例如: 机器指令 1000100111011000 表示把寄存器 BX 的内容送到 AX 中。 汇编指令则写成 mov ax,bx。这样的写法与人类语言接近,而且他是有含义的,mov代表着英文单词的move, 便于阅读和记忆。

然后,程序员们就可以用汇编指令编写源程序。 但是,计算机能读懂的只有机器指令, 那么如何让计算机执行程序员用汇编指令编写的程序? 这时,就需要有一个能够将汇编指令转换成机器指令的翻译程序, 这样的程序我们称其为编译器

image-20200725002539922

高级语言

为了解决汇编语言存在的不可移植性,并且进一步优化程序员编写代码体验,高级语言出现了!例如:C/C++,Java,Python等等。

高级语言的组成:

  • 编译型:C/C++
  • 解释型:Python,PHP
  • 既编译又解释型:Java(JDK编译,JVM解释并运行)

和汇编语言执行一样,为了让编译型高级语言执行,会有自己的编译器把他翻译成汇编指令(具体内容可以去看《编译原理》),然后汇编指令再翻译成机器语言最后被CPU执行(具体内容可以去看《8086微机原理》和《汇编语言》)。

image-20200725004604897

而对于解释型高级语言,靠的是解释器解释(相当于上图第一个编译器),然后解释器通过后续的编译器再翻译成机器语言。

一般来说解释型语言的跨平台性更强,因为他最终翻译成机器语言是他的解释器来完成的,对于解释型语言他自己本身就针对不同的平台,例如Linux,windows会有自己的适配规则,帮我们屏蔽了不同系统的差异

举个例子,windows下的原生C++程序只能在windows平台下运行,他不能移植到linux下运行,更不用说安卓平台了。

对于Java来说,Java的JVM就是整个Java生态的核心!Java不仅仅是一门语言,而是一种很完整很成熟的生态,包括:Java语言本身,JVM(有解释器,屏蔽操作系统差异),JDK,JRE,各种成熟的第三方框架等等。

正因为Java生态的JVM技术,使得Java语言既拥有了编译型语言的强类型等优点,还具有解释型语言的“一次编码,到处运行”的优点,让程序员更加集中精力于业务开发,而不是去处理兼容性!

内存

问题来了,以C/C++为例,编译好的二进制程序是在硬盘上的,他怎么进入到CPU中执行呢?这时候就出现了他的中间层:内存,他是硬盘上的程序和CPU沟通的桥梁

计算机中所有程序的运行都是在内存中进行的,其作用是存放CPU中的运算数据,以及与硬盘等外部存储设备交换的数据。只要计算机在运行中,内存就会把需要运算的数据调到CPU中进行运算,当运算完成后CPU再将结果传送岀来。

  • 内存结构:

内存是按字节编地址的,也就是说每一个格子可以存放1Byte的数据,同时每个格子会有相应的地址与他对应,可以类比房屋和门牌号。

image-20200725151159054

C/C++下内存的操作

C/C++程序编译时当前程序被分配的内存可以分为5大存储区:(实际上还是一格一格的连续单元,只不过逻辑上划分了几个不同的区域)

  1. 栈区(stack) -- 编译器自动分配释放,主要存放函数的参数值,局部变量值等;
  2. 堆区(heap) -- 由程序员分配释放;
  3. 全局区或静态区 -- 存放全局变量和静态变量;程序结束时由系统释放,分为全局初始化区和全局未初始化区;
  4. 字符常量区 -- 常量字符串放与此,程序结束时由系统释放;
  5. 程序代码区-- 存放函数体的二进制代码 (不是重点,大概了解一下就好了,主要是栈和堆)

image-20200725181007583

int a=0;    //3.全局初始化区
char *p1;    //3.全局未初始化区
void main(){
    int b = 10;     //1.栈
    char s[]="bb";    //1.栈
    char *p2;         //1.栈
    int  *p3=new int(100); //p3在1.栈区   int(100)这100个Int型的连续空间在2.堆区
    static int c=0; //3.全局区
    p1=(char*)malloc(10);     //10个字节区域在2.堆区
    free(p1);            //释放2.堆区的空间
}

程序代码区的代码执行过程:

核心:提取,解码和执行。

过程:CPU通过地址总线传输地址,然后定位到内存相应地址,然后读取指定内存单元的指令并通过数据总线传回到指令缓冲队列(先进先出),然后交给执行控制器去执行

image-20200725152953603

数据结构

知识体系:

说明:索引存储和散列存储本质上还是顺序存储。所以物理存储可以分为顺序存储链式存储两大类。

image-20200725011450217

逻辑结构:即数据元素间的逻辑关系。只抽象反映数据元素集合的结构,不管其存储方式。逻辑结构有线性结构和非线性结构两种。

image-20200725172828346

a:一对一,例子:线性表,栈和队列(操作受限的线性表)

b:一对多,例子:树,二叉树

c:多对多,例子:图

d:没有任何关系

物理结构:即数据及数据元素间的关系在计算机内存(计算机内存单元布局是线性的)中的表示。主要的存储方式有顺序存储链式存储两种。

  • 顺序存储:开辟的是连续的空间

image-20200725172909249

  • 链式存储:开辟的空间既可以是离散型的,也可以是连续型的。不过一般是离散的。

image-20200725172919416

把逻辑结构通过物理结构表达出来的例子:

对于树这种逻辑结构来说,他不是一个线性的结构,而我们的内存是一个线性结构,该使用什么办法把树型映射到线性的内存单元中呢?

答案是:使用指针来表示他的逻辑关系,注意这里的指针是一个抽象的概念,他既可以指地址指针,也可以指数组下标。对于顺序存储来说,这里的指针指的是数组下标。而对于链式存储来说,指的是地址指针。

下图为顺序存储树这种逻辑结构,下标是数组的下标,data是该结点存放的数据,parent是他爹的指针(数组下标)。

image-20200725173236679

顺序存储(数组)和链式存储(链表)的比较:

image-20200726021953538

©著作权归作者所有

发表评论

正在加载 Emoji