【问题标题】:Passing unknown Array to Function by reference (C++)通过引用将未知数组传递给函数(C++)
【发布时间】:2014-12-03 20:57:51
【问题描述】:

我花了一个小时试图弄清楚这一点 - 我如何编写这个函数(在代码顶部 - 插入排序),它允许我通过引用传递一个数组。以一种允许我在数组上调用“.size”的方式。它必须是这个分配的数组。

我尝试过不通过引用传递它,在调用 size 之前取消引用数组等。我不断收到错误:(。

这是此代码的最新编译器错误:

insertionSort.cpp:11: 错误:参数“A”包括对未知绑定数组“int []”的引用 insertSort.cpp:在函数‘void insertSort(int (&)[])’中: insertSort.cpp:13: 错误:请求“(int)A”中的成员“size”,它是非类类型“int”

#include <iostream>
//#include <array> - says no such file or directory

using namespace std;


void insertionSort(int (&A)[])                 <-----ERROR HERE
{
    for (int j=1; j <= A->size(); j++)         <-----ERROR HERE
    {
        int key = A[j];
        //now insert A[j] into the sorted sequence a[0...j-1].
        int i = j-1;
        while (i >= 0 && A[i] > key)
        {
            A[i+1] = A[i];
            i -= 1;
        }
        A[i+1] = key;
    }
}

int main()
{
    int Asize = 0;

    cout << "Hello. \nPlease enter a number value for the insertionSort Array size and then hit enter: " << endl;
    cin >> Asize;

    int A[Asize];

    char Atype;

    cout << "There are three ways to order your inserstionSort array; \nb - for best case \nw - for worst case \na - for average case" << endl << "Which type do you desire for this array? \nPlease enter 'b', 'w', or 'a': " << endl;
    cin >> Atype;

    if (Atype == 'b')
    {
        cout << "You have chosen type b." << endl;
    }

    else if (Atype == 'w')
    {
        cout << "You have chosen type w." << endl;
    }

    else if (Atype == 'a')
    {
        cout << "You have chosen type a." << endl;
    }


    cout << "Terminate Program" << endl;
}

【问题讨论】:

  • 这不是 Java。原生数组没有 size() 成员。
  • 如果大小在编译时没有固定,你应该使用std::vector&lt;&gt;
  • 您不能“在阵列上调用 .size”。 C++ 中的内置数组不是类,它们没有方法。您不能“调用”阵列上的任何内容。如果您不知道数组大小,通常是不可能确定数组大小的。
  • @AndreyT 总是可以确定命名数组的大小
  • @Matt McNabb:不是真的。指向未知大小数组的指针或引用(如上例中的那个)可以正确初始化(即使它需要强制转换),然后用于合法访问某个命名数组的内容。然而,它无法让您确定该数组的实际大小。

标签: c++ arrays pass-by-reference variable-length-array


【解决方案1】:

当你这样做时:

std::cin >> Asize;
int A[Asize]; // Not standard

您使用编译器的扩展来使用 VLA(可变长度数组)。 更喜欢使用std::vector 代替(然后你有void insertionSort(std::vector&lt;int&gt; &amp;v))。

如果你不能使用std::vector,你可以使用:

std::unique_ptr<int[]> A(new int [Asize]);

由于大小仅在运行时知道,因此您必须将大小传递给您的函数:

void insertionSort(int* a, std::size_t size)

并拨打insertionSort如下:

insertionSort(A.get(), ASize);

具有已知的编译时间大小的数组,

void insertionSort(int (&A)[42])

是通过引用传递数组的正确方法。

【讨论】:

    【解决方案2】:

    请务必记住,C 数组只是指向数组第一个元素的指针。传递数组很容易,您只需执行以下操作:

    void foo(int *array)
    

    void foo(int array[])
    

    然而,由于它只是一个指向它的基类型的指针,它没有可调用的成员函数,并且它不知道内存结构在它之外是什么样子(即没有长度的概念)。如果您想知道传递的动态数组的长度,那么您需要将长度作为第二个参数传递,大概创建数组的任何东西都应该知道它的长度。

    void foo(int *array, unsigned int length)
    

    或者,您可以避免所有这些并使用在概念上类似于 java 中的 ArrayList 的向量。

    【讨论】:

    • 太棒了。这清除了很多东西。谢谢你。那么不加其他参数就没有办法做到这一点了吗?
    • 查看向量,它们会让你的生活变得更轻松哦。 cplusplus.com/reference/vector/vector
    • 我想记住你,'C 数组只是指针'这句话就像说地球是平的(实际上不是)。
    【解决方案3】:

    数组可以通过引用传递,例如:

    void somefunc(int (&arr)[30]) {}
    

    这将确保您不能为此数组传递任何其他大小(固定大小的数组): 所以,你不能这样做:

    int a[40];
    func(a); // compilation error
    

    不过,任意大小的数组也可以通过引用传递,例如:

    template<typename T, size_t N>
    void somefunc2(T (&arr)[N])
    {
        // N can be used as size, as required, instead of querying size of the array
    }
    

    所以,修正后的功能如下:

    template<typename T, size_t N>
        void insertionSort(T (&A)[N]) // ok, now
        {
            for (size_t j=1; j < N; j++) 
            {
                int key = A[j];
                //now insert A[j] into the sorted sequence a[0...j-1].
                int i = j-1;
                while (i >= 0 && A[i] > key)
                {
                    A[i+1] = A[i];
                    i -= 1;
                }
                A[i+1] = key;
            }
        }
    

    【讨论】:

    • 你可能想要for (size_t j = 0; j &lt; N; j++)
    【解决方案4】:

    尝试使用在 Borland c++ builder 中应该可以工作的 Array.length

    【讨论】:

    • 我只是尝试用 .length 代替,我得到了同样的错误,但是用“length”这个词代替了“size”哈哈
    猜你喜欢
    • 1970-01-01
    • 2011-07-08
    • 2018-01-18
    • 2012-08-05
    • 1970-01-01
    • 2011-12-07
    • 1970-01-01
    • 2017-08-12
    • 2023-03-08
    相关资源
    最近更新 更多