老衲 又有不懂得了,问了这么一段话,很值得思考呀
#include <stdio.h> int main(int argc,const char* argv[]) { printf("hello,world"); return 0; }
老衲说,你看看这个,我上c语言的时候,老师就直接把这个写出来了,也没告诉我这为啥这么写呀!
不着急,来听我,慢慢絮叨!
上面这段是什么?难道是程序吗?其实并不是,上面这段是代码,那么程序又是什么呢?
程序是指示计算机每一步动作的指令,也是一个可执行文件
是不是有点纳闷,其实啊,这个程序譬如全运会,音乐会的程序等,指的是“行事的先后次序”,计算机的程序也是一样的道理!
那么程序是由什么组成的呢? 程序是指令和数据的组合体
是不是有发问数据会是什么呢?没关系看另一篇博客(此处是超链接)
这块我们简单的说一下:指令是printf ,“hello ,world”是数据
老衲说:我明白了,那么那么我写的这段代码,是如何让计算机变成程序,并让他运行的呢?
有意思了这,开始举一反三发问了,这块我来分成两部分来介绍一下:
咳咳!开唠!
首先,程序员用c语言(这种高级语言)编写出来程序
这块我们就能看出来是怎么个过程了。。。。
其实这个代码变成程序的话,虽然图上面显示了1~2,只有两步,但是呢实际上是4步!
预处理呢,又分为(还有很多,有兴趣可以看看程序员的自我修养这本书)
宏替换(就是把#define 的内容替换掉),
删除注释
还有最重要的一点就是#include <stdio.h> 把这个头文件给展开了
那么我们就来看看预处理后的文件,长什么样子! (在linux底下,通过gcc hello.c -E hello.i)来查看
gcc 是个啥不懂了吧(那么关注下一篇博客)
#include <stdio.h> //我是老衲的第一个程序 #define laona 521 int main() { int a =laona; printf("hello,%d",a); return 0; }
这就能看出来了,把stdio.h这个头文件给包含进来了加了700多行,然后还把注释删了,然后海拔laona 这个宏定义给替换了,奇妙不奇妙!
2.编译
把上面这个预处理的文件,通过语法分析,语义分析等生成汇编语言!
mov enx,dword ptr [edp-8]
诸如这样的代码,这块了解就好了
3.汇编
到重点了,这块呢,就把这个汇编语言,翻译成0101010101的机器语言,这样才给了计算机去让他按照咱们写的代码思路去跑!
还有一步就是链接,这个链接呢!
我准备给老衲将一个故事:
很久很久以前,在一个非常遥远的赛博坦星系.......人们编写程序时,将所有的源代码都放入一个文件,发展到后来一个程序源代码的文件长达数百万行,以至于已经没有 人具备维护这个程序的能力。人们开始寻找新的办法,就这样一场革命,即将爆发..........
在最开始的时候啊,程序员先把一个程序在纸上写好,当时没有高级语言,只有机器语言,甚至连汇编都没有。那么当程序需要运行的时候怎么运行呢,那就需要程序员人工将写好的程序写入到存储设备上,最开始的存储设备之一就是纸带。也就是在纸带上打孔。
可以看出来啊:纸带上每行由8个孔位,每个孔位代表一位,穿孔代表0,未穿孔代表1
这也就是纸带上每条指令是1个字节,也就是8位.
比如你看第一条指令是程序的入口地址,比如main函数
0001 表示跳转指令,跳转到那块地方呢?后面跟这个0100,就是跳转到这儿
0100也就是第五条指令的位置,有了这块的理解,老衲试着理解理解函数之间跳转呀
其实呢,这也就是后来汇编语言的演练,其实上面的 mov也是一种跳转指令,他是把0001换成了高级语言去表示而已。
链接,其实往小了说,就是把很多个源文件头文件都连在一起,组成一个可执行的文件,但这块涉及到了静态链接和动态链接(以后更新一篇博客来仔细讲讲)
老衲发话了:我懂了,把代码变成程序就是,通过预处理把咱写的代码先格式化一下变成机器能翻译的高级语言,然后通过编译,让计算机去分析咱写的程序,就类似于咱们写了让他打印一句话,他翻译成汇编指令,然后在通过汇编翻译成机器语言,这样他就能跑了!
老衲就是聪明,看懂了
不要着急,这块也是很有意思的,虽然说代码经过了预处理、编译、汇编、链接,成了程序(可执行文件),但是呢,什么是计算机的大脑呢?
老衲说:CPU? 真聪明
CPU是中央处理器的缩写,相当于计算机的大脑,他的内部由数百万至数亿个晶体管构成。当然仅限于理解到这,那就没必要提及这个cpu了
CPU负责的就是解释和运行最终转换成机器语言的程序内容。
CPU由4部分组成:
1. 寄存器 用来暂存指令、数据等处理对象
2. 控制器:负责把内存上的指令、数据读入寄存器
3.运算器:负责运算从内存中读入寄存器的数据
4.时钟:负责发出CPU开始计时的时钟信号(这块是linux信号这块)
这底下呢,又是如何解释呢?其实咱编译好的程序,如何把它从硬盘上装载到内存中,那么咱代码在内存中又是如何分布的呢?(这块后续写一篇博客,叫做操作系统内存分布,以及虚拟内存,cpu是如何读取内存上的程序的)
总之,在这块我们先知道了,CPU要处理咱写的代码,就要通过控制器读取内存上的程序放到cpu里面去运算,然后在返回处理后的结果。
结束语:老衲 ,你理解了吗?