面向过程和面向对象
大千世界中,事务的发展规律都是面向过程的状态。例如一颗种子从生根到发芽,从发芽到开花,从开花到结果。
但是面向过程是一个更贴近**“机械”**的表达方式,而更贴近人类思想的却是面向对象的表达方式。
以汽车生产为例,用面向过程的方式表达:
- 生产车壳
- 安装发动机
- 安装内饰
- 安装轮胎
而面向对象的方式表达:
汽车有车壳、发动机、内饰、轮胎等属性。
面向对象是人类思想的一种“抽象”。
而在程序语言中,近代经典面向过程的语言则是C语言,而它面向对象的语言“亲戚”则是C++。
但非常有意思的是,C++在不同的运行平台拥有不同的语法规则。
这个现象可以用一个比较形象的比喻是:
中国的官方语言是普通话,但是不同地区存在着四川话、上海话等地区方言。但是不论如何,他们都符合“中文”这个语言规范。
C++在平台上的运行步骤,简单来说可能是下面这样:
怎么来理解这个抽象过程呢?可以用平常说话来作比方。
源代码的书写规范
注释
注释是一种给其他同行的提示“hint”。
通常书写的源代码可能会被其他人阅读借鉴。
如果书写的源代码可能非常冗长(如果是习惯较差的程序员,一个文件可能有上千行),这时候阅读你的杰作是拗口乏味的。所以一定的注释可以大大改善这一情况。
C++中,有两种注释表示方式://和/* */
- //用来表示剪短的hint(不超过一行)
- /**/用来表示篇幅长的hint(超过一行)
头文件
头文件相当于所写源文件的目录。
编写目录是一种非常好的习惯,它可以把想表达的大量文字分段落、分章节。
C++中,用h,hpp来表示头文件。
需要注意,我们常见到**include <>和include" "**两种用法。这两种用法功能相同,但又有一些区别:
- #include :优先标准函数库寻找头文件head
- #include “head.h”:优先在当前路径下寻找头文件
例如,当head.h是工程中自己定义的头文件,推荐用#include " ";
当head是一个系统自带的头文件,推荐用#include <>。
include的执行原理:将include文件内容复制于调用处,然后与该调用所在源代码,组成复合文件一起送入编译器。
命名空间
命名空间用来解决什么矛盾呢?
你班上有三个同学都叫张三,这时候一个新来你班上的同学无法根据名字来区分这三个人。那么可以用“浙江张三”、“东北张三”、“四川张三”来区分这三个人。
此时,浙江、东北、四川就相当于命名空间。
命名空间的出现,大大避免了程序代码重复定义的现象发生。
C++中,用namespace来定义命名空间。在其它编程语言中也有类似的概念,例如java中,用package定义命名空间。
命名空间不仅可以区分不同类,也可以用于区分C风格函数
例如,有两个不同名的produce函数,都用于生产汽车。
但是加上了VM和GW两个不同的命名空间,就不会造成函数的二义性(ambiguous)
#include <iosteam>
namespace VW{
void produce(){
std:cout << "produce VW car" << std::endl;
}
void secret(){
std:cout << "this is a secret" << std::endl;
}
}
namespace GW{
void produce(){
std:cout << "produce GWcar" << std::endl;
}
}
下面展示了如何调用不同命名空间下的函数,使用::作用域运算符
#include "example.hpp"
int main()
{
VW::produce();
GW::produce();
}
源代码的书写工具
“工欲善其事必先利其器”,要想书写你脑海里的文字必须要有个好笔杆才行。IDE就是书写C++源代码必不可少的工具。
需要注意的是,市面上的IDE一般分为2种:一种是仅书写,给你提供语法的高亮显示但不提供编译功能;另一种是集成了编译器的重型“IDE”,这类IDE包含了很多常见的编译功能按钮:
这里罗列一下常见功能按钮的解析:
- compile:编译。对当前源代码文件进行编译。
- Build/Make:对项目中所有源代码文件进行编译。需要注意的是,这是一个递增过程,意味着它只会重新编译发生改动的文件。
- Clean:删除之前编译结果。由于Build/Make是个递增的过程,发生改动的文件经过一次编译后,结果会被缓存成一个临时后缀名为“.o”的文件。clean代表清除之前所有这样的临时文件。
- Link:编译后的源代码与其它.o文件或第三方库进行组合。由于你写的代码很可能像论文一样引用别人论文(也就相当于第三方库)中的表达,所以这时候需要把别人论文中的表达和你的代码进行组合,才能输出通顺的意思。
- Run/Execute:运行程序。编译好的结果,如果包含main()程序启动入口,就可以开始运行程序。
- Debug:以步进方式调试程序(gdb)。
Q:不是有编译器帮忙检查语法么,为什么还会出现语病呢?
A:语病的种类很多,像不合逻辑,表意不明,语序不当是符合语法,但不符合常识的语病。
所以我们可以得出一个重要结论:
编译器通过不等于程序合法