对于全局变量使用长的名字,局部变量使用短的名字。 对于类的属性,尽量还是使用一个完整的单词。
类的名称首字母大写,包的名称小写(由反转域名开头)。
类型参数的名称有单个字母组成,T表示任意的类型, E表示集合元素的类型,K和V表示映射的键和值类型,X表示异常。
NOTE: 同时参考了《Effective Java》的第56条。
使整个项目的风格一致,如果维护一个项目,保持和原来一致的代码风格。
对于一些比较常用的语句,使用惯用法来表示, 比如:。
遍历数组
for (int i = 0; i < n; ++i) { // 在C语言中,要先声明i // 使用array[i] }
遍历链表
for (p = list; p != NULL; p = p->next) { // 使用p }
使用迭代器
for (Iterator i = c.iterator(); i.hasNext(); ) { doSomething(i.next()); } // 这个用法比使用while更好,因为可以在循环体里声明变量
foreach循环(Java等语言)
for (Element e: c) { doSomething(e); } // 使用foreach循环更加方便,能使用foreach循环尽量使用foreach循环。
strdup 函数并不在标准C中,需要glibc。
函数宏很容易出错,尽量少用,在C++中已经被内联函数代替了。
注释是为了让程序员更好地理解代码,所以,代码中能够体现的就不需要通过注释来表明了。 (这与API注释不一样,API注释是给不看代码的人使用的)
给全局函数和全局变量一个注释,指明函数或者变量的用途。这和API注释有点类似。 写注释时,始终要明白这个注释是为谁而写,区别API的使用者和代码的阅读者, 虽然有时这两种人可能会重叠。
就拿一个类来说吧,如果类的属性或者方法是public的,那此时的注释就是为了API的使用者而使用的, 这时的注释应该以代码的使用方法为主,不需要涉及过多的实现细节。 而如果属性是private的,那么这些注释就是给代码的阅读者用的, 这时的注释应该讲清楚的一些关键的细节,算法或功能。
但是,大部分情况下,能够给出API类型的注释已经很不容易了,更别说为了人理解代码而写的注释。 虽然写足够清楚和有帮助的注释值得提倡, 但如果时间来不及的话,我的观点是写出足够清楚的API注释(或文档), 然后在一些关键的难以理解的过程或者算法给出代码注释, 这可能是一些比较难以理解的地方或者容易出错的地方。
write code that is easy to understand, the better you do this, the fewer comments you need.
传递数组指针(或者字符串指针)时,为了指定数组的大小, 一方面可以传递一个size参数,另一方面可以在数组的末尾增加一个哨兵(比如NULL或者0), 标志者数组的结束。
对于 realloc, 先使用一个临时指针来作为结果, 这样能够保证如果出错,原来的数据不会丢失。
Prefer memmove over memcpy 。同时这个函数不需要一个个元素的修改, 减少了出错的可能。不过在C++中必须一个拷贝。
从第3章的性能比较看到C++的标准库还不是很成熟,那只是00年时候的情况, 不知道现在怎么样,应该有很大改进了吧。
设计出一个好的接口是比较困难的,需要花很长时间的考虑。
使用两个index加 memmove 来完成需要拷贝一个数组才能完成的工作, 节约空间。不过现在看起来也不是很有必要了。
接口设计原则:
free 之后需要把指针指向null。
报错应该给出具体的信息,与其说输入太大,比如给出具体的范围。
现在对于这个没有太多感觉,这章的方法我也会经常用到, 现在暂时还没碰到那种解决不了的bug, 实在解决不了再来这章中找灵感吧。
这里的处理确实很巧妙,看完整个代码之后感觉很爽。 其实思想很简单,就是通过函数把功能组织起来, 尽量加大代码的复用。 至于如何针对于不同的功能实现不同的操作, 也就是说,如果把实现不同功能的操作统一到一起, 不同的情况就要不同的处理了。 在这个例子中,是使用了一种特殊的Notation, 这样不同的函数的区别仅仅在这个notation, 而不管是什么样的notation, 都可以按照同样的方式来进行处理, 很容易扩展其他的功能。 这也正是这个notation的强大和巧妙之处。
仔细想想,正则表达式不也正是这样的一种notation吗? 通过定义不同的正则表达式可以完成不同的功能。
作者实现了一个简化版的正则表达式匹配, 代码不到50行,而且十分清楚。 这段代码应该在心中熟记。
尽量使用能够自动生成代码的方法,而不要自己去写, 这样能够保证正确性。