`
徜徉の小溪
  • 浏览: 447569 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

如何像计算机科学家一样思考

阅读更多

系列名称:如何像计算机科学家一样思考(How to think like a computer scientist)
包含版本:C++、JAVA、Python
我很喜欢这种教育方式~

附录A:程序开发计划
  如果花费了大量的时间在调试上,很可能是因为没有一个有效的程序开发计划。

  一个典型的不好的程序开发计划就像这样:
    1. 编写一个完整的方法。
    2. 编写更多的方法。
    3. 编译程序。
    4. 花一个小时来找语法错误。
    5. 花一个小时来找运行时错误。
    6. 花三个小时来找语义错误。

  显而易见,问题出在头两步。如果写了一个方法甚至很多方法都不调试,那么得到的代码可能已经多得让你无法调试了。 如果遇到这种情况,唯一的解决办法就是删除代码直到再次获得一个可以工作的程序,然后再慢慢将程序增加回来。编程新手往往不希望这么干,因为他们精心编写的代码实在是太宝贝了。可是为了高效的进行调试,你不得不残忍起来!
  下面是一个较好的程序开发计划:
    1. 从一个能做一些直观事情(比如打印一些东西)的程序开始。
    2. 每次增加少许几行代码,并且每次改动都测试程序是否正确。
    3. 重复前两步直到程序满足预期的要求。
  每次改动后的程序都应该产生一些验证新添代码的可见效果。这种编程方式能节省许多时间。因为一次只增加少许几行代码,所以容易发现语法错误;程序的每个版本产生一些可见的结果,这就使你能不断测试自己头脑中关于程序是如何工作的模型。如果头脑中的模型是错的,在写出一大堆错误代码之前你将面对矛盾(并且也有了改正的机会) 。
  这种方式的问题是常常难于找出下手的地方并得到一个完整正确的程序。我将通过开发一个名为isIn 的方法来演示这种方式。 这个方法取一个字符串和一个字符为参数, 返回一个布尔值: 如果字符出现在字符串中就返回 true否则返回 false。
  1. 第一步,写一个尽量短但可以编译、运行并做一些可见的事情的方法:

public static boolean isIn (char c, String s) { 
    System.out.println ("isIn"); 
    return false; 
}

  当然,要测试这个方法就要调用它,需要在main 方法或在一个正常工作的程序中什么地方创建一个简单的测试用例。 先来看一个字符串中出现了字符的用例(期望得到的结果是true) :

public static void main (String[] args) { 
    boolean test = isIn ('n', "banana"); 
    System.out.println (test); 
}

  如果一切按照计划进行,代码将顺利编译、运行然后打印单词 isIn 和值false。当然,答案是不对的,但目前我们知道方法被调用并且返回了值。 在个人的编程生涯里,我浪费了太多太多的时间调试某个方法,结果却发现它根本没有被调用。如果当时我采用这种开发方式,这种事情是不应该发生的。
  2. 第二步,检查方法取得的参数:

public static boolean isIn (char c, String s) { 
    System.out.println ("isIn looking for " + c); 
    System.out.println ("in the String " + s); 
    return false; 
}

  第一个打印语句允许我们确认 isIn 方法找的是正确的字母, 第二句用来确认找的是正确的位置。
  现在输出是:
    isIn looking for b
    in the String banana
  既然已经知道它们的作用,再打印参数似乎有点傻。关键在于确认它们是否和我们设想的一样。

  3. 为了遍历字符串,可以利用 7.3 节的代码。一般来说,重用代码片断比全部从头开始更好。

public static boolean isIn (char c, String s) { 
    System.out.println ("isIn looking for " + c); 
    System.out.println ("in the String " + s); 
    int index = 0; 
    while (index < s.length()) { 
        char letter = s.charAt (index); 
        System.out.println (letter); 
        index = index + 1; 
    } 
    return false; 
}

  现在运行这个程序,它将一次打印字符串中的一个字符。如果一切进展良好,可以确定这个循环检测了字符串中的每个字母。
  4. 到这里还没有充分思考过这个方法到底要做什么, 此时我们最需要的可能就是找到一种算法。最简单的算法是一个线性查找,即遍历向量并将每个元素和目标键进行比较。
  令人愉快的是前面已经写过了遍历向量的代码。和以往一样,每次增加几行:

public static boolean isIn (char c, String s) { 
    System.out.println ("isIn looking for " + c); 
    System.out.println ("in the String " + s); 
    int index = 0; 
    while (index < s.length()) { 
        char letter = s.charAt (index); 
        System.out.println (letter); 
        if (letter == c) { 
            System.out.println ("found it"); 
        } 
        index = index + 1; 
    } 
    return false; 
}

  遍历字符串的时候,将每一个字母和目标键做比较。如果找到了目标,就打印一些信息, 这样我们就能知道新增代码执行的时候产生了一些可见的效果。
  5. 现在已经很接近正确工作的代码了。 如果找到了要找的内容那么下一个改动是要从方法中返回:

public static boolean isIn (char c, String s) { 
    System.out.println ("isIn looking for " + c); 
    System.out.println ("in the String " + s); 
    int index = 0; 
    while (index < s.length()) { 
        char letter = s.charAt (index); 
        System.out.println (letter); 
        if (letter == c) { 
            System.out.println ("found it"); 
            return true; 
        } 
        index = index + 1; 
    } 
    return false; 
}

  如果找到了目标字符,返回true;如果经历了整个循环也没有找到,正确的返回值就应该是false。
  现在运行程序应该得到:
    isIn looking for n
    in the String banana
    b
    a
    n
    found it
    true
  6. 下一步是要确认别的测试用例能正确的工作。 首先应该确认如果字符没有在字符串中则方法返回false。然后要检查一些典型的容易招致麻烦的情况,例如空字符串”",或者只有一个字符的字符串。
  一般说来这种测试可以帮我们找到存在的bug,但不能判断方法是否正确。
  7. 倒数第二步要移出或注释掉打印语句。

public static boolean isIn (char c, String s) { 
    int index = 0; 
    while (index < s.length()) { 
        char letter = s.charAt (index); 
        if (letter == c) { 
            return true; 
        } 
        index = index + 1; 
    } 
    return false; 
}

  如果稍后还要查看这个方法,那么将打印语句注释掉是一个好主意。但如果这个方法是最终版本并且你能确信它是正确无误的,就可以移出这些打印语句了。
  移出注释可以让代码更加干净,也有助于发现遗留的问题。 如果代码的用意并不是很明显,就应该增加注释来解释清除。要抵制逐行翻译代码的诱惑。例如,这样做是毫无必要的:

// if letter equals c, return true
if (letter == c) {
return true;
}

  注释应该用来解释含义不明显的代码,提示容易导致错误的情况和说明包含在代码中的假设。还有,在每个方法之前给出该方法的用途也是一个很好的做法。
  8. 最后一步是检测代码并确认它是正确的。在这里我们知道方法的语法是正确的,因为编译顺利通过。要检查运行时错误,只有找出每个可能导致错误的语句和条件。
  在这方法中唯一能导致运行时错误的语句是 s.charAt (index)。如果s 是null 或者索引超越了边界那么这条语句就将失败。因为s 是一个参数,就不能确保它不是null,所以只有检查。一般说来方法最好都要确认参数的合法性。while 循环的结构保证了 index 总是在0 到 s.length-1 之间。如果检查全部有问题的条件,或者证明这些条件不可能发生,那么就证明了方法不会导致运行时错误。
  我们还没有证明这个方法的语义是正确的,但在逐步递增的过程中,避免了很多可能的错误。例如已经知道方法能正确取得参、循环遍历了整个字符串。我们还知道这个方法成功的比较了字符,如果目标在字符串中就返回true。最后我们知道,如果循环存在就表明目标不在字符串中。
  在没有正式证明的情况下,这可能是我们能做到的最好情况。

0
1
分享到:
评论
1 楼 juda 2011-06-08  
格式不能调整下?

相关推荐

    像计算机科学家一样思考Python(第二版,中英文)

    本书的目标是教你像计算机科学家一样思考。这一思考方式集成了数学、工程以及自然 科学的一些最好的特点。像数学家一样,计算机科学家使用形式语言表示思想(具体来 说是计算)。像工程师一样,计算机科学家设计东西,...

    像计算机科学家一样思考python(已解密)

    《像计算机科学家一样思考python》按照培养读者像计算机科学家一样的思维方式的思路来教授python语言编程。全书贯穿的主体是如何思考、设计、开发的方法,而具体的编程语言,只是提供一个具体场景方便介绍的媒介。...

    像计算机科学家那样思考,Python中文版第二版

    高清完整版《像计算机科学家一样思考python》按照培养读者像计算机科学家一样的思维方式的思路来教授python语言编程。全书贯穿的主体是如何思考、设计、开发的方法,而具体的编程语言,只是提供一个具体场景方便介绍...

    【文件】像计算机科学家一样思考(C++版).pdf

    《像计算机科学家一样思考(C++版)》是一本旨在帮助读者以计算机科学家的角度理解和解决问题的书籍。本书的核心是引导读者运用计算机科学的思维方式来分析和解决实际编程问题,特别是通过C++语言来实践这些思想。...

    探秘C#:如何像计算机科学家一样思考

    《探秘C#:如何像计算机科学家一样思考》是一本专为C#初学者和有志于深入理解编程原理的读者设计的书籍。它旨在帮助读者不仅掌握C#语言的基本语法,更深层次地,它教导读者如何运用计算机科学的思维方式去理解和解决...

    《像计算机科学家一样思考Python》

    《像计算机科学家一样思考Python》按照培养读者像计算机科学家一样的思维方式的思路来教授Python语言编程。全书贯穿的主体是如何思考、设计、开发的方法,而具体的编程语言,只是提供一个具体场景方便介绍的媒介。...

    像计算机 科学家那样思考电子版pdf

    作为教育家、研究者及书籍作者,我很高兴看到这本书的完成。Python 是个有趣并且非 常易用的程序语言,在过去几年里,Python 逐渐地受到...一就是它广泛吸引了专业软件开发者、科学工作者、研究者、艺术家及教育家。

    像计算机科学家一样思考Python kindle

    《像计算机科学家一样思考python》按照培养读者像计算机科学家一样的思维方式的思路来教授python语言编程。全书贯穿的主体是如何思考、设计、开发的方法,而具体的编程语言,只是提供一个具体场景方便介绍的媒介。...

    像计算机科学家一样思考Python

    《像计算机科学家一样思考Python》是一本面向初学者的编程教材,由美国计算机科学家Allen B. Downey编写。这本书的独特之处在于它不仅教授Python语言,更注重培养读者以计算机科学家的思维方式来解决问题。通过阅读...

    像计算机科学家一样思考 java

    《如何像计算机科学家一样思考:Java版本》旨在教会读者如何像真正的计算机科学家那样思考问题。书中强调的不仅是编程语言本身的技术细节,更注重培养解决问题的能力、算法设计思路以及对软件工程原理的理解。以下是...

    像计算机科学家一样思考E文c++版

    《像计算机科学家一样思考》是一本深入探讨计算机科学思维与C++编程技术的书籍,旨在帮助读者理解并掌握计算机科学家的思维方式,同时提供C++语言的实际应用指导。本书由书部落分享,作为计算机领域的经典巨著,其...

    像计算机科学家一样思考C++

    像计算机科学家一样思考C++语言本身并不重要,解决问题的创新方法才是王道,学会“ 像计算机科学家一样思考” 作 者:[美] Allen B. Downey 著 出版时间:2013-6-1

    像计算机科学家一样思考(超清电子书)

    《像计算机科学家一样思考》是一本深入探讨计算机科学思维的超清电子书,旨在帮助读者构建像专业计算机科学家那样的思维方式。这本书的核心理念是通过解决问题和理解编程基础来培养逻辑思维和抽象能力,这对于在信息...

    如何像计算机科学家一样思考_Java Version.pdf

    《如何像计算机科学家一样思考——Java版本》是Allen B. Downey所著的一本深入浅出的编程入门书籍,旨在帮助读者理解计算机科学的核心概念,掌握编程思维,并以Java语言作为实现工具。这本书的创作背景源于作者在...

Global site tag (gtag.js) - Google Analytics