0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看威廉希尔官方网站 视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

从C++的“深度”与“广度”来探究其复杂程度

C语言专家集中营 2018-01-15 15:48 次阅读

从深度和广度谈C++的复杂度

C++到底有多复杂,没有人知道,我们知道的,只是C++很复杂。但是再复杂的事情也有解决的方法,对于C++的复杂度,我们可以从C++的“深度”与“广度”来探究。

C++有一个朴素的思想:“简单的问题用简单的方法解决,复杂的问题,用复杂的方法解决。”。这句话当然不能绝对化。一个问题的复杂性,往往有多种来源,比如可以是“深度”上的困难;从这一点上,我们了解,证明“任何一个>=6之偶数,都可以表示成两个奇质数之和 ”是个难题,虽然题目很短一读明白,但它确实是一个复杂的问题,因为它是“哥德巴赫猜想”。

复杂度的来源也可以是问题的“广度”。比如给一个人做一道可口的菜是简单的,但今天是周末,我家来了七大姑八大姨,站在厨房里的我就会感觉面临一道复杂的问题。我不仅要了解每一位亲人的口味,并不绝不能做八道菜,让客人各选所需就算了。八个简单的问题,交叉在一起时,成就了一道“众口难调”的复杂的问题。

C++中所具备的复杂功能,一小部分有助于我们解决深度上的复杂问题,但更多的功能,是为用来对付“广度”上问题。这符合软件开发行业的主要市场需求。

小结一下:C++中有很多复杂的(方法或)知识点其实是留着对付一些复杂问题的。但,我们在学习C++时,我们能遇上什么“复杂”问题吗?答:很少,甚至就是没有。那么,光靠一些简单的问题,我们能理解那些复杂的方法吗?

比如“面向对象”。C++之父早说过,C++语言不是,也不愿意成为一门单纯的“面向对象”的语言。为什么?因为“简单的事情简单解决。”,“面向对象”的编程思想,在历史上出现,就是为了解决足够庞大的复杂问题才提出,并且确实取得了一定程度上的成功。于是乎人人都对它趋之若骛,更是成为了大学编程专业的必修课。但请问,你根本就没可能在书本上遇上任何足以体现“面向对象”之必要性的问题,你怎么学习“面向对象”呢?请注意,写一个“非常面向对象”的程序,是很容易地,一个java版本的“Hello world”程序就很OO。但把程序写得非常有“面向对象”的风格,这绝对不是我们的目标。目标是解决问题,“面向对象”是一种“思想工具”,当我们判断再没有更简单的工具来解决一个问题时,于是把手伸入机器猫的口袋,叮叮铛……屏幕上打出四个大字“面向对象”。

有同学要举手反对了,复杂度是相对啊。一个在大拿眼里,很简单的,用面向过程可以非常漂亮地解决的问题,但在初学者面前,就是一个大广度的问题,这时,作为一种组织方法,“面向对象”不能帮我们些什么吗?如果能帮上,那我们用它来学习“面向对象”,就不算是纸上谈兵了吧?

完全同意。像Linus这样的大牛,操作系统这样既深又广的问题,他都觉得用C语言这样典型的面向过程的语言,就可以轻易拿下,他倒觉得像C++这样的语言的OO,纯是添乱。

复杂度当然是相对的,但当我们面临,或者说期望的复杂是指“广度”上的复杂度时,普通教程上的那种一杆子想把C++语言捅到底的教学内容与教学方式,就显得非常的不够用了。写一个“俄罗斯方块”的程序,就是一个“相对复杂”的问题。翻开一本《C++ Primer》,740多页,如果仅仅从C++语言知识点来看,任何一个学到第227页的读者,都应该要开始动手写一个俄罗斯方块的程序。因为那时候他已经懂得多维数组,于是可以定义出方块数据;他已经懂得if判断,于是写得出碰撞判断;他已经学会for循环,于是知道如何消掉被填满的一行或多行……

有人觉得我这是“忽悠”。他们又改口说,“俄罗斯方块”是一个太复杂的问题了,如果学生在学习半途花上一个月时间去搞一个俄罗斯方块,会节外生枝,彻底打乱原来学习计划云云。好吧我承认确实存在苦研十年军事理论,然后杀上战场一举成名的将军;但我更愿意相信多数将军是不断地打一场场小战役,不断地在晚上挑灯看《武穆遗书》的过程中成长起来的。而我也确实看到那些在一个月中,被“俄罗斯方块”程序搞得头破血流,并坚持下来的学生,确实在日后遇上问题时,有着更好的“纠缠”能力。试想一下吧,学完《C++ Primer》200多页时,像样的问题都没遇上一个,却要再翻过那么一百多页,然后开始学习“第三部分 类和数据抽象”。

我用《C++ Primer》当教材当老师,不是一次两次了,但每当我开始兜售“面向对象的本质不是封装、不是派生、不是多态,而是抽象”时,我总觉得自己是那么无力。底下的战士,他们没有打过任何一场像样的战役,但他们希望在课堂上成长为巴顿,成长为陈庚。

