翻译《有关编程、重构及其他的终极问题?》——9.使用’\0’符号作为结尾标记
标签(空格分隔): 翻译 技术 C/C++
作者:Andrey Karpov
翻译者:顾笑群 - Rafael Gu
最后更新:2016年12月10日
本书背景说明、总目录等介绍,可以跳转到以下链接进行查看:
http://blog.csdn.net/headman/article/details/53045891欢迎大家转载,但请附上原作者以及翻译者的名字、原文出处,以尊重光荣的劳动者。
9.使用’\0’符号作为结尾标记
下面这段代码来自Nodepad++项目(译者注:我个人非常喜欢免费开源的Nodepad++多功能文本编辑器,在这里推销一下)。PVS-Studio诊断出来的错误说明为:The error text: V528 It is odd that pointer to ‘char’ type is compared with the ‘\0’ value. Probably meant: headerM != ‘\0’(译者注:大意是指向char类型的指针和’\0’直接比较是奇怪的,可能本意是:*headerM != ‘\0’,注意,加了一个)。
TCHAR headerM[headerSize] = TEXT("");
...
size_t Printer::doPrint(bool justDoIt)
{
...
if (headerM != '\0')
...
}
解释
非常感谢上面代码的作者使用了\0
来标明字符串结尾标示(译者注:作者意思是幸亏作者没有直接使用0,看后面就明白了),让我们可以容易的发现并修复错误,从一定意义上来说(译者注:虽然作者犯了错),但这个错误还是不错的(译者注:作者有点小嘲讽又带点小欣赏,看后面就知道了)。
想象一下,如果上面的代码写成如下的方式:
if (headerM != 0)
那么这个字符数组的地址就要和0比较,那么这个比较结果就毫无意义了,因为绝大多数指针的地址都是非0的,所以这个返回总是true,那么问题就来了,这是个错误还是个多余的检查呢?特别是如果代码是很久之前就被写好的(译者注:你敢轻易修改吗?)
但是,自从程序员们开始使用\0
以来,我们就能明确知道只是用来做字符串结尾比较的。另外,虽然我们知道使用headerM指针和NULL比较同样无意义(译者注:0、NULL和\0
大部分情况都是一个值,表意不同而已),但归根到底,我们用NULL和\0
就能让程序员们分清到底是进行一个指针是否为空的比较,还是一个字符串的结尾符比较,这样就能避免一些错误。为了修复上面的代码,我们还需要增加一个指针解除操作。
正确的代码
TCHAR headerM[headerSize] = TEXT("");
...
size_t Printer::doPrint(bool justDoIt)
{
...
if (*headerM != _T('\0'))
...
}
建议
比较语句中,不推荐直接使0,而是使用NULL,false或者字符串结尾符号\0
,如果都用不上,再考虑使用0。所以,不要偷懒,避免使用在所有情况中使用0,这样就能让代码更容易理解,并且更容易发现错误。
下面是一些技巧:
- 0 - 只使用在需要整型值0的情况;
- nullptr - 作为C++的null指针;
- NULL - 作为C的null指针;
\0
,L\0
,_T\0
- 作为字符串结尾符;- 0.0,0.0f - 作为浮点值的0;
- false,FALSE - 作为false;
坚持使用上面的规则可以让你的代码更干净,使你的代码在review的时候更容易找到问题。