【问题标题】:Why is my array being passed with an incorrect size? [duplicate]为什么我的数组以不正确的大小传递? [复制]
【发布时间】:2020-09-06 04:01:03
【问题描述】:

我刚刚开始学习 C++,并且正在玩弄函数。我正在尝试将整数数组作为参数传递,并让函数打印数组的每个元素。然而,我的问题是我有一个初始化为 10 的数组,但是当我将它传递给函数时,它只读取它的大小为 2。任何帮助将不胜感激!你可以在下面找到我的程序。

#include <iostream>
#include <cmath>

using namespace std;

void Max(int Arr[])
{
    for (int i=0; i<sizeof(Arr)/sizeof(Arr[0]); i++)
    {
        cout<< Arr[i]<<endl;
    }
}


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

    Max(Arr);

    return 0;
} 

提前感谢大家的帮助!

【问题讨论】:

  • 是的,但是现在我在使用 std::vector Arr={1,2,3,4,5,6,7,8,9,10}; 时收到错误消息而不是我已经拥有的。它说“未定义模板'std::__1::vector >'的隐式实例化”
  • Arr 衰减为指针,因此编译器会将其评估为 sizeof(int*)

标签: c++ arrays pass-by-reference implicit-conversion pass-by-value


【解决方案1】:

void Max(int Arr[]) 等于 void Max(int* Arr)
在函数Max(int Arr[]):
sizeof(Arr)/sizeof(Arr[0]) = sizeof(int*)/sizeof(int)
在 x64 上等于 2,在 x86 上等于 1

更正您的代码:
---------------------------------

    #include <iostream>
    #include <cmath>

    using namespace std;

    void Max(int Arr[], int len)
    {
        for (int i=0; i<len; i++)
        {
            cout<< Arr[i]<<endl;
        }
    }


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

        Max(Arr, sizeof(Arr)/sizeof(Arr[0]));

        return 0;
    }

【讨论】:

    【解决方案2】:

    当数组按值传递时,它会隐式转换为指向其第一个元素的指针。

    另一方面,声明为具有数组类型的函数参数由编译器调整为指向数组元素类型的指针。

    例如这些函数声明

    void Max(int Arr[]);
    void Max(int Arr[1])
    void Max(int Arr[10])
    void Max(int Arr[100]);
    

    声明相同的函数并由编译器调整为声明

    void Max( int *Arr );
    

    因此在函数中,参数 Arr 是一个指针,而这个表达式

    sizeof(Arr)/sizeof(Arr[0])
    

    等价于

    sizeof( int * ) / sizeof( int )
    

    根据 int * 类型的大小产生 1 或 2。

    当您将数组按值传递给函数时,您还应该显式传递其大小。

    所以函数可以这样定义

    void Max( const int Arr[], size_t n )
    {
        for ( size_t i = 0; i < n; i++ )
        {
            cout << Arr[i] << endl;
        }
    }
    

    并且函数可以像这样调用

    Max(Arr, sizeof( Arr ) / sizeof( *Arr ) );
    

    另一种方法是将函数参数声明为具有引用类型。在这种情况下,最好使用一个模板函数,它可以为至少任意大小的数组调用。

    template <size_t N>
    void Max( const int ( &Arr )[N] )
    {
        for ( size_t i = 0; i < N; i++ )
        {
            cout << Arr[i] << endl;
        }
    }
    

    或者函数可以这样定义

    template <typename T, size_t N>
    void Max( const T ( &Arr )[N] )
    {
        for ( size_t i = 0; i < N; i++ )
        {
            cout << Arr[i] << endl;
        }
    }
    

    这两个函数都可以像这样调用

    Max(Arr);
    

    请注意,您可以使用标头&lt;array&gt; 中声明的标准类模板std::array。例如

    #include <iostream>
    #include <array>
    
    const size_t N = 10;
    
    std::ostream & Max( const std::array<int, N> &a, std::ostream &os = std::cout )
    {
        for ( const auto &item : a )
        {
            os << item << ' ';
        }
    
        return os;
    }
    
    
    int main()
    {
        std::array<int, N> a = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    
        Max( a ) << '\n';
    
        return 0;
    } 
    

    程序输出是

    1 2 3 4 5 6 7 8 9 10 
    

    【讨论】:

    • 使用std::vectorstd::liststd::deque 可能更简单。
    • @JanChristophTerasa 如果您只需要一个数组,则没有任何理由使用例如 std::vector 或 std::list 。
    • 你说得对,std::array 也可以。我只是反对为不同大小的数组提供数百个(模板)函数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-08
    • 2013-04-19
    • 1970-01-01
    • 2011-07-19
    • 1970-01-01
    • 2013-11-13
    相关资源
    最近更新 更多