关于C ++:C ++-传递未知大小的数组

C++ - passing an array of unknown size

本问题已经有最佳答案,请猛点这里访问。

尝试传递以1开头的连续数字的int数组,但假设接收此数组的函数不知道其长度。 尝试计算函数内部的长度时,它只会给我1,因为它仅在计算sizeof(arrayName)时会找到第一个元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
using namespace std;

int Sum(int intArray[]) {
    int n = sizeof(intArray) / sizeof(*intArray);
    cout <<"Array size in function:" << n << endl;
    return n * (n + 1) / 2;
}

int main() {
    int anArray[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int arraySum = Sum(anArray);

    cout <<"Array size in main:" << sizeof(anArray) / sizeof(*anArray) << endl;
    cout <<"Sum is:" << arraySum;
    int a;
    cin >> a;
    return 0;
}


您的函数正在使用指向int的指针。当您将数组传递到指针时,所有大小信息都会丢失。但是,您可以使用函数模板来实例化与正确的数组大小匹配的函数:

1
2
3
4
5
6
template <size_t N>
int Sum(const int (&intArray)[N])
{
  cout <<"Array size in function:" << N << endl;
  return std::accumulate(std::begin(intArray), std::end(intArray), 0);
}

Sum函数将接受编译时已知的纯数组或大小。但是,在这些情况下使用std::array或在运行时选择大小的情况下使用std::vector更有意义。

请注意,对std::accumulate的调用只是解决总和问题的示例。它不需要N知识,可以完全替换该功能。大小由std::beginstd::end照顾。您分别需要accumulatebegin/end的标头


在此函数声明中

1
int Sum(int intArray[]);

作为参数传递给它的数组将隐式转换为指向数组第一个元素的指针。所以这个声明相当于

1
int Sum( int *intArray );

和表达

1
int n = sizeof(intArray) / sizeof(*intArray );

相当于

1
int n = sizeof( int * ) / sizeof( int );

如果sizeof(int *)等于sizeof(int),则n等于1。

如果以这种方式声明参数,则还应该声明第二个参数,该参数将接受数组中的元素数量。所以我会用以下方式重写函数

1
2
3
4
5
6
7
8
int Sum( int intArray[], size_t n )
{
    int sum = 0;

    for ( size_t i = 0; i < n; i++ ) sum += intArray[i];

    return sum;
}

而且我主要会通过以下方式调用该函数

1
int arraySum = Sum( anArray, sizeof( anArray ) / sizeof( *anArray ) );

}

同样,通常编写函数来执行一些通用算法。只为具有从1到大约N的连续值的数组编写函数是一个坏主意。