C ++中的运算符优先级对于指针和迭代器是否不同?

时间:2010-05-28 06:34:18

标签: c++ stl

以下代码展示了这种差异:

#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.

3 个答案:

答案 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;