目录
注:
本笔记参考:《C++ PRIMER PLUS》(第6版)
C++简史
C语言编程原理概括
在C语言诞生的年代,和其他主流语言一样,C语言最初是过程性语言,强调的是算法。但随着程序规模的扩大,为了满足需求,出现了一种新型的编程方法 —— 结构化编程。
正好,C语言就有进行结构化编程的能力。在C语言中存在一个理念:大化小。就是把大型程序分解成小型、便于管理的任务。也就是说,C语言鼓励程序员开发程序单元(函数)来表示各个任务模块。
但是仅仅是这样的进步是跟不上时代的,随着时代进步,结构化语言面对大型程序时的弊端也在逐渐被人们发现。
------
面向对象编程
面向对象程序设计(Object Oriented Programming,简称OOP)与强调算法的过程性编程不同,它强调的是数据。这种方式不在试图使问题满足语言,而是试图让语言满足问题。
这种设计的理念就是设计与问题的本质特性相对应的数据格式。
在C++中,存在一种名叫类的规范,它就描述了这种新型的数据格式,对象是根据这种规范构造的特定数据结构。通常,类规定了 ①可使用哪些数据来表示对象 以及 ②可以对这些数据执行哪些操作 。
当然,类并不仅仅是将数据和方法合并。OOP编程有多个优点:
- 信息隐藏 —— 保护数据免受不正当访问。
- 多态 —— 为运算符和函数创建多个定义,通过编程的上下文决定使用那个定义。
- 继承 —— 运行使用旧类派生出新类。
OOP编程不在将任务重点放在任务上,而是放在概念上。让编程从不在局限于自下而上,而是还有至下而上。
在现在的情景中,OOP语言使程序员可以轻松使用现有的类。这就是C++真正的优点之一:可以方便地重用和修改现有的、经过仔细测试的代码。
C++和泛型编程
泛型编程(Generic Programming)是C++支持的另一种编程模式。它的目的也是使重用代码和抽象通用概念的技术变得更简单。但是相比于OOP侧重的数据方面,泛型编程强调的是独立于特定数据类型。
泛型编程提供了执行常见任务(排序、合并链表)的工具。术语泛型指的是创建独立于类型的代码。
例如:现在需要为不同类型的数据进行排序,通常来说需要为每种类型创建一个排序函数。泛型编程就可以扩展语言,通过一个泛型函数实现目标。C++的模板提供了实现这种编程的方式。
C++的起源
可参考书籍:
- 《The C++ Programming Language》
- 《The design and Evolution of C++》
C++是Bjarne Stroustrup于20世纪80年代在贝尔实验室诞生的。因为C语言简洁、适合程序编程、使用广泛并且与UNIX操作系统紧密相连的优点,C语言成为了C++的基础。
因为C++并没有对C的组件进行大规模改动,所以可以认为C++就是C语言的超集,这意味着:
- 任何有效的C程序都是有效的C++程序。
- C++的程序可以使用现有的C软件库。(库是编程模块的集合,可以从程序中调用它们)
ps:C++的名字来自于C语言中的递增运算符++,这个名字表明C++是C的扩充版本。
OOP部分赋予了C++将问题涉及的概念联系起来的能力。C部分赋予C++紧密联系硬件的能力。只有关注到C++的面向对象的特性,才能完全利用起C++。
注意:C++是一门强调实用价值的语言,这也是该语言成功的语言之一。
可移植性和标准
可移植性:如果在不修改代码的情况下,重新编译程序后,程序将运行良好,则该程序是可移植的。
可移植性方面存在的两个障碍:
- 硬件:硬件特定的程序是不可移植的。(将依赖于硬件的部分放在函数模块中,可以最大限度地降低可移植性问题——只需要程序编写这些模块即可)
- 语言上的差异:口语确实可能产生问题。(只有拥有能准确描述语言工作方式的公开标准,才能让C++版本与其他版本兼容。)
为了解决语言问题,诞生了C++98标准(即ISO/IEC 14882:1998),并于2003年发布了第二版标准C++03(IOS/IEC 14882:2003),因为C++03没有改变语言特性,所以我们使用C++98表示C++98/C++2003。
之后还诞生了C++11(ISO/IEC 14882:2011),这个版本和C++98一样,新增了许多特性。除此之外,ISO C++标准还吸收了ANSI C语言标准。(实际上,ANSI加入了C++的一些特性,如函数原型和const)
C++的事实标准:
- 《The Programming Language》
- 《The Annotated C++ Reference Manual》
程序创建的技巧
创建源代码程序
C++存在一些常用的扩展名:
C++实现 | 源代码文件的扩展名 |
UNIX | C、cc、cxx、c |
GUN C++ | C、cc、cxx、cpp、c++ |
Digital Mars | cpp、cxx |
Borland C++ | cpp |
Watcom | cpp |
Microsoft Visual C++ | cpp、cxx、cc |
Freestyle CodeWarrior | cp、cpp、cc、cxx、c++ |
编译和链接
最初,Stroustrup实现C++时,使用的是cfront,这是一个C++到C的编译器程序,它将C++源代码翻译成C源代码,然后通过标准C编译器就像编译。后来,随着C++的普及,出现了C++编译器,直接将C++源代码生成目标代码。
UNIX编译和链接
最初,UNIX通过命令CC调用cfront,但cfront的最后一个版本发布于1993年。如今的UNIX可能使用专业编译器或者第三方编译器,如GNU g++ 编译器。在大多数情况下,命令CC仍然可用。如果要用UNIX编译一个C++源文件spiffy,则应该这样输入:
CC spiffy.C
如果程序没有错误,编译器将生成应该文件 spiffy.o ,再生成可执行文件 a.out 。如果只有这一个源文件,spiffy.C 将被删除,如果要运行该程序 ,只需输入可执行文件的文件名:
a.out
如果新编译程序,那么新的可执行文件将覆盖旧的可执行文件。
与C语言一样,在C++中,程序可以包含多个文件。这种情况下,需在命令行上列出所有文件来编译程序:
CC xxx.C yyy.C zzz.C
此时,程序存在多个源代码文件,编译器不会删除目标代码文件。如果只修改了 my.C ,则可以这样重新编译指令:
CC my.C precious.o
如果需要显式地指定一些库,需要使用-lm标记:
CC usingmath.C -lm
Linux编译和链接
Linux最常见的编译器是g++。
如果要生成可执行文件,那么:
g++ spiffy.cxx
如果要求链接C++库:
g++ spiffy.cxx -lg++
如果要编译多个源文件:
g++ my.cxx precious.cxx
同样,如果在多个源文件存在的情况下修改了其中某个源文件,可以重新编译:
g++ my.cxx precious.o
Windows命令行编译器
推荐的免费命令行编译器:Cygwin和MinGW,它们使用的也是g++。
一般的编译是通过命令行窗口启动上述程序,在提示符下输入。如:
g++ great.cpp