在那一时,我总会想起C++之父痛心地说到C++教育的一句话,大意是说:现在C++教育似乎进入了一个怪圈:要教会一个人C++,唯一的办法,就是把他教成C++高手。我在从事C++教育时,很长时间,发现自己一样落在怪圈里!长叹。

(以上内容,任何有正常理智或心态的人,都不会认为:本文作者在说《C++ Primer》是一本差书。)

对一个初学者,学完《C++ Primer》227页之后,动手写一个俄罗斯方块游戏,复杂在哪里?

(一),C++初学者(没有其它语言学习经验)那时刚刚把类型、变量、数组、指针、if、for………装入脑里,每一个知识点都才刚刚开始消化,这时要把这一切掺合到一起,去解决一个真正的问题,就像一个刚刚看完《高尔夫球杆使用说明》的人上了场,那个乱劲儿!

(二),没有人会觉得写一个字符界面的俄罗斯方块很爽,所以总得要去碰一下图形用户界面的编程知识吧。窗口、菜单、定时器、消息、GDI,资源文件……妈啊。就这一点就够广的。

(三)、教材里那些花花草草小猫小草的例程,也确实拿来过调试,什么单步跟踪、什么断点、什么变量观察……还有什么条件编译、二分法、以及如何使用Windows的调试API,比如“OutputDebugString”函数等等,平常老师在台上讲,我们都觉得需要那么多调试方法吗?现在可好,程序好不容易编译通过,一运行就死了,一头雾地才开始想如何调试……

公元一九八九年,有人问总设计师说中国十年改革开放最大的失误是什么?他说是教育。(公元2008?)有人问C++之父,十数年,C++语言最大的失误是什么?Stroustrup说,也是教育。这个“也”字纯属我加的。原文得是这样:

Stroustrup Says C++ Education Needs To Improve :

“在C++的早期,我很担心不能足够快的教好教师。我有理由担心,因为许许多多明显的C++的错误使用都可以追踪到教育者自身对基础的误解。我未能足够清晰的阐述我的想法和原理。”Stroustrup表示,“我避免传授‘如何思考’,我猜想最好的教育之法是使用大量优秀的例子。”

没错,如果可能,就永远别去教学生如何“面向对象”,而是要让他们陷在问题的海洋里,再加上有力的引导,最终让他们自己悟出面向对象的真谛。

如果我有儿子。当他成长到对爱情似懂非懂的青涩年龄时,我不想对他讲一堆什么爱情啊责任啊的大道理。我也不希望他谈第一个女朋友,就马上顺利地步入婚姻,我希望如果可能,他最好遇上些嫌贫爱富的女人,遇上些虚荣乖张的女人,然后被女人抛弃过,或抛弃过别人,然后命运再安排他遇上他的灰姑娘。

花花公子,情海里几度沉浮,不轻易付出感情的男人,通常比那些遇上第一个女人就爱得死去活来的青涩男孩,更懂得爱情的真谛,在婚后也往往更不会爱上别的女人。为什么,因为随便碰上个异性就爱得死去活来的人,通常他们爱的不是人,他们爱的是“爱情”这个东西,就算他们其实没有足够了解爱情中另一个人。

作为C++程序员,碰上任何一个问题,就要来扯上一通“面向对象”如何如何的人;在碰上真正问题时,往往比那些懂得简单问题简单解决的人,挂得早。因为他们的出发点是爱上了“面向对象”,而不是了解所要解决的问题。

同样的,作为一个C++爱好者,你可以爱上C++,但作为一个程序员,请别轻易说,我爱上了一门语言。爱容易让人盲目;一个盲目的fans,是有力量的,他全身心地投入了学习,真好;但一个盲目的程序员,是可怕的,他会以为,C++和爱情一样,无所不能。

但具体到我个人,我有我的坚持,我决不愿意把我的学生培养成C++的粉丝(但,成为C++之父BS的粉丝,我热烈支持:)。相反,我会“折磨”他们,《白话 C++》中的第二章《准备》,已经成功地让很多学习者,发出哀怨:“学习C++,有必要去安装、编译这么多库吗? 还是Java好,一切都准备好了。”

《准备篇》的绪言,是一句煽情的话:“决定你能否成为程序员,不在于你的计算机基础,在于你是否有足够的耐心。”

现在社会,有些女人或男人,会同时和几个异性谈恋爱,他们是势利的。我当然也反对这种不道德的行为。但如果是学习语言(无论是编程语言或自然语言),如果你有能力,我建议完全可以同时学习两门,学习上越“势利”越好,而有能力时,同时学习多门语言,那是相当的有利可图,具体有机会再展开。通常一个人对在C++语言熟练之后,就具备了这个能力。对于从没有学习过其它编程语言的初学者,同时学习C++语言之外,还要学习另一门,不现实。但是,当我们仅仅限定C++编程的范畴,那就一定不能痴痴,长期地把精力和爱心都放在语言自身上。

