让我们的补丁雅致一点

来源:互联网 发布:域名指向企业官网解析 编辑:程序博客网 时间:2024/04/28 04:37

《C++ Primer》中提供了一个简单的例子来教我们应该如何为现有的程序打补丁。修改程序或许很容易,但是如果我们不注意一些细节上的处理可能会让修改后的程序很难读懂。

这是一个计算 C 风格字符串长度的实现。注意了,因为我们是要为程序打补丁,理所当然地,以下这个实现是有问题的:

 
#include <iostream>

using namespace std;

const char *st = "The expense of spirit ";

int main() {
int len = 0;

while( st++ ) ++len; }

cout 
<< len << "" << st;
return 0;
}

在这 个实现中不难发现错误在于循环 while( st++ ),我们是要利用 C 风格字符串以 '/0' 字符结束的特性来计算其长度。st++ 表示的不是字符串中的字符数值,而是字符的地址。因此,while( st++ ) 应该改为 while( *st++ )。

这时候,len 的值是计算正确了,但是必须注意,在 cout << st 中, st 已经前进到终止空字符之后的字符上去了。往往,有些人会这样处理:在 cout 前加入一条语句 st = st - len - 1;


#include <iostream>

using namespace std;

const char *st = "The expense of spirit ";

int main() {
int len = 0;

while*st++ ) ++len; }

st 
= st - len - 1;
cout 
<< len << "" << st;
return 0;
}


经过修改,此时程序是正确了。可是任何看了修改后的程序也会觉得别扭。确实 st = st - len -1; 如此赋值并不符合程序的原始逻辑,而且修改后的程序并不容易理解。

如此翻来覆去的修改,已经使得代码不太雅致了。

在打补丁的时候,必须考虑修改后的程序逻辑是不是明了,对问题是否考虑周全了。

《C++ Primer》提示了一个方法来处理这个实现的 bug,这也是我平时最喜欢使用的,对于在一个作用域中需要重复使用的变量,我会另外定义的一个同类变量来做变化参数。

在这个例子中,我定义了另一个指针 p,并用 st 对它初始化。
const char *p = st;
用 p 来计算长度,st 就不用改变了。
while( *p++ )

修改后的代码如下:

#include <iostream>
using namespace std;

const char *st = "The expense of spirit ";

int main() {
    
const char *= st;
    
int len = 0;

    
while*p++ ) ++len; }

    cout 
<< len << "" << st;
    
return 0;
}

原创粉丝点击