当前课程知识点:基于Linux的C++ > 第一讲 C/C++基本语法元素 > 1.2 程序设计的基本概念 > LinuxCPP0102
我们首先来看程序设计的基本概念
什么叫程序呢
我们给程序下一个定义
程序就是一系列遵循一定的规则
并且能够正确地完成
特定功能的代码或者指令序列
讲起来好像很罗嗦
但讲清楚了程序的一些基本的概念
首先一条
它是一系列的指令序列
一条计算机指令接着一条计算机指令
这些指令连接在一起
形成一个指令序列
最终能够完成一个特定一个功能
这种指令序列肯定要按照
一个特定规则来组织
不同的操作系统
不同的硬件架构的指令都不一样
所以必须针对它
来完成这个指令序列的编写
这个东西就叫程序
这就是我们说的编程
就是要解决这样一个问题
程序通常包括两个部分
一个我们称之为数据结构
一个称为算法
所以有的程序员就会说
程序是什么呢
程序就等于数据结构加上算法
这两个部分
有了这个程序的概念
我们有一个任务
我就要开发这个程序
实现它 解决它
这个就叫程序设计
解决这个任务 要提供一个工具
这个工具有特定的规则
来说明我们怎么解决它
你怎么使用这个工具
我按照我的任务的需要
设计数据结构和算法
然后把这个代码写出来
最后验证 测试代码的正确性
然后执行得到正确的结果
整个过程走下来
我们称它为程序设计
整个程序设计过程中
必须遵循一定的规则和方法
这种东西称为程序设计方法学
没有一定的规则
程序写起来会很困难
因为相当多的程序是大而复杂的
每一条指令(执行时间)又非常非常短
指令的条数又非常非常地多
短到什么程度 短到它是纳秒级的
10的-9次方秒这个级别
所以这个程序呢
非常非常地复杂
你如果不按照一个特定的
程序设计方法学
来对这个程序进行设计
最终你的程序稍微复杂一点
你就解决不了
这是非常非常重要一个地方
程序设计语言就是我刚才讲的
编写程序代码
肯定要按照一个特定规范来
有特定的语法规则
有语法所对应的意义
还有它所使用的环境
这种东西称之为语法 语义和语用
这就是我们的程序设计
程序设计包括两个部分
算法加数据结构
什么叫算法呢
算法是描述问题的解决方法和步骤
问题来了
我怎么去解决它
第一步应该做什么
第二步应该做什么
第三步应该做什么
这是问题解决的方法和步骤
这个就叫算法
对于计算机算法来讲呢
它不允许存在二义性
不能够给我一个模糊的
有两种解释这是不可以的
计算机是一个机械计算过程
它的逻辑计算是非常非常机械的
绝不允许出现二义性
算法的整个设计过程本身
应该是逐步求精的
咱们也不能指望写一个算法
来解决一个实际的问题
我一下子就把这个算法做完了
一调试 正确
一般情况下这做不到
尤其是初学者
程序写出来
觉得自己解决问题了
然后一编译出很多个编译错误
一下子就很沮丧
这是非常非常正常的一件事情
对于初学者来讲
很难在一开始写一个程序
一个错误都没有
其实程序写多了以后
你就会很有经验
如果程序一开始很多个错误
别慌张 一个一个去调试
改正它 修正它就OK了
很多时候写出来程序
一个编译错误都没有
你觉得很高兴
最后程序一运行出来
结果不对
那才是很郁闷的事情呢
因为它没有语法错误
如果结果不对
只说明它有逻辑错误
逻辑错误很难查的
所以写程序算法设计都要有一个
逐步求精的一个过程
我先完成一个初步的算法
然后一步一步不断去修正它
改进它 升级它
任务要分解开
然后逐步求精
这是我们算法设计基本逻辑
后面我们会专门
讨论我们怎么设计一个优良的算法
同学们会通过例子
看到几种不同算法设计方案
算法执行效率千差万别
我们怎么样在程序设计语言里面
来描述算法呢
我们用语言来编写算法步骤
一条接着一条指令去写
那不就行了吗
在我们实现或者思考这个算法过程中
一开始就在那儿写程序不太妥当
对吧 没有想清楚程序
逻辑是什么 就开始编码
这是一个不好的编程习惯
所以 计算机理论界提供了好几种方案
来描述你的算法
最常用的是流程图和伪代码
伪代码我们平时用得多
流程图就是画图
把你的算法逻辑绘出来
那个图很美观
我们后面也会介绍
第二个方面就是数据和数据结构
什么是数据
数据就是程序操作的对象
对象两个意思 对吧
一个特指恋爱时的对方
这跟咱们没关系
第二 行动或思考的目标
我们的程序里面
程序操作对象
就是我们行动和思考的目标
这一点不仅仅C/C++程序员的初学者
就是很多已经很有经验的程序员
都会按照这个方式来做
我把这个思维模式叫做数据中心主义
这是很多同志
在一开始学习C++编程的时候
不自觉的思维习惯
不太容易纠正过来
它有什么好处呢
好处就是我解决这个问题
我怎么用数据来表达它
这个目标是清晰
这是好处
它坏在什么地方呢
坏在当我这个问题
没有想清楚的时候
这个数据的表达可能是不恰当的
当我在一个
不恰当地基上面写算法的时候
最终发现这个数据表达是错误的
那么我所想的算法基本上是没用的
你做的是无用功
程序越大越复杂
这个问题越严重
严重到我们这个程序
最终没有办法解决
所以我们最后才把它变成
我们称之为算法中心主义的一个东西
待会我们再来讲
回过头来说这个数据
我们程序中操作的数据
就一个对象吗 不是的
俩对象吗 也不是的
可能会包含很多个对象
互相之间是有一定关系的
这个关系你不把它建构出来
你的程序数据对象就是零散的
它们就不能够深刻表达
我们现实世界中的这种联系
事物是普遍联系的呀 对吧
你要把这个东西给我关联起来
这就是数据结构
我要把它在程序中表达出来
这是非常非常重要的
数据结构和算法关系密切
正常情况下
一个数据结构应该有一个
和它相配套的算法
一个算法应该有一个
和它相适应的数据结构
两者是一种紧密联系的关系
完全把这两者给割裂
算法就是算法
数据结构就是数据结构 是不对的
这是二分法
程序等于数据结构加算法
如果你认为两者一点关系都没有
那不对的
它不符合马克思主义哲学原理
说的很清楚
两者是紧密相连的
而且在某些情况下还会互相转化
我们后面会讨论这个问题
对于大家理解编程
会非常非常有用
这是非常重要一个地方
数据结构和算法是密切相关的
一个良好的结构
可以让你的算法更简单
反过来 一个恰当的算法
可以让你的数据结构更加清晰
非常非常重要
现在我们有了程序 算法
和数据结构概念
那么我们回过头来说
我们怎么做程序设计
这门课程实际上涉及到
三种形态的程序设计
一个是结构化的程序设计
一个是面向对象的程序设计
一个是泛型编程
结构化程序设计是早期
从C那里面继承过来的
你必须会用
哪怕你最后写的是面向对象程序
和泛型程序
你使用到的代码实现还是结构化的
所以这个基础不能丢
它里面包括一些数据结构
程序流程的控制
函数和算法实现 程序的组织
复合数据型
这些都是结构化程序设计里面的内容
同学们一定要精通和掌握
这是一个
第二个这就是面向对象的程序设计
我刚才不是提了一下
我们说数据中心主义吗
你行动和思考的目标叫对象
我们现在面向对象程序设计
做了一个很巧妙的改变
把数据对象和这个对象的行为
也就是算法
合在一块
我把它辩证统一
合一块有什么好处
现在你行动和思考的目标
是对象 没错
但是你不再是数据中心主义了
你是对象中心主义了
你行动和思考的目标
不仅仅数据和数据结构
还包括了在这个数据和数据结构上面
可以执行的操作
也就是它的行为
这实际上是我们完成
从数据中心主义向算法中心主义
这样一个转化
这非常非常重要
为什么我们要做这样一个转变
其实同学们仔细想一想就很清楚了
一个程序代码中
要么是算法
要么是数据结构
你觉得在程序里面
哪一个东西是不太容易变的
是算法容易变动呢
还是数据结构容易变动
那一定是算法不太容易变动
而数据结构是易变的对吧
我可以写一个程序操作很多个数据
每个数据都在变化
但算法本身一点都不用改 对不对
那你写程序的时候
你应该首先攻克什么东西呢
当然首先应该攻克那些
不太容易变化的地方啊
我先把它固定下来
然后去攻克那些容易变动的地方
对不对
这就是我们为什么要从
结构化程序设计
改成面向对象程序设计
一定要从数据中心主义
向算法中心主义转变
你要走极端肯定不对
我们应该讲中庸对不对
那么我们就应该是对象中心主义
两者融合在一起
这就是我们面向对象程序设计的由来
或者产生面向对象程序设计的
根本原因
就是为了解决大程序开发的时候
原来的结构化程序设计
解决不了的问题
程序太大 规模太大 控制不住
第三类就是泛型编程 它很特殊
和面向对象架构不太一样
我们后面会专门讨论泛型编程
怎么使用标准模板库
来写优雅的C++泛型程序
怎么设计自己的泛型程序
包括泛型类 泛型函数
-1.1 提纲
-1.2 程序设计的基本概念
-1.3 简单C/C++程序介绍
-1.4 程序设计的基本流程
-1.5 基本语法元素
-1.6 程序设计风格
-1.7 编程实践
-第一讲 C/C++基本语法元素--编程实践提交入口
-2.1 提纲
-2.2 结构化程序设计基础
-2.3 布尔数据
-2.4 分支结构
-2.5 break语句
-2.6 循环结构
-2.7 编程实践
-第二讲 程序控制结构--编程实践提交入口
-3.1 提纲
-3.2 函数声明、调用与定义
-3.3 函数调用栈框架
-3.4 编程实践
-第三讲 函数--编程实践提交入口
-4.1 提纲
-4.2 算法概念与特征
-4.3 算法描述
-4.4 算法设计与实现
-4.5 递归算法(一)
-4.6 递归算法(二)
-4.7 容错与计算复杂度
-4.8 编程实践
-第四讲 算法--编程实践提交入口
-5.1 提纲
-5.2 库与接口
-5.3 随机数库(一)
-5.4 随机数库(二)
-5.5 作用域与生存期
-5.6 典型软件开发流程(一)
-5.7 典型软件开发流程(二)
-5.8 编程实践
-第五讲 程序组织与开发方法--编程实践提交入口
-6.1 提纲
-6.2 字符
-6.3 数组(一)
-6.4 数组(二)
-6.5 结构体
-6.6 编程实践
-第六讲 复合数据类型--编程实践提交入口
-7.1 提纲
-7.2 指针基本概念
-7.3 指针与函数
-7.4 指针与复合数据类型(一)
-7.5 指针与复合数据类型(二)
-7.6 字符串
-7.7 动态存储管理(一)
-7.8 动态存储管理(二)
-7.9 引用
-7.10 编程实践
-第七讲 指针与引用--编程实践提交入口
-8.1 提纲
-8.2 数据抽象(一)
-8.3 数据抽象(二)
-8.4 链表(一)
-8.5 链表(二)
-8.6 链表(三)
-8.7 链表(四)
-8.8 函数指针(一)
-8.9 函数指针(二)
-8.10 抽象链表(一)
-8.11 抽象链表(二)
-8.12 编程实践
-第八讲 链表与程序抽象--编程实践提交入口
-9.1 提纲
-9.2 程序抽象与面向对象
-9.3 类类型
-9.4 对象(一)
-9.5 对象(二)
-9.6 类与对象的成员(一)
-9.7 类与对象的成员(二)
-9.8 类与对象的成员(三)
-9.9 继承(一)
-9.10 继承(二)
-9.11 继承(三)
-9.12 多态(一)
-9.13 多态(二)
-9.14 编程实践
-第九讲 类与对象--编程实践提交入口
-10.1 提纲
-10.2 四则运算符重载(一)
-10.3 四则运算符重载(二)
-10.4 关系与下标操作符重载
-10.5 赋值操作符重载(一)
-10.6 赋值操作符重载(二)
-10.7 赋值操作符重载(三)
-10.8 赋值操作符重载(四)
-10.9 赋值操作符重载(五)
-10.10 流操作符重载(一)
-10.11 流操作符重载(二)
-10.12 流操作符重载(三)
-10.13 操作符重载总结
-10.14 编程实践
-第十讲 操作符重载--编程实践提交入口
-11.1 提纲
-11.2 泛型编程概览
-11.3 异常处理机制(一)
-11.4 异常处理机制(二)
-11.5 运行期型式信息(一)
-11.6 运行期型式信息(二)
-11.7 模板与型式参数化
-11.8 题外话:术语翻译
-11.9 泛型编程实践(一)
-11.10 泛型编程实践(二)
-11.11 泛型编程实践(三)
-11.12 泛型编程实践(四)
-11.13 泛型编程实践(五)
-11.14 泛型编程实践(六)
-11.15 泛型编程实践(七)
-11.16 泛型编程实践(八)
-11.17 泛型编程实践(九)
-11.18 泛型编程实践(十)
-11.19 编程实践
-第十一讲 泛型编程--编程实践提交入口
-12.1 提纲
-12.2 程序执行环境(一)
-12.3 程序执行环境(二)
-12.4 程序执行环境(三)
-12.5 程序执行环境(四)
-12.6 输入输出(一)
-12.7 输入输出(二)
-12.8 文件系统
-12.9 设备
-12.10 库(一)
-12.11 库(二)
-12.12 makefile文件(一)
-12.13 makefile文件(二)
-12.14 makefile文件(三)
-12.15 编程实践
-第十二讲 Linux系统编程基础--编程实践提交入口
-13.01 提纲
-13.02 进程基本概念
-13.03 信号
-13.04 进程管理(一)
-13.05 进程管理(二)
-13.06 进程管理(三)
-13.07 进程间通信(一)
-13.08 进程间通信(二)
-13.09 进程间通信(三)
-13.10 进程间通信(四)
-13.11 进程池
-13.12 编程实践
-第十三讲 进程编程--编程实践提交入口
-14.1 提纲
-14.2 线程基本概念
-14.3 线程管理(一)
-14.4 线程管理(二)
-14.5 线程管理(三)
-14.6 线程管理(四)
-14.7 线程同步机制(一)
-14.8 线程同步机制(二)
-14.9 C++11线程库(一)
-14.10 C++11线程库(二)
-14.11 C++11线程库(三)
-14.12 C++11线程库(四)
-14.13 C++11线程库(五)
-14.14 编程实践
-第十四讲 线程编程--编程实践提交入口
-15.1 提纲
-15.2 Internet网络协议
-15.3 套接字(一)
-15.4 套接字(二)
-15.5 编程实践
-第十五讲 网络编程--编程实践提交入口