繁体   English   中英

如何通过引用将 C++ 数组作为 function 参数传递?

[英]How to pass by reference a C++ array as a function parameter?

要通过引用将 C 样式数组作为参数传递给 function,还需要将数组大小作为参数发送给 function。 下面的代码显示了一个 function,它接受一个数组作为通过引用传递及其大小。 Q1)有没有办法,我们可以通过引用传递 arrays 而不传递它的大小? Q2) 如果我要重载下面的 function get_num_of_even_digited_input() 以接受数组容器 (std::array) 作为第一个参数,那么 function 原型会是什么样子? (我的意思是如何提及数组的 size_t 参数?它会是 int get_num_of_even_digited_input(array<int,??> )

int get_number_of_digits(int in_num)
{
    int input = in_num, rem = -1, dividend = -1, dig_count = 0;
    
    while(input)
    {
        dig_count++;
        dividend = input % 10;
        input = input/10;
    }

    return dig_count;
}

int get_num_of_even_digited_input(int arr[], int size_arr)
{
    int arrsize = 0, i = 0, count_of_evendigited_num = 0, count_of_dig = 0;
    arrsize = size_arr;

    for(i = 0; i < arrsize; i++, arr++)
    {
        count_of_dig = get_number_of_digits(*arr);
        if(count_of_dig % 2 == 0)
        {
            count_of_evendigited_num++;
        }
    }

    return count_of_evendigited_num;
}

void main()
{
    int array2[] = {23, 334, 4567, 1, 259};
    int sizearr2 = sizeof(array2)/sizeof(int);

    array<int, 6> array3 = {23, 5677, 564, 342, 44, 56778};

    cout << "Count of even digited numbers in array2[] : " << get_num_of_even_digited_input(array2, sizearr2) << endl;
    cout << "Count of even digited numbers in array3[] : " << get_num_of_even_digited_input(array3, array3.size) << endl; // HOW IS THIS FUNCTION PROTOTYPE GOING TO LOOK LIKE??
}

是的:

template<auto size>
void foo(int (&arr)[size]);

STL 这样做的方法是传递开始/结束迭代器:

template<typename Iter>
void foo(Iter begin, Iter end);

或者在 C++20 中使用std::span

有没有办法,我们可以通过引用传递 arrays 而不传递它的大小?

传递数组大小不是强制性的。 您只能传递数组,但必须确保不会越界操作。 该尺寸可帮助 function 的用户做到这一点(即以安全方式操作)。

或者,更好的是,使用std::vector代替。 您不必再担心大小,因为该信息来自输入向量本身。

function 原型会是什么样子?

当你使用vector时,原型可以是:

int get_num_of_even_digited_input(std::vector<int>& param)

如前所述,您不再需要传递大小,因为您始终可以使用param.size()找出有多少项目。

此外,如果您不更改param内部的参数,请改用const std::vector<int>& param

您可以使参数按引用传递,则无需传递数组的大小。 (当通过引用传递时,原始数组不会衰减为指针并且其大小被保留。)并且还制作了 function 模板,然后它可以与原始 arrays 和std::array一起使用。

template <typename T>
int get_num_of_even_digited_input(const T& arr)
{
    int count_of_evendigited_num = 0;

    // I use range-based for loop here
    // you can get the size of the array as std::size(arr) if necessary
    // it works with raw arrays and std::array too
    for (auto e : arr)
    {
        if(get_number_of_digits(e) % 2 == 0)
        {
            count_of_evendigited_num++;
        }
    }

    return count_of_evendigited_num;
}

在 C++ 中,数组大小是一个编译时概念,因为数组的大小是其类型的一部分,所以说您有一个 function 在运行时接受不同大小的 ZA3CBC3F9D0CE2F2C1554E1B671D7 并没有任何意义。

您可以编写一个 function template ,该模板将接受 arrays 并将扩展为接受给定数组大小的引用/指针的特定版本。 这很少是一个好主意,因为如果您为 arrays 设置 10 个不同的大小,那么您编译的代码最终会得到相同 function 的 10 个不同副本。 template奇怪的语法使您摆脱的只是手工编写这些副本。

通常所做的是编写一个 function ,它接受指向第一个元素的指针和运行时元素的数量,然后是一个小的模板包装器,它只会扩展调用,以便不需要显式传递大小:

int sum(const int *x, int n) {
    int s = 0;
    for (int i=0; i<n; i++) {
        s += x[i];
    }
    return s;
}

template<int N>
int sum(const int (&x)[N]) {
    return sum(x, N);
}

int foo() {
    int x[] = {1,2,3,4};
    return sum(x);
}

在上面的代码中,实际上计算元素总和的 function 只有一个副本, template技巧仅用于替换

sum(x);

sum(&x[0], 4);

自动地。

Even more frequently C arrays are replaced with std::vector for dynamic size containers and std::array for static size containers (the main advantage of std::array is that is a "normal" type that is handled like other C++ types and例如,可以按值传递,也可以从 function 返回,这不适用于 C 数组)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM