C/C++ 匪夷所思的特性们
逗号表达式
形如
(exp1, exp2, exp3)
的表达式的返回值是 exp3 ,毋庸置疑。
但在:
(func1, func2, func3) 中。
三个函数的执行顺序却是未规定的,换句话说,C++的编译器可以任意、随意地规定三个函数的执行顺序。
这非常致命,因为这可能会导致我们的结果偏离预期。
见样例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #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; }
|
这个程序写的非常难以阅读,但其的效果是
统计一个字符串中有多少个,并输出该字符串去掉后的新字符串
观察代码,并没有不妥之处。本地运行,输出也符合期望。但提交却提示答案错误。
结合上文的经验,我们把代码修改为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| #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
。从而导致其返回未预期的结果。