zoukankan      html  css  js  c++  java
  • 代码之髓 读书笔记

    这本书是一位日本人写的,装订得蛮漂亮。因为白骨精学习法一书,我对日本人诡异的思路相当感兴趣,日本人写的书有种不一样的风味,在某一方面上有很大的参考价值,所以第一眼看到这本书的时候就感兴趣了。

    ##语言为什么会这样设计

    本书主要从语言的发展史,穿插地介绍一些语言背后的东西。

    关于条件判断语句

    if…else,while,break,相对于以前的语言来说,也就是加了限制的 goto 语句。

    关于 while,与 for: 一开始是先设计出 while 语句的,但对在0至N范围的某种数值进行某种操作,这样的需求经常会遇到。

    i = 0;
    while(i<N){
    	printf(“%d
    ”,i);
    	i++;
    }
    
    用 while 语句实现起来是这样的,在循环体外写 i=0 ,循环条件写 i<N, 循环体写 i++。代码分散,这样原来要表达的意图就会别削弱,因为这是经常用到的。所以就有了跟while功能类似的for语句。
     

    关于函数

    在最初程序中,命令和数据完全都存储在内存中,修改程序就如同把数值代入变量中一样简单。通过修改程序中跳转目的地,就能使函数调用后返回原来的位置

    不过这就要求程序员知道函数跳转的目的地地址,以及返回原来的内存地址。这是很难办到的,因为如果在函数中增加几行代码,返回命令的位置就会相应地往后挪一些。这样一来,就不得不修改调用这一函数的全部代码。

    后来有改良的办法:创建用来事先记录返回目的地的内存空间,并设计能跳转到该内存空间里记录的地址的命令。这样,即使函数调用前不知道返回命令所在地也没关系。但是这又有一个问题当调用函数X期间又调用了Y函数时,返回的目的地内存被覆盖,函数X执行后应该返回的目的地址就找不到了。

    再后来,就轮到栈登场了。栈就是用来存储函数的返回的目的地地址等信息。

    关于异常处理

    一开始语言的错误处理大体可以分为两种:一种是利用函数返回值来传达错误信息(比如C传-1来表示错误),另一种是在调用函数前设定好错误处理的代码,错误发生时能跳转到相应的错误处理代码

    在错误就跳转处理这种主导思想下也出现过几种设计:

    l PL/I语言,先定义好出错时的错误处理操作,再编写可能出错的代码。

    l Java等,先编写可能出错的代码(try{}),然后编写出错时的处理操作。

    相应的,在这种设计下也带来了一些问题。在捕获到错误后,有些必须要执行的操作会被忽略,所以微软引入了finally语句。

    关于异常,不同的设计者又持有不同的观点。比如对于数组越界的问题,Python会抛出异常,Ruby会返回一个指示不存在的特殊值(nil),而JavaScript会返回undefined。而调用有两个参数函数时,只传递了一个参数时,Python和Ruby会在函数调用的时候抛出异常。但JavaScript会把缺失的参数当做未定义的特殊值(undefined)继续执行。(orz 这样看来JavaScript真是很多坑…)

    这三门语言的设计者都是大牛中的大牛,他们对于何种情况应该抛出异常也不能达成一致。异常应该在何种情况下使用,何为异常的情况,这些问题是没有正确的答案的。

    PS:当然出错后立即抛出异常一般来说是比较好的习惯。

    异常的传递

    在Java语言在内的很多现代语言的异常处理机制中,异常可传递至调用方。也就是说,如果函数f调用g,g调用h。h有异常抛出,但无法或没处理异常,那么就会看函数g能否处理异常,再不行就传到f。

    关于这个设计,大家意见并未统一,因为这个设计有一个很大的问题。那就是,即使看到了f函数的代码也不知道函数f可能会抛出什么异常,有可能是g会抛出,也有可能是h会抛出。换句话说,也就是不看见f调用的所有函数的代码是无从得知f会抛出何种异常的。

    1975,John Goodenough在自己的论文中主张为了避免这一问题,需要明确地声明可能会抛出的异常。其中Java语言就采用了这个方针。

    Java对异常进一步分为三类:不应该做异常处理的重大问题、可做异常处理的运行时异常和做异常处理的其他异常。其他异常叫做检查型异常(也就是玩家自己定义的),如果在方法之外熬出,就需要在定义方法时声明。Throw就是为这个目的而准备的。

    检查型异常时一种非常好的机制,但是并没有很好地普及到其他语言中。一言蔽之,就是他太麻烦,一旦throws或try/catch中异常数目增多,或者某一方法需要追加一种异常,就不得不修改调用了该方法的所有方法,特别麻烦。

    C#很大程度上参考了Java,但没有借用它的这种机制。C#设计者Anders Hejlsberg说:“检查型异常的理念本身并没有什么不对的地方,相反是很棒的。然而在像Java语言这样的实现方式下,它在解决某些问题的同时又引入了别的问题。如果能有更好的实现方法,C#语言或许也是可以借用的”

    PS:作者在写这章时,插入了一段话,关于阅读作者本人写的文档而不是二手资料时的策略问题。他采用三种策略:一从需要的地方开始阅读,二先掌握概要再阅读细节,三从头开始逐章手抄。我用的最多的就是第一种了。其实也并不是十分有用的建议哈哈。

    关于命名以及作用域

    待补充

  • 相关阅读:
    1014 Waiting in Line (30)(30 point(s))
    1013 Battle Over Cities (25)(25 point(s))
    1012 The Best Rank (25)(25 point(s))
    1011 World Cup Betting (20)(20 point(s))
    1010 Radix (25)(25 point(s))
    1009 Product of Polynomials (25)(25 point(s))
    1008 Elevator (20)(20 point(s))
    1007 Maximum Subsequence Sum (25)(25 point(s))
    1006 Sign In and Sign Out (25)(25 point(s))
    1005 Spell It Right (20)(20 point(s))
  • 原文地址:https://www.cnblogs.com/hwencc/p/5002550.html
Copyright © 2011-2022 走看看