第七章
7.6 使用函数时要特别考虑的问题
什么时候使用函数,什么时候使用过程
- 函数指有返回值的子程序,过程是指没有返回值的子程序
- 当过程中存在判断时,最好在入参中加入状态变量用以返回判断结果,而不是用过程的返回值作为返回结果;原因是对子程序的调用和对状态值的判断写在一行代码中,增加了该条语句的密度,也响应地增加了其复杂度;
设置函数的返回值
- 检查所有可能的返回路径:写代码的时候,所有的返回分支都能够清楚地进行数据返回;还有一种保险的做法就是,为返回值设置初值(这个初值一定要与你所要返回的值不一样,这样调试的时候出现这个初值,就说明程序中有遗漏的返回路径);
- 不要返回指向局部变量数据的引用或指针
7.7 宏子程序和内联子程序
下面的规则适用于在C++中使用预处理器的情形
- 把宏表达式整个包含在括号内:由于宏和其参数会被最终展开到代码中,尤其涉及到一些运算符或者其他符号的优先级问题,如果不加括号的话,可能会改变宏定义的本意;括号的添加,不仅指整个宏定义需要添加,在宏定义中的每一个参数也最好添加;这样做还有一个原因就是,宏定义是不进行参数类型检查的,所以存在错误会很隐蔽,因此小心为上,那么就都加上括号吧!!!!
- 把含有多条语句的宏用大括号括起来:最好不要用宏定义来实现多条语句,这不是一种好的编程习惯;
- 用给子程序命名的方法来给展开后代码形同子程序的宏命名, 以便在需要时可以用子程序来替代宏:其实这种规则的意义无非是代码的可迭代性,现实的意义不是很大;
宏子程序在使用上的限制
C++提供的大量的可以取代宏的方案:
- const可以 用于定义常量
- inline可以用于定义可被编译为内嵌的代码(inline code)的函数
- template可以用于以类型安全的方式定义各种标准操作,如min、max等(C语言中没有)
- enum可以用于定义枚举类型
- typedef 可以用于定义简单的类型替换
几乎每个宏都表明在编程语言、程序或程序员身上存在问题…当你使用宏的时间,就甭指望调试器、交叉引用工具和剖测器等工具能好好工作。——C++设计师;所以宏定义提供便利的同时,也会带来危险,那么在用之前最好做好评估
内联子程序
节制使用inline子程序:inline子程序违反了封装原则,inline子程序会把实现细节暴露给使用头文件的程序员;inline子程序会增加整体代码的长度;
第七章小结
要点
- 创建子程序最主要的目的是提高程序的可管理性,当然也有其他一些好的理由。其中,节省代码空间只是一个次要原因;提高可读性、可靠性和可修改性等原因都更重要一些。
- 有时候,把一些简单的操作写成独立的子程序也非常有价值。
- 子程序可以按照其内聚性分为很多类,而你应该让大多数子程序具有功能上的内聚性,这是最佳的一种内聚性。
- 子程序的名字是他的质量的指示器。如果名字糟糕但恰如其分,那就说明这个子程序设计得很差劲。不管怎样,糟糕的名字都意味着程序需要修改。
- 只有在某个子程序的主要目的是返回由其名字所描述的特定结果时,才应该使用函数。
- 细心的程序员会非常谨慎地使用宏,而且只在万不得已时采用。