如何学习C++(面向对象和windows编程第一节课讲稿)

来源:互联网 发布:淘宝 菜鸟驿站 不显示 编辑:程序博客网 时间:2024/04/30 03:19

一、什么是 C++?
很多人不知道这个问题的正确答案。如果有人认为"C++ 是 C 的超集",那这个先生就大大落伍了,这是二十年前的答案了。如果你说"C++ 是一种面向对象的程序设计语言",哈哈,沾边,但也不对,在98年 C++ 国际标准公布以后尤其不对!

C++ 之父 Bjarne Stroustrup 曾有一篇论文 Learning Standard C++ as a New Language,《程序员》杂志2001年4月号有陈崴的译文《将标准 C++ 视为一个新语言》,把 C++ 和C(它那个好像还不是右派的爹)彻底划清了界限。文章对 C 和 C++ 在 Complexity(复杂度)和 Efficiency(效率)两方面做了比较,指出 C++ 已经完全不同于 C 的观念,并对如何学习标准 C++ 提出建议。有兴趣的朋友可以看看,很有启发性。

C++ 发展至今,其历史已足够写一本书了,Bjarne 的经典名著 The Design and Evolution of C++,详细记述了 C++ 设计和发展过程中(1979-1994)的种种考虑与妥协,它不讲 C++ 是什么样的,它只讲 C++ 为什么会成为这样。不建议初学者去看这本书,实在是咬不动,我当初已经看得头破血流了,而且这本书只讲到1994年为止,多少有些过时了,如果你已比较好地掌握 C++,并想了解其历史,看看倒是有些参考价值。

C++ 虽然起源于 C,语法也比较相似,其迅速成功并成为主流很大程度上也归功于 C 的成功。但经过多年的发展,其最精妙,最有吸引力的部分正是不同于 C 的那一部分。Koenig & Moo 夫妇(Andrew Koenig和Barbara Moo夫妇是C++领域内国际知名的技术专家、技术作家和教育家。)在为想成为更好的 C++ 程序员的人提出的3条建议中第1条就是"避免使用指针",你相信吗?指针正是 C 的核心呀。C 的宏、位运算、结构、联合、数组、强制类型转换、指针,在 C++ 程序中都应该尽量避免(在少量涉及底层的程序设计中例外),C++ 语法上强调的是类、对象、模板、标准库、引用、异常和 const 关键字,思想上强调的是面向对象和泛型。

在 Procedural Programming, Object-Based Programming, Object-Oriented Programming, Generic Programming 中,C 仅仅支持第一种,而就是在 Procedural Programming 的程序中,如果使用了标准库,一个 C++ 程序也可以和实现同样功能的 C 程序完全不同。

Bjarne 曾不止一次强调 C++ 不仅仅是一种 Object-Oriented Programming Language,那是 Java,C++ 是一种集各种编程风格于一身的程序设计语言,Object-Oriented Programming 只是其中一种,并不比其它几种风格重要。我目前很怀疑 C++ 对面向对象的支持程度,虽然它一度在这方面风光无限,但多年发展,它并没有形成一个类似于 Java 或 Python 或其它语言那样的类库,也很少取得成功的像样的类库(不能说一个没有,但毕竟很少),反而,在难产到1998年的 C++ 的第一个标准化文本中的库却是基于 Template 和 Generic 的。哈,这多少有些讽刺意味,在别的语言还唧唧喳喳讨好面向对象的时候,C++ 抛下一个媚眼,却转身投入泛型的怀抱。见风使舵的 Java 和 C# 好像上错了贼船,又都赶着往自己身上贴泛型的金,弄得人不人鬼不鬼,当初,Java 可是批判 C++ 过于复杂最起劲的一个,在可以预见的将来,它的复杂程度将不低于 C++。

二、选用什么样的编译器?

这个问题也是初学者经常问的问题,其实一句话,对于初学者来说,现有的较新的编译器,除了易用性外,没有任何区别。

有人总是在用 VC 还是 BCB 还是 GCC 上争论不休,我想如果你能把这三种编译器的区别用出来,你现在就不会看我这篇破玩意儿了。但有人现在还在用 Turbo C++ 3.0/3.1,如果你真想学好 C++,我劝你还是换换的好,那东东确实是个好东东,但已经被 Borland fans 们当作古董收藏起来了(我也留着一套呢,还有 TC 2.0),你也收起来吧,没准什么时候能卖个好价钱。

