4.4 其它建议 ☆ 【建议4.4-1】 函数的功能要单一,不要设计多用途的函数; ☆ 【建议4.4-2】 函数体的规模要小,尽量控制在150行代码之内; ☆ 【建议4.4-3】 尽量避免函数带有“记忆”功能。相同的输入应当产生相同的输出带有“记忆”功能的函数,其行为可能是不可预测的,因为它的行为可能取决于某种“记忆状态”。这样的函数既不易理解又不利于测试和维护。在C/C++语言中,函数的static局部变量是函数的“记忆”存储器。建议尽量少用static局部变量,除非必需。 ☆ 【建议4.4-4】 不仅要检查输入参数的有效性,还要检查通过其它途径进入函数体内的变量的有效性,例如全局变量、文件句柄等; ☆ 【建议4.4-5】 用于出错处理的返回值一定要清楚,让使用者不容易忽视或误解错误情况。 4.5 使用断言 程序一般分为Debug版本和Release版本,Debug版本用于内部调试,Release版本发行给用户使用。 断言assert是仅在Debug版本起作用的宏,它用于检查“不应该”发生的情况。示例4.5是一个内存复制函数。在运行过程中,如果assert的参数为假,那么程序就会中止(一般地还会出现提示对话,说明在什么地方引发了assert)。
示例4.5 复制不重叠的内存块
assert不是一个仓促拼凑起来的宏。为了不在程序的Debug版本和Release版本引起差别,assert不应该产生任何副作用。所以assert不是函数,而是宏。程序员可以把assert看成一个在任何系统状态下都可以安全使用的无害测试手段。如果程序在assert处终止了,并不是说含有该assert的函数有错误,而是调用者出了差错,assert可以帮助我们找到发生错误的原因。
☆ 【规则4.5-1】 使用断言捕捉不应该发生的非法情况,不要混淆非法情况与错误情况之间的区别,后者是必然存在的并且是一定要作出处理的; ☆ 【规则4.5-2】 在函数的入口处,使用断言检查参数的有效性(合法性); ☆ 【建议4.5-1】 在编写函数时,要进行反复的考查,并且自问:“我打算做哪些假定?”一旦确定了的假定,就要使用断言对假定进行检查; ☆ 【建议4.5-2】 一般教科书都鼓励程序员们进行防错设计,但要记住这种编程风格可能会隐瞒错误。当进行防错设计时,如果“不可能发生”的事情的确发生了,则要使用断言进行报警。 4.6 引用与指针的比较 引用是C++中的概念,初学者容易把引用和指针混淆一起。一下程序中,n是m的一个引用(reference),m是被引用物(referent)。 int m; int &n = m; n相当于m的别名(绰号),对n的任何操作就是对m的操作。所以n既不是m的拷贝,也不是指向m的指针,其实n就是m它自己。 引用的一些规则如下: (1) 引用被创建的同时必须被初始化(指针则可以在任何时候被初始化); (2) 不能有NULL引用,引用必须与合法的存储单元关联(指针则可以是NULL); (3) 一旦引用被初始化,就不能改变引用的关系(指针则可以随时改变所指的对象)。 以下示例程序中,k被初始化为i的引用。语句k = j并不能将k修改成为j的引用,只是把k的值改变成为6。由于k是i的引用,所以i的值也变成了6。 int i = 5; int j = 6; int &k = i; k = j; // k和i的值都变成了6; 上面的程序看起来象在玩文字游戏,没有体现出引用的价值。引用的主要功能是传递函数的参数和返回值。C++语言中,函数的参数和返回值的传递方式有三种:值传递、指针传递和引用传递。 以下是“值传递”的示例程序。由于Func1函数体内的x是外部变量n的一份拷贝,改变x的值不会影响n, 所以n的值仍然是0。 void Func1(int x) { x = x + 10; } … int n = 0; Func1(n); cout << “n = ” << n << endl; // n = 0
以下是“指针传递”的示例程序。由于Func2函数体内的x是指向外部变量n的指针,改变该指针的内容将导致n的值改变,所以n的值成为10。 void Func2(int *x) { (* x) = (* x) + 10; } … int n = 0; Func2(&n); cout << “n = ” << n << endl; // n = 10
以下是“引用传递”的示例程序。由于Func3函数体内的x是外部变量n的引用,x和n是同一个东西,改变x等于改变n,所以n的值成为10。 void Func3(int &x) { x = x + 10; } … int n = 0; Func3(n); cout << “n = ” << n << endl; // n = 10
对比上述三个示例程序,会发现“引用传递”的性质象“指针传递”,而书写方式象“值传递”。
|