虽然这些话都是比较空洞的讲述历史,但章杉恰恰就吃这一套~
对于上来就用极其专业的语言来讲述C语言该如何如何的,章杉半点好感都没有!
良好的开头是成功的一半~
不知不觉中,章杉便入了迷~
作者还是十分较真的,在书里认真地探讨了是先有C语言还是先有UNIX呢?
说起这个问题,人们很容易陷入先有鸡还是先有蛋的死循环中~
然而,作者讨论的不是家禽趣闻,而是编程故事。
这本书中作者认真地指出,UNIX比C 语言出现得早。
这也是为什么 UNIX 的系统时间是从 1970年1月1日起按秒计算的,它就是那时候产生的啊~
不过说起来这本书里面描写C历史的篇幅是相当有限的!
之后则完完全全的干货满满
“尽量不要在你的代码中使用无符号类型,以免增加不必要的复杂性。尤其是,不要仅仅因为无符号数不存在负值(如年龄、国债)而用它来表示数量。尽量使用像 int 那样的有符号类型,这样在涉及升级混合类型的复杂细节时,不必担心边界情况(如-1 被翻译为非常大的正数)。只有在使用位段和二进制掩码时,才可以用无符号数。应该在表达式中使用强制类型转换,使操作数均为有符号数或者无符号数,这样就不必由编译器来选择结果的类型。”
“许多操作数类型为算术类型的双目运算符会引发转换,并以类似的方式产生结果类型。...如果其中一个操作数的类型是 unsigned long int,那么另一个操作数也被转换为 unsigned long int。其次,如果其中一个操作数的类型是 long int,而另一个操作数的类型是 unsigned int,如果 long int 能够完整表示 unsigned int 的所有值,那么 unsigned int 类型操作数被转换为 long int,如果 long int 不能完整表示 unsigned int 的所有值,那么两个操作数都被转换为 unsigned long int。再次,如果其中一个草所属的类型是 long int,那么另一个操作数被转换为 long int。再再次,如果其中一个操作数的类型是 unsigned int,那么另一个操作数被转换为 unsigned int。”
“……”
“除了递归调用之外,堆栈并非必需。因为在编译时可以知道局部变量、参数和返回地址所需空间的固定大小,并可以将它们分配于bss段。BASIC,COBOL和FORTRAN的早期编译器并不允许函数的递归调用,所以它们在运行时并不需要动态的堆栈。允许递归调用意味着必须找到一种方法,在同一时刻允许局部变量的多个实例存在,但只有最近被创建的那个才能被访问,这很像栈的经典定义。”
尽管动辄长篇大论,但有一说一,这本书的写作风格还是很舒服的~
基本上书中的内容都是循序渐进的。
而不是和《手把手教你学XXX》/《XXX从入门到精通》这类书一般,章节难度布置的毫无规律可言!
章杉很喜欢这本书11.18的章节名——《如果我的目标是那里,我不会从这里起步》
按照书中的话“编程语言的主要目标是提供一个框架,用计算机能够处理的方式表达问题的解决方法,编程语言越是能体现这个原则,就越成功……”
在这句话的指引下,章杉对过往学过的种种编程语言有了些新的见解。
尽管这种认知并不意味着质变,但正是一点点量变的积累才酝酿了质变!