从C或c++中的函数返回多个数据项

Returning multiple data items from a function in C or C++

本文关键字:返回 数据项 函数 c++      更新时间:2023-10-16

我对几个作业问题感到困惑…你可以通过return()从函数返回多个数据项吗?一个函数只能返回一个值,除非它是指向数组的指针?

我相信答案是一个函数可以通过返回一个结构来返回多个数据项。然后,返回指向数组的指针不是唯一的方法-如果这是一种方法?

但是似乎有很多关于这个话题的讨论,所以我想确保我至少有基本的想法是正确的:你可以使用一个结构返回多个数据项,但使用指针(我不明白这一点)会更有效地使用内存。这是正确的吗?

对于c++ 0x/c++ 11,可以这样使用:

#include <string>
#include <iostream>
#include <tuple>
using namespace std;
tuple<int, unsigned, string, int> getValues()
{
    return tuple<int, unsigned, string, int>(1, 2, "3", 4);
}
int main()
{
    int a;
    unsigned b;
    string c;
    int d;
    tie(a, b, c, d) = getValues();
    cout << a << ", " << b << ", " << c << ", " << d << endl;
    return 0;
}
用 编译
g++ tuple_test.cpp -std=c++0x -o tuple_test

如果你运行这个程序,它会输出如下内容:

1, 2, 3, 4

但最好使用这样的引用(我想说):

void getValues(int& a, unsigned& b, string& c, int& d)
{
    a = 1;
    b = 2;
    c = "3";
    d = 4;
}
int main()
{
    ...
    getValues(a, b, c, d)
    ...
}

这就是我没有仔细阅读问题的结果…

函数只能返回一个值,除非它是指向数组的指针?

是的,你只能返回一个值,但是这个值可以包含多个值(结构体,类,数组)。

你可以使用结构返回多个数据项,但使用指针(我不明白这一点)将更有效地使用内存。这是正确的吗?

正确的。但是当你使用指针时,这取决于你如何使用它。当你动态分配每个函数调用时,它不会非常有效,你需要在使用后手动释放内存。当你使用全局数组/结构体时,它将是高效的。但是当你多次调用这个函数时,就会出现问题。

除了在这个线程中已经说过的,在c++ 11中您可以返回使用统一初始化初始化的结构:

struct XYZ {
    int x;
    int y;
    int z;
};
XYZ foo() {
    return {1, 2, 3};
}

我个人更喜欢返回带命名成员的结构体,而不是元组,因为元组不提供其成员的名称。

正确。

然而,您可以通过添加引用传递的参数,然后将多个结果写入它们来"返回"多个项。

一个函数在它的返回语句中确实只能返回一个"东西"。然而,这个东西可以是一个指针(C &c++数组只是指针的伪装),引用(不能重定位或数组索引的指针)或对象,可以封装多个东西。

如果返回一个结构体,则返回整个结构体。如果你返回一个指针或引用,你返回的只是结构体的地址——所以你最好不要返回一个结构体的引用或指针,因为当函数返回时结构体已经超出了作用域!这样做会调用未定义的行为,这很可能(但并不总是)是分段错误。

如果你想更全面地了解这一点,请阅读按值传递参数和按引用传递参数,它也适用于返回参数。

如你所述:

你可以使用结构返回多个数据项,但使用指针(我不明白这一点)将更有效地使用内存。这是正确的吗?

假设你有一些结构:

struct BigStructure{
       int array[1000];
       double otherData[1000];
       //... etc
};

和一些方法:

BigStructure workWhenCopying(BigStructure bigStruct){
      // some work with a structure
      return bigStruct;
}

这个方法说明了当您向方法传递参数并按值返回它时的情况,这意味着每次调用该方法时,您都将方法的参数复制到内存中的另一个位置。这种复制需要时间,当你有更大的结构体时,它会减慢程序的运行时间,因此通过引用传递大的结构体会更有效。

void workWithReference(BigStructure & bigStruct){
     // do some work
}

在这种情况下,你不是复制整个数据结构,只是传递该结构所在的内存地址。您也不需要return语句,因为对该结构对象的更改将在此方法外部可见。但是如果你将bigStruct重新分配到一个新的内存位置,它将只在局部方法中可见:workWithReference

我希望它现在更清楚;)