我要讲的一个重要问题是不要把 VC 与 C++ 混为一谈,也不要把 VC 当作另一种语言。首先,VC 的全称是 Microsoft Visual C++,注意,前面带有公司的名字,即使是 Java,也没有叫过 Sun Java,这就意味着 VC 是一个产品,它是 C++ 众多编译环境中的一种,它不仅仅带有一个 C++ 语言的编译器,它还带有一个用于开发 Windows 应用程序的 Application Framework - Microsoft Foundation Classes Library (MFC),又一个带公司名的家伙,它只是用 C++ 语言在 Windows API 外面加了一层包装而已,省得赤裸裸的,让程序员们在工作的时候总走神去看那些不该看的地方, 这个东西多少让开发 Windows 程序变得更容易一些。呵呵,不要再把 VC 当作语言了。

在易用性层面上,我还是推荐初学者使用 VC,用这个东东的比较多,遇到问题也好找人问。至于版本,6.0 应该够用,但这个版本已经是5年前的东东了,毕竟早了些,与标准的兼容性也多有诟病,如果有条件的话,可以用 VC .NET,这个东东的最新版本是刚刚发布的2003版,我还没见过,我只用过它的上一个版本。经过 C++ 大腕 Lippman 亲手调教过的2003版,据说对标准的兼容性已经有了根本性的转变,管他呢,又是一个宣传用语,只要你不是特意去实验标准中的那些犄角旮旯,现在流行的编译器都已经绝对够用了。

三、选书很重要

这是一个最让人挠头的问题,选什么书总是见仁见智,什么书最好是一个永远找不到标准答案的难题,来我们这个论坛的朋友多半是冲着书来的。我不想评论哪本书好哪本不好,我只是大致列一个书单,简单讲两句。

我的书单并不定位于一个没有任何语言编程基础的初学者,我觉得这样的初学者不适合直接学习 C++ 语言。我的书单定位于那些有其它语言的一定的编程基础的 C++ 初学者,他至少应该知道什么是变量,什么是运算符,什么是表达式,关键字,语句,程序,至少应该知道赋值语句是干什么的,分支判断语句干什么,循环语句干什么,当然他不必知道 C/C++ 的词法和语法,也就是说他有以上的概念,但不知道这些东西在 C/C++ 中是如何实现的。在这个基础上,我把书单分为入门类、进阶类、应用技巧类。

入门类:
C++ Primer, 3rd Edition / Thinking in C++, 2nd Edition / Accelerated C++ / The C++ Standard Library: A Tutorial and Reference
进阶类:
The C++ Programming Language, Special Edition / The Design and Evolution of C++ / Inside C++ Object Model / C++ Templates: The Complete Guide / STL 源码剖析 / Generic Programming and the STL / Modern C++ Design: Generic Programming and Design Patterns Applied
应用技巧类:
Effective C++, 2nd Editon / More Effective C++ / Exceptional C++ / More Exceptional C++ / Effective STL / Ruminations on C++

以上书可以寻找中译本!

四、学习过程很辛苦

不要问我学习 C++ 有什么捷径,因为我也不知道。不过现在开设 C++ 课程,那你很幸运,送你八个字:"课前预习,课后复习",按时完成作业之类是作为学生的基本要求,我就不在这里重复了。接下来介绍一下大家下课后的自学方法:

1、不要死抠语法:初学者最容易犯的错误就是抱着一本大书死抠语法,结果语法倒是很熟,程序还是一行都不会写,学习的积极性也受到很大打击。学习编程,语法是最不重要的,最重要的是思路。语法可以从任何一本书上查出来,比如说,用到循环语句的时候,你忘了语法,你可以翻书去查,但如果该用循环的时候你不知道用循环,该赋值的时候不知道用赋值,语法再熟有什么用呢?

2、建立面向对象的概念:在这一点上,我很欣赏 Thinking in C++,第一章是 Introduction to Objects,第二章是 Making & Using Objects,先让读者建立起对象的概念。面向对象概念开始建立的时候确实比较难,但这一关早晚得过,不过这一关就永远写不出真正的 C++ 程序,因此从开始就要培养这一思维方式,不必一蹴而就,要慢慢来,一点一点把思想方法转变过去。只要面向对象的概念建立起来,以后无论学习 Java 还是 C#,都不过是小菜一碟,新东西很少了。

3、尽早接触标准库:这也就是我把 The C++ Standard Library: A Tutorial and Reference 归入入门类的出发点,标准库的概念接触越早越好,要把使用标准库作为天经地义的事情,作为自己的编程习惯,能用的地方一定要用。几乎所有的 C++ 大师都强调过这一点,The C++ Programming Language 第三章就是 A Tour of the Standart Library,已经提前得不能再提前了,可见其重视程度。而国内的 C++ 教材要么不讲,要么简简单单一带而过,晕!

