【问题标题】:Function returning unexpected struct values函数返回意外的结构值
【发布时间】:2015-10-25 15:56:38
【问题描述】:

我对结构和用户定义的数据类型完全陌生,我试图创建一个返回结构的函数:

评论突出了问题:

#include <iostream>

using namespace std;

struct num {
    int n[2];
};

num func( num x, int a, int b) {
    x.n[0] = a+b;
    x.n[1] = a*b;
    return x;
}

int main() {
    int x,y;
    num s1;
    cout << "enter: ";
    cin >> x >> y;
    func(s1,x,y);
    cout << s1.n[0] << "\n" << s1.n[1];        // THIS GIVES ERROR
    cout << func(s1,x,y).n[0] << "\n" << func(s1,x,y).n[1];  // THIS DOENST GIVE ERROR
    return 0;
}

我知道第二种方法有意义并返回结构变量。然后放一个点地址结构的内部变量。

但我不明白为什么第一种方法会失败,或者给出奇怪的输出。该函数已经完成了它的工作,即创建了s1.n[0] = x + ys1.n[1] = x*y
现在,打印s1.n[0] 应该只打印x + y。我们如何检查和纠正函数的内部运作?

【问题讨论】:

  • 究竟是哪个错误?请照常提供minimal reproducible example
  • @πάνταῥεῖ:问题显而易见。而且,好吧,无论如何,这一个 MCVE。

标签: c++ function struct


【解决方案1】:

您必须将返回值分配给main中的结构对象

s1 = func(s1,x,y);

在主体内部,函数处理原始对象的副本。它不会改变原始对象,因为它是按值传递的。

另一种方法是通过引用传递结构

void func( num &x, int a, int b) {
    x.n[0] = a+b;
    x.n[1] = a*b;
}

在这种情况下,您可以在 main 中编写

func(s1,x,y);

或者你甚至可以使用所谓的 C 方法通过引用传递

void func( num *x, int a, int b) {
    x->n[0] = a+b;
    x->n[1] = a*b;
}

然后这样称呼它

func( &s1, x, y );

至于这个说法

cout << func(s1,x,y).n[0] << "\n" << func(s1,x,y).n[1];  

然后您访问由函数的两次调用返回的两个临时对象的数据成员。执行此语句后,这些临时对象将被删除。

【讨论】:

  • 谢谢,但为什么要这样做?函数不是这样做的吗?
  • @TimKrul:不。你的代码复制了你的num,修改它然后返回它。您的 main 函数对这个新的修改版本没有任何作用。
  • 哦,我没有过多关注按值类调用。谢谢!
【解决方案2】:

看起来您从未分配func() 的返回值。您的函数返回结构,但您从未分配它。要解决这个问题,您应该可以简单地说:s1 = func(s1,x,y); 这会将结构的修改版本分配给 s1 变量。

或者,您可以重写func() 以接受指向结构的指针。这将允许您修改结构而无需返回它:

 void func( num *x, int a, int b) {
     x->n[0] = a+b;
     x->n[1] = a*b;
 }

然后你只需将你的电话改为func() 说:func(&amp;s1, x, y);

【讨论】:

    【解决方案3】:

    你没有通过引用传递你的结构,因此结果。请尝试以下操作:

    void func(num &x, int a, int b) { 
        x.n[0] = a+b;
        x.n[1] = a*b;
    }
    

    函数不需要返回任何东西,因为你的结构是通过引用传递的,无论如何它都会被改变。 Void 会更合适。

    【讨论】:

    • 那为什么要保留num的返回类型呢?它从未使用过。弗拉德的回答更好。
    【解决方案4】:

    这是因为您已经通过值传递了结构,而您的意图看起来像是要通过引用传递。 检查此链接:http://courses.washington.edu/css342/zander/css332/passby.html

    num func( num &x, int a, int b) 
    

    应该解决你的问题

    【讨论】:

    • 那为什么要保留num的返回类型呢?它从未使用过。
    • @LightnessRacesinOrbit 取决于 func 的用例。从这个问题看来,OP 对将参数传递给函数的语义感到困惑。对象返回一个实例并修改传递给它的参数的情况有先例。
    • 当然有,但“默认”方法应该是清晰简单的方法,即使用 OP 已经获得的返回值。您的答案保留了该值,但使其完全多余;对我来说,这似乎是一种倒退。
    猜你喜欢
    • 1970-01-01
    • 2011-05-19
    • 1970-01-01
    • 1970-01-01
    • 2022-01-09
    • 1970-01-01
    • 1970-01-01
    • 2011-12-02
    • 1970-01-01
    相关资源
    最近更新 更多