C++ 中运算符优先级是否相同?指针和迭代器有什么不同?

发布于 2024-09-03 10:48:25 字数 1012 浏览 2 评论 0原文

下面的代码演示了这种差异:

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

The code below demonstrates this difference:

#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;
}

it produces output:

abcd
bcd

if we separate assignment operation and increment operator:

while(it != end) {
  *it = tolower(*it);        // <-- incr before assignment ?
  it++;
}

the output will be as expected.

What's wrong with the original code?

$ g++ --version
g++ (GCC) 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)
Copyright (C) 2004 Free Software Foundation, Inc.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

沩ん囻菔务 2024-09-10 10:48:25

问题在于 operator= 参数的求值顺序未指定。这是根据 C++ 标准 5.2.2/8 的。考虑以下情况:

*it++ = tolower(*it);

等于

operator=( *it++, tolower(*it) );

现在可以在 tolower(*it) 之前计算 *it++,反之亦然。

The problem is that the order of evaluation of arguments of operator= is unspecified. This is according to C++ Standard 5.2.2/8. Consider the following:

*it++ = tolower(*it);

is equal to

operator=( *it++, tolower(*it) );

Now *it++ could be computed before tolower(*it) and vice versa.

黑色毁心梦 2024-09-10 10:48:25
*it++ = tolower(*it); 
*p++ = tolower(*p);

这两行都会调用未定义的行为。您不能在一条语句中多次修改变量的值(++ 修改一次,operator = 修改两次)。

因此,您获得不同的值这一事实并不令人惊讶。

*it++ = tolower(*it); 
*p++ = tolower(*p);

Both of these lines invoke undefined behaviour. You cannot modify the value of a variable more than once in a single statement (++ modifies once, operator = modifies twice).

So the fact that you get different values is unsurprising.

时光匆匆的小流年 2024-09-10 10:48:25

指针和迭代器的语法完全相同。运算符隐含的操作被转换为类类型对象(例如大多数迭代器)的函数调用。

不过,代码的问题不在于运算符优先级,在这两行中,递增操作和第二次读取在语句中其他地方递增的同一变量之间没有顺序。因此,您有未定义的行为,因此他可能会看到您程序中的任何行为,包括您所看到的结果。

*p++ = tolower(*p);

*it++ = tolower(*it);

您需要以定义顺序的方式重新表述该语句。我猜你想要这样的东西。

char c = tolower(*p);
*p++ = c;

The grammar works exactly the same for pointers and iterators. The operations implied by operators are turned into function calls for objects of class type (such as most iterators).

The issue with your code isn't with operator precedence though, in both of these lines there is no sequencing between the increment operation and the second read of the same variable that is incremented elsewhere in the statement. Because of this, you have undefined behaviour so he might see any behaviour from your program including the results that you are seeing.

*p++ = tolower(*p);

*it++ = tolower(*it);

You need to reformulate this statement in a way in which the sequencing is defined. I'm guessing that you want something like this.

char c = tolower(*p);
*p++ = c;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文