4、认真分析例题:从别人的源代码中学习是最简单的学习方法。书上的例题大部分都是作者精心挑选的,最能体现某种语法特点或思想观念的程序,认真体会这些例题,理解程序的逻辑和结构,多问自己几个问题:作者为什么要设计这个类?这个类有什么作用?作者是如何设计这个类的?如何使用这个类的?这个类是否还可以用在别处?等等。把上述问题中的"类"换成"函数"、"模板"等同样适用。遇到不好理解的例题我有一个笨办法,就是把源程序输入一遍,这个办法确实很有效,看了半天也看不懂的程序,只要输入一遍基本就能理解了,而且还加深了印象。不要不动脑子一个字母一个字母敲,敲完都不记得敲的什么了,要看一行或一段再自己输入。

5、培养良好的编程风格,积累编程技巧:只要你对 C++ 有了一个初步的概念,就可以开始看我在上一部分列出的应用技巧类书籍了。并不是每一个条款都那么高难,你也不是一定要按顺序读,一边学一边就可以挑选自己能看懂的条款研究一番。当然初学者不可能理解很深,好在这些书也不是看一遍就够的,有些条款随着你学习的深入,反复阅读会有更深的体会。如果一本全面的书是正餐的话,这些书就是佐餐的小菜,提供人体必须的维生素、矿物质和微量元素,全面吸收才能茁壮成长。

6、擅于利用身边的工具与环境:大多数编程环境都提供丰富的工具供用户使用,比如调试器等,参照用户手册,利用这些工具对自己写的程序进行分析、监视和跟踪,可以在很大程度上提搞学习和工作效率。互联网更是一个丰富的资源,特别是 google 和 MSDN,利用这些可以解决你的大多数问题,即使没有找到答案,还可以上论坛去问。

7、学无止境:C++ 语言还在不断发展,C++ 语言的国际标准也正在修订,早一天了解就能早一天受益。推开这扇门吧,有一片奇异的风景在等着你。

 

文中概念:

GP(Generic Programming)

泛型,赋予了类型参数式多态的能力
泛型编程让你编写完全一般化并可重复使用的算法,其效率与针对某特定数据类型而设计的算法相同。泛型编程的代表作品STL是一种高效、泛型、可交互操作的软件组件。所谓泛型(Genericity),是指具有在多种数据类型上皆可操作的含意,与模板有些相似。STL巨大,而且可以扩充,它包含很多计算机基本算法和数据结构,而且将算法与数据结构完全分离,其中算法是泛型的,不与任何特定数据结构或对象类型系在一起。STL以迭代器(Iterators)和容器(Containers)为基础,是一种泛型算法(Generic Algorithms)库,容器的存在使这些算法有东西可以操作。STL包含各种泛型算法(algorithms)、泛型指针(iterators)、泛型容器(containers)以及函数对象(function objects)。STL并非只是一些有用组件的集合,它是描述软件组件抽象需求条件的一个正规而有条理的架构。
泛型编程也就是GP(Generic Programming),推崇与类型无关的编程思想。简单来说,就是将针对不同数据类型的相同算法从数据结构<类>中剥离出来, 这与传统的C++的继承和多态截然不同。 可以说泛型思想中没有多少继承和多态的成分。甚至有背道而驰的味道。 在C++实现上,泛型严重依赖于模板机制,事实上如果没有模板的引入,泛型绝对不会在C++语言中获得如此巨大的成功! 泛型代码由C++编译器在编译期解释成二进制代码。也就是说,泛型的代码编译起来可能会使程序的二进制代码变大,但这一点也保证了程序在运行的时候不会损失效率...

STL(Standard Template Library) 标准库

STL(Standard Template Library,标准模板库)是惠普实验室开发的一系列软件的统称。它是由Alexander Stepanov、Meng Lee和David R Musser在惠普实验室工作时所开发出来的。现在虽说它主要出现在C++中,但在被引入C++之前该技术就已经存在了很长的一段时间。
STL的代码从广义上讲分为三类:algorithm(算法)、container(容器)和iterator(迭代器),几乎所有的代码都采用了模板类和模版函数的方式,这相比于传统的由函数和类组成的库来说提供了更好的代码重用机会。
大家都能取得的一个共识是函数库对数据类型的选择对其可重用性起着至关重要的作用。举例来说,一个求方根的函数,在使用浮点数作为其参数类型的情况下的可重用性肯定比使用整型作为它的参数类性要高。而C++通过模板的机制允许推迟对某些类型的选择,直到真正想使用模板或者说对模板进行特化的时候,STL就利用了这一点提供了相当多的有用算法。它是在一个有效的框架中完成这些算法的——你可以将所有的类型划分为少数的几类,然后就可以在模版的参数中使用一种类型替换掉同一种类中的其他类型。
STL提供了大约100个实现算法的模版函数,比如算法for_each将为指定序列中的每一个元素调用指定的函数,stable_sort以你所指定的规则对序列进行稳定性排序等等。这样一来,只要我们熟悉了STL之后,许多代码可以被大大的化简,只需要通过调用一两个算法模板,就可以完成所需要的功能并大大地提升效率。