C语言知识体系梳理讲义(一)
这里引用了《深入理解计算机系统》、《C和指针》、《大话设计模式》等书
开篇说点
- 前几天我也向一些同学咨询了想要了解的以及有疑惑的地方。今天我想和大家从两个方面对C/C++语言进行一次全面的框架梳理,并通过一些经典的运用范例讲解进一步了解C语言。
- 那么我们先解决一些问题,
解决问题
有同学问我“我C语言基础都会了,而且考试的时候选择题答的都不错,可是在编程题的时候却是寸步难行,一点头绪都没有,好不容容易写完了但是却全是bug,bug又都是我看不懂的问题我就只能推翻重写。”我们可以先解决一下这个问题
如何编写程序以及什么是面向对象?什么是面向过程?
我认为编写程序就是一种解决问题的双向思维:自上而下分解问题,自下而上解决问题。不论是在写算法解决问题还是写框架满足应用需求。我们都要反复的进行这种思维。
第一个例子
举一个《大话设计模式》里面的简化例子,如何设计一个从文件输入输出学生学籍信息结构体的应用。那么在C语言具备一定经验的人来说,一般会这样思考。我们先设计一个满足条件的结构体,在程序开始的时候进行初始化,之后打开文件,循环输入学生学籍信息满足输入信息后再跳出循环,之后开启下一循环从文件输出到cmd窗口,最后关闭文件。但是这样的鲁棒性以及效率并不高。那么我们可以细化一些操作。在初始化的时候我们将牺牲一些空间和时间去满足一些功能并弥补一些问题。通过计算机存储的知识,处理器的读取速度由栈(L1)、堆(L2)、文件(L3)依次减缓。
这是从《深入理解计算机系统》里面截的图,顺便说一句我特别鼓励大家多去图书馆去借书看书,白嫖的知识不香嘛,但是还是希望不要在书上涂涂画画的,铅笔也不行。这本书过了十多年了这个铅笔印我怕一擦就碎掉了。一般来说L2是L1的5到10倍而从磁盘中读取比从栈中读取慢了100到200倍(一般是3000个指令周期)。由此我们返回到刚才的问题在开始之初我们定义一个长度待用户确定的堆,并且设置一个预先确定的数组功能为循环队列。在用户输入时优先输入到数组中(称为入队),等待数组中数据存满后弹出(称为出队),输入到堆中。其中队的作用是提高速度并且提供一定长度下·用户反悔功能,堆的作用是提高工作效率。这样在输出的过程中也是由CPU读取堆内数据,缩短用户使用时间。当一个用户结束使用时,下一个用户开始访问的时候就可以跳出到另一个线程中消化上一次使用的记录。
这就是我们按照一个有经验的人完成的面向过程开发的过程。但是对于一个不了解过程甚至不了解C语言的人该怎么办呢?我们再举一个《大话设计模式》里面的问题
第二个例子
现在假设一个没有经验的人,要辅助上边的人编写一个计数器的功能函数或者说是一个类。这个该怎么想?(挺几秒)那么我们就会想,我需要一个计数器,这个计数器应该有这样的一个功能,在他结束一次用户访问后在用户访问记录需要加一,在一次输入的时候输入记录也会加一。另外最好还要有一个计数器清零的功能。当然如果计数器有一个可以设置为任意值的功能的话我就可以作弊了。对于一个没有设计过这类函数的人来说他不会想到对文件读取、对数据库读取需要什么操作,但是他会考虑这个角度我有什么需求,我的业务逻辑是什么,我的软件应该有什么功能。这样我们面向对象分析问题的思路就清晰了:首先我们需要一个计数器类(你也可以简单理解为是函数组这一类函数组共享一部分数据)有两个必须的和两个可选的函数:
addCount();//计数器增加方法
getCount();//取出计数器值的方法
resetCount();//计数器清零的方法
setCount();//设置计数器为相应值的方法
这样我们的需求明白了,面向对象的过程也结束了。我们就可以从过程方面由下向上的解开一个一个小问题一个一个函数。
下面是第二章《C语言知识体系梳理讲义(二)》