C++之所以复杂,是因为C++的“深度”与“广度”都很深远,但是遵循“有一定深度,扩大广度,有一定广度,加深度”的方法,会发现C++的“深度”与“广度”会成为我们编程中的一点乐趣。希望本文会给读者带来收获。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • C++
    C++
    +关注

    关注

    22

    文章

    2108

    浏览量

    73623

原文标题:从深度和广度谈C++的复杂度

文章出处:【微信号:C_Expert,微信公众号:C语言专家集中营】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    C++避坑指南

    C++是一门古老的语言,但仍然在不间断更新中,不断引用新特性。但与此同时 C++又甩不掉巨大的历史包袱,并且 C++的设计初衷和理念造成了 C++异常
    发表于 09-15 09:04 565次阅读

    C语言与C++的区别

    在很大程度上,C++C的超集,这意味着一个有效的C程序也是一个有效的C++程序。
    发表于 09-16 10:20 1150次阅读

    CC++中const的用法比较

    #define一样不占空间,但拥有类型安全检查和作用域控制)。因此上述不能编译通过的C代码,在C++中可以顺利地通过。当不需要分配空间时(这依赖于数据类型的复杂度和编译器的智能化程度)
    发表于 11-11 10:00

    c++程序设计语言题解

    c++程序设计语言题解是与Bjarne Stroustrup的《C++程序设计语言》一书配套使用的习题解答,为C++程序设计
    发表于 09-05 16:00 121次下载
    <b class='flag-5'>c++</b>程序设计语言题解

    C++课件、习题及答案

    *1.1  CC++*1.2  最简单的C++程序 1.3  C++程序的构成和书写形式&nbs
    发表于 09-08 09:35 108次下载
    <b class='flag-5'>C++</b>课件、习题及答案

    详述不用c++写网页的理由

    C++在web开发中地位如何,进来一探究竟吧。
    的头像 发表于 12-22 10:07 5949次阅读

    如何C转向C++ Effective C++ PDF中文版教材免费下载

    对每个人来说,习惯 C++需要一些时间,对于已经熟悉C 的程序员来说,这个过程尤其令人苦恼。因为CC++的子集,所有的C 的威廉希尔官方网站 都可以继
    发表于 01-10 16:48 0次下载

    C++程序设计教程之C++的初步知识的详细资料说明

    C++程序设计教程之C++的初步知识的详细资料说明包括了:1. CC++,2 . 最简单的C++
    发表于 03-14 14:48 31次下载
    <b class='flag-5'>C++</b>程序设计教程之<b class='flag-5'>C++</b>的初步知识的详细资料说明

    如何深度解析C++拷贝构造函数详细资料说明

    本文档的主要内容详细介绍的是如何深度解析C++拷贝构造函数详细资料说明。
    发表于 07-05 17:41 0次下载
    如何<b class='flag-5'>深度</b>解析<b class='flag-5'>C++</b>拷贝构造函数详细资料说明

    如何使用Borland C++ Builder6.0开发OpenCV的程序

    本文档的主要内容详细介绍的是如何使用Borland C++ Builder6.0开发OpenCV的程序。
    发表于 05-26 17:32 14次下载
    如何使用Borland <b class='flag-5'>C++</b> Builder6.0<b class='flag-5'>来</b>开发OpenCV的程序

    C语言与C++相互调用

        1CC++相互调用 在一个嵌入式系统中大部分的底层和驱动层更多的是采用C语言进行开发,而上层应用、服务更多的采用C++等高级语言
    的头像 发表于 01-18 11:05 3329次阅读
    <b class='flag-5'>C</b>语言与<b class='flag-5'>C++</b>相互调用

    EE-128:C++中的DSP:C++调用汇编类成员函数

    EE-128:C++中的DSP:C++调用汇编类成员函数
    发表于 04-16 17:04 2次下载
    EE-128:<b class='flag-5'>C++</b>中的DSP:<b class='flag-5'>从</b><b class='flag-5'>C++</b>调用汇编类成员函数

    测量深度广度判断AI算法的潜力

    算法的潜力会受到感测能力的限制。开尔文勋爵曾经的名言至今仍不过时――“无法测量,则无法改进”。要想了解 AI 的真正能力,请务必从分析其测量的广度深度开始。
    的头像 发表于 01-16 09:33 698次阅读

    深度解析C++中的虚函数

    虚函数作为C++的重要特性,让人又爱又怕,爱它功能强大,但又怕驾驭不好,让它反咬一口,今天我们用CPU的角度,撕掉语法的伪装,重新认识一下虚函数。 虚函数是C++实现面向对象设计及多态特性
    的头像 发表于 02-15 11:14 828次阅读
    <b class='flag-5'>深度</b>解析<b class='flag-5'>C++</b>中的虚函数

    C++的引用和指针

    之前的文章我们已经介绍了C++中的基本类型如int,bool和double等,除了基本类型C++还有一些更复杂的数据类型复合类型,所谓的复合类型就是通过其他类型定义的类型,本篇文章我们将会着重介绍
    的头像 发表于 03-17 14:00 630次阅读