C/C++ 匪夷所思的特性们
逗号表达式
形如
(exp1, exp2, exp3)
的表达式的返回值是 exp3
,毋庸置疑。
但在:
(func1, func2, func3)
中。
三个函数的执行顺序却是未规定的,换句话说,C++的编译器可以任意、随意地规定三个函数的执行顺序。
这非常致命,因为这可能会导致我们的结果偏离预期。
见样例:
#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
string str;
while (cin >> str)
cout << count(str.begin(), str.end(), '*') << " " << (str.erase(remove(str.begin(), str.end(), '*'), str.end()), str) << endl;
return 0;
}
这个程序写的非常难以阅读,但其的效果是 统计一个字符串中有多少个,并输出该字符串去掉后的新字符串
观察代码,并没有不妥之处。本地运行,输出也符合期望。但提交却提示答案错误。
结合上文的经验,我们把代码修改为:
#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
string str;
while (cin >> str)
{
cout << count(str.begin(), str.end(), '*') << " ";
str.erase(remove(str.begin(), str.end(), '*'), str.end());
cout << str << endl;
}
return 0;
}
这时答案正确。
为什么呢,可以发现原程序 Line 12 逗号表达式中的
str.erase(remove(str.begin(), str.end(), '*'), str.end()), str
语句有可能在 count()
返回结果前就伤害了 str
。从而导致其返回未预期的结果。