【问题标题】:C++: operator precedence from a Stroustrup exampleC++:来自 Stroustrup 示例的运算符优先级
【发布时间】:2020-06-07 18:20:14
【问题描述】:

Stroustrup C++ 第 4 版第 197 页包含以下示例,这些示例导致打印的字符流递增,直到 null 而不是 "abc"。问题:如何评估++*p++* 是相同的优先级和从右到左的评估,因此我的理解是 *p 首先评估,导致字符 p 指向,然后这个字符增加 ++。这种理解正确吗?谢谢

#include <iostream>
using namespace std;

void fp(char* p)
{
    while (*p)
        cout << ++*p;
}

void fr2(char& r)
{
    char* p = &r;
    while (*p)
        cout << ++*p;
}


int main(int argc, char *argv[])
{
    char s[] = "abc";
    char *p = s;

    fp(p);
    fr2(*p);

    return 0;
}

【问题讨论】:

  • 这里不可能有歧义。请考虑使用*p++
  • 谢谢 我知道应该使用*p++ 来打印字符串。我只是通过 Stroustrup 的例子,这并没有出现在他的勘误表中 stroustrup.com/4th_printing3.html
  • 我会说“这是一个错误”。此外,这本书有点过时了,所以您可能应该寻找更现代的参考。
  • 我的意思是 ++*p 被明确地解析为 ++(*p) 而不考虑优先级和关联性。这些规则仅用于解决歧义。相比之下,*p++ 模棱两可的,我们需要一些规则来解决歧义。
  • @Evg *p++ 模棱两可?在现代解释中,++ 的优先级高于 *,因为 ++ 是后缀,因此在计算行之后执行操作。导致取消引用 p 用作表达式的值,然后递增指针。我相信 K&R *++ (后缀或前缀)具有相同的优先级,但 assoc 是从右到左的。它仍然会导致上述评估。

标签: c++


【解决方案1】:

是的,您对优先级和关联性的看法是正确的。这个表达式:

++*p;

被解析为

++(*p);

即首先p的间接寻址完成​​,然后返回值递增。

这意味着在while循环中:

while (*p)
    cout << ++*p;

指针p 从未真正递增。这会导致无限循环,其中只有 p[0] 的值会永远递增。

这是一个demo,它将输出显示为从a 开始的很长的ascii 值序列。请注意,abc没有打印出来。

同理,表达式:

*++p;

被解析为:

*(++p);

这很好,因为指针先递增,然后指针被取消引用。

【讨论】:

  • 为什么优先级在这里很重要?如果++ 的优先级高于/低于*,会发生什么变化?
  • @Evg 这将影响首先评估哪个运算符。由于预增量和间接具有相同的优先级,因此关联性开始发挥作用。也编辑了答案。
  • 我认为这不是真的。 ++*p 怎么可能被解析为 ++(*p) 以外的东西?相比之下,*p++ 可以解析为*(p++)(*p)++
  • 代码本质上是增加*p 的值直到*p == 0。因为++ 是前缀,所以每次调用cout 之前都会发生递增。这就是我能说的。
  • @Evg 同意,我不是说++*p 可以被解析为其他任何东西。 (考虑到这些运算符的优先级和关联性)。
猜你喜欢
  • 2014-03-01
  • 1970-01-01
  • 2013-02-24
  • 2017-06-02
  • 1970-01-01
  • 2019-01-17
  • 2021-03-29
  • 2013-07-31
相关资源
最近更新 更多