不创建变量,能否将数组作为参数传递给函数?

4

我写了一个函数,它的参数是数组。我尝试通过传递未定义为变量的数组(如{0,0,0,0})来调用该函数。然而,系统报错:“初始化值太多”。

假设我们定义了以下函数:

int func(int values[]) {
  int average = 0;
  for(int x = 0; x < values.size(); x++) {
    average += values[x];
  }
  return average / values.size();
}

我们希望不需要像这样定义一个数组来传递参数,就能调用函数:func({1,6,7,2})

是否有一种方法可以实现这样的效果,还是必须定义一个数组并将其传递到函数中?

4个回答

4

使用内置数组是无法实现这个目标的。因为数组既不可赋值也不可复制,同时它们也不是类,所以没有size()成员函数或者初始化列表。

如果大小是常量,可以使用std::array来实现;如果大小是动态的,则可以使用std::vector来实现。

#include <array>


int func(const std::array<int, 5>& values) { 

    int average = 0;
    for (size_t x{}, sz{ values.size() }; x != sz ; ++x)
        average += values[x];

    return average / values.size();
}



int main() {
    auto ret{
        func({ 1, 6, 7, 2 })
    };

    std::cout << ret << std::endl;
}
  • Also don't mix Unsigned with Signed in calculations like in your loop:

    for(int x = 0; x < values.size(); x++) // x is int while values.size() is unsigned int.
    
  • int func(const std::array<int, 5>& values): pass by reference to avoid the copy especially if the size is big. Also pass by const as long as the function doesn't intend to change the parameter also another benefit of using const reference is you can pass literals instead of an object.

  • N.B: I recommend to also to use range-based for because it is really relevant in your example as long as you want to iterate over all the elements and not intending to insert nor to delete elements:

    int average = 0;
    for (const auto& e : values)
        average += e;
    
  • Another version of func as @M.M pointed out is to use std::accumalate to do the job for you:

    int func(const std::array<int, 5>& values) {    
        return std::accumulate(values.begin(), values.end(), 0) /
            values.size();
    }
    

2
通过引用传递,取得巨大成功。 - Lightness Races in Orbit
这个答案对我有用,但是当我的参数中有一个二维的std::array(比如{{ {"Character", "hello"} }})以及一个普通的std::array时,出现了一个错误,提示“无法将参数<数字>从初始化列表转换为std::array”。我会编辑我的帖子,包括更多细节。 - Cyerunix
@CodyFG:请提出另一个问题。因为继续编辑主题是不相关的。 - Raindrop7
@M.M:是的,我在答案的结尾指出了这一点。只要我不需要额外复制并且不改变数组元素,我就将循环变量设置为const auto& - Raindrop7
1
好的。我不会使用引用,因为我们只是在谈论一个 int,但这真的取决于个人偏好。 - M.M

3
使用向量,是的:
#include <vector>
using namespace std;

void f( const vector <int> & v ) {
}

int main() {
    f( {1,2,3,4} );
}

@Rietty 不要通过s/vector/array/来实现。 - user2100815

1

数组不是这样工作的。当你将一个数组传递给一个函数时,第一个元素的地址被传递类似于指针,并且在函数内部没有关于数组大小的更多信息。(编译器本身可以推断大小,因为数组在范围内声明,但是函数可以从任意数量的位置调用)

如果你想做这样的事情,你要么使用容器类,比如vector,或者你可以传递第二个参数到函数中,说明数组的大小。另一种方法是在数组中有某种结束点,例如c-strings,例如null值。


1
实际上,您可以像这样将数组传递到函数中:
avg({1, 2, 3}); 

通过使用模板,可以在编译时推断出数组大小。

这里有一个例子

template<std::size_t N>
double avg(const int (&values)[N]) {
  double sum = 0;
  for(auto v: values) {
    sum += v;
  }
  return sum / N;
}

int main() {
    std::cout << avg({1, 2, 3});
}

请注意,该函数必须将数组作为const引用传递。
另请参见相关答案

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接