以下代码展示了这种差异:
#include <iostream>
#include <string>
int main()
{
char s[] = "ABCD";
std::string str(s);
char *p = s;
while(*p) {
*p++ = tolower(*p); // <-- incr after assignment
}
std::cout << s << std::endl;
std::string::iterator it = str.begin(), end = str.end();
while(it != end) {
*it++ = tolower(*it); // <-- incr before assignment ?
}
std::cout << str << std::endl;
return 0;
}
它产生输出:
abcd
bcd
如果我们将赋值操作和增量运算符分开:
while(it != end) {
*it = tolower(*it); // <-- incr before assignment ?
it++;
}
输出将按预期进行。
原始代码出了什么问题?
$ g++ --version
g++ (GCC) 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)
Copyright (C) 2004 Free Software Foundation, Inc.
答案 0 :(得分:9)
问题是operator=
的参数评估顺序未指定。这是根据C ++标准5.2.2 / 8。请考虑以下事项:
*it++ = tolower(*it);
等于
operator=( *it++, tolower(*it) );
现在可以在*it++
之前计算tolower(*it)
,反之亦然。
答案 1 :(得分:2)
*it++ = tolower(*it);
*p++ = tolower(*p);
这两行都会调用未定义的行为。您不能在单个语句中多次修改变量的值(++修改一次,operator =修改两次)。
因此,您获得不同的价值这一事实并不令人惊讶。
答案 2 :(得分:2)
对于指针和迭代器,语法的工作方式完全相同。运算符隐含的操作转换为类类型对象的函数调用(例如大多数迭代器)。
您的代码的问题不在于运算符优先级,但在这两行中,增量操作和第二次读取同一变量之间没有排序,该变量在语句的其他位置递增。因此,您有未定义的行为,因此他可能会看到您的程序中的任何行为,包括您看到的结果。
*p++ = tolower(*p);
*it++ = tolower(*it);
您需要以定义排序的方式重新构造此语句。我猜你想要这样的东西。
char c = tolower(*p);
*p++ = c;