58-C++赋值比较可能犯的错误

赋值比较和可能犯的错误

不要混淆等于运算符(= =)与赋值运算符(=)。下面的表达式问了一个音乐问题——musicians是否等于4?

musicians == 4

该表达式的值为true或false。下面的表达式将4赋给musicians :

musicians = 4;

在这里,整个表达式的值为4,因为该表达式左边的值为4。

for循环的灵活设计让用户很容易出错。如果不小心泄漏了==运算符中的一个等号,则for循环的测试部分将是一个赋值表达式,而不是关系表达式,因此代码仍是有效的。这是因为可能将任何有效的C++表达式用作for循环的测试条件。别忘了,非零值为true,零值为false。将4赋给musicians的表达式的值为4,因此被视为true。如果以前使用过用=判断是否相等的语言,如Pascal或BASIC,则尤其可能出现这样的错误。

下列程序指出了可能出现这种错误的情况。该程序试图检查一个存储了测验成绩的数组,在遇到第一个不为20的成绩时停止。该程序首先演示了一个正确进行的循环,然后是一个在测试条件中错误地使用了赋值运算符的循环。该程序还有另一个重大的设计错误,稍后将介绍如何修复(应从错误中吸取教训,而程序在这方面很有帮助)。

//equal.cpp——equality vs assignment
#include<iostream>
int main()
{
    using namespace std;
    int quizscores[10] = { 20 , 20 , 20 , 20 , 20 , 19 , 20 , 18 , 20 , 20};
    cout<<"Doing it right:\n";
    int i;
    for( i =0 ;quizscores[i] ==20 ;i++)
        cout<<"quiz "<<i<<" is a 20\n";
//Warning:you may prefer reading about this program
//to actually running it.
    cout<<"Doing it dangerously wrong :\n";
    for( i =0 ; quizscores[i] = 20;i++)
        cout<<"quiz "<<i<<" is a 20\n";
    return 0;

}

由于这个程序存在一个严重的问题,读者可能希望了解它,以便真正运行它。下面是该程序的一些输出:

第一个循环在显示了前5个测试成绩后正确地终止,但第二个循环显示整个数组。更糟糕的是,该程序可能导致其他应用程序无法运行,您必须重新启动计算机。

当然,错误出在下面的测试表达式中:

quizscores[i ]=20;

首先,由于它将一个非零值赋给数组元素,因此表达式始终为非零,所以始终为true。其次,由于表达式将赋值给数组元素,它实际上修改了数据。第三,由于测试表达式一直为true,因此程序在到达数组结尾后,仍不断修改数据。它把一个又一个20放入内存中!这会带来不好的影响。

发现这种错误的困难之处在于,代码在语法上是正确的,因此编译器不会将其视为错误(然而,由于C和C++程序员频繁地犯这种错误,因此很多编译器都会发出警告,询问这是否是设计哲的真正意图)。

警告:不要使用=来比较两个量是否相等,而要使用==。

和C语言一样,C++比起大多数编程语言来说,赋予程序员更大的自由。这种自由以程序员应付的更加责任为代价。只有良好的规划才能避免程序超出标准C++数组的边界。然而,对于C++类,可以设计一种保护数组类型来防止这种错误,以后提供了这样的例子。另外,应在需要的时候在程序中加入保护措施。例如,在上个程序的循环中,应包括防止超出最后一个成员的测试,这甚至对于“好”的循环来说是必要的。如果所有的成绩都是20.“好”的循环也会超出数组边界。总之,循环需要测试数组的值和索引的值。后面将介绍如何使用逻辑运算符将两个这样的测试合并为一个条件。

猜你喜欢

转载自blog.csdn.net/qq_41200424/article/details/82560014