【问题标题】:structure and functions in C++C++中的结构和函数
【发布时间】:2017-03-13 01:42:17
【问题描述】:

有人能解释一下为什么这段代码会输出 10 吗?当我尝试分析它时,我的逻辑给出了结果 11。

#include <iostream>
using namespace std; 
class A { 
public:     
    A() { a.a = a.b = 1; }   
    struct { int a,b; } a;  
    int b(void); 
};

int A::b(void) { 
    int x=a.a;
    a.a=a.b;
    a.b=x; 
    return x; 
};

int main(void) {     
    A a;
    a.a.a = 0;
    a.b();
    cout << a.b() << a.a.b << endl;
    return 0;
}

【问题讨论】:

  • 欢迎来到 Stack Overflow。请花时间阅读The Tour 并参考Help Center 中的材料,您可以在这里问什么以及如何问。
  • 调试器是解决此类问题的正确工具。 询问 Stack Overflow 之前,您应该逐行浏览您的代码。如需更多帮助,请阅读How to debug small programs (by Eric Lippert)。至少,您应该 [编辑] 您的问题以包含一个重现您的问题的 Minimal, Complete, and Verifiable 示例,以及您在调试器中所做的观察。
  • 也许读过Sequence Points
  • @πάνταῥεῖ 它确实包含一个 MCVE。
  • @M.M 嗯,这是一个股票评论,包括 OP 错过的可能性。不过,我仍然没有在问题中看到任何调试工作。

标签: c++ struct


【解决方案1】:

cout 行中,a.b() 可以在评估a.a.b 之前或之后调用。初学者有时会在这种代码中假设从左到右的评估,但实际上这不是 C++ 的规则。

这两种不同的可能性可以解释您的1011。为避免歧义,您可以这样写:

cout << a.b();
cout << a.a.b << endl;   

(假设订单是您的意图)。

注意:C++17 may change this 并为此代码定义左右评估顺序。

【讨论】:

    【解决方案2】:

    除了使用调试器,您还可以使用cout 语句来帮助跟踪调用的时间。

    为了帮助自己跟踪你的程序,我修正了一些缩进并添加了关于何时发生的事情:

    #include <iostream>
    using namespace std; 
    class A {
    public:
        A() {
            a.a = a.b = 1;
        }
        struct {
            int a,b;
        } a;
        int b(void); 
    };
    
    int A::b(void) {
        cout << "Within A::b()" << endl;
        // swap a.a, a.b
        int x=a.a;
        a.a=a.b;
        a.b=x;
    
        cout << "a.a.a = " << a.a << " a.a.b: " << a.b << endl;
    
        return x;
    };
    
    int main(void) {
        // sets a.a.a = 1, a.a.b = 1
        A a;
        // sets a.a.a = 0, a.a.b = 1
        a.a.a = 0;
        // a.a.a = 1, a.a.b = 0
        a.b();
        // check output here
        cout << a.b() << a.a.b << endl;
        return 0; 
    }
    

    上述程序在http://cpp.sh/ 上产生以下输出:

    Within A::b()
    a.a.a = 1 a.a.b: 0
    Within A::b()
    a.a.a = 0 a.a.b: 1
    10
    

    总而言之,这取决于调用cout时是先解析a.b()还是a.a.b。在这种情况下,由于cout 的工作方式,运算符优先级未定义。 This stackoverflow post 对此有一些很好的信息。

    【讨论】:

    • 感谢您抽出宝贵的时间将您的 cmets 添加到代码中...我非常感谢它,它非常有帮助...谢谢乔
    猜你喜欢
    • 1970-01-01
    • 2013-10-15
    • 2012-02-27
    • 2018-11-05
    • 2020-09-05
    • 1970-01-01
    • 2010-11-10
    • 1970-01-01
    相关资源
    最近更新 更多