【问题标题】:How to pass and return 2d array to a function如何将二维数组传递和返回给函数
【发布时间】:2018-06-23 00:44:48
【问题描述】:

我正在尝试在不同的函数中更改二维数组值,以便满足我的需要。 对于下面代码中的示例,我试图通过将 Matrix 更改为“1”来将 Matrix 更改为自反。

我在返回新数组并将其替换为主程序中的旧数组时遇到问题,以便我可以再次使用它。

int reflexive(int m, int n, int matrix[100][100])
{

 for(int i = 1;i <= m; i++)
  {
    for(int j = 1; j <= n; j++)
    {
        if(i == j)
        {
            if(matrix[i][j] != 1)
                matrix[i][j] = 1;
        }
 return matrix;
     }
   }
 }
int main()
{
    int  matrix[100][100];
    int m , n;
    for(int i = 1;i <= m; i++)
    {
        for(int j = 1; j <= n; j++)
        {
            cin>>matrix[i][j];
        }
    }

    matrix[m][n] = reflexive(m,n,matrix);
 return 0;
}

我想修复此代码,以便它可以将完整的新二维数组返回到主程序。

【问题讨论】:

  • 你可以定义一个struct(保存数组)和/或使用std::vector
  • 打开你的 C++ 书中解释如何使用std::array 的章节,并学习如何使用这个类。与本机数组几乎相同的语义,但具有类似对象的语义,避免了这里的所有陷阱。尽管按值返回大型数组效率有点低,但这是稍后要处理的事情。出于学习 C++ 的目的,这很好。
  • 没有新数组,函数正在修改你传递的数组。
  • ** UnholySheep** 你能告诉我如何使用 std::vector 吗?
  • 使用 Boost 矩阵或自己创建一个矩阵类。您可以使用std::vector 提供底层存储。

标签: c++ arrays pointers matrix return


【解决方案1】:

在您的函数reflexive 中,return 语句位于循环内。这导致函数在到达 return 语句时立即终止。如果您正确格式化您的代码,您将能够轻松地看到这种行为。

进一步注意,数组中的第一个元素的索引为 0,最后一个元素的索引为数组的大小 -1。这是因为数组索引是元素“偏移量”。这意味着

a[i]

*(a + i)

访问相同的数组元素。

for(int i = 1;i <= m; i++)      // <--- should be  for(int i=0; i<m; i++)
{
    for(int j = 1; j <= n; j++) // <--- should be for(int j=0; j<n; j++)
    {
        if(i == j)
        {
            if(matrix[i][j] != 1)
                matrix[i][j] = 1;
        }
        return matrix;          // <--- here the function is terminated
    }
}

数组通过指针传递给函数,而不是通过值传递。这意味着如果函数的形参是一个数组,那么并非所有实参的值都被复制到该数组中。只有一个指向函数参数值的指针。
因此,您的情况不需要任何返回值。

下面的代码应该做你想做的事:

int reflexive(int m, int n, int matrix[100][100])
{
    for(int i=0; i<m; i++)
    {
        for(int j=0; j<n; j++)
        {
            if(i == j)
            {
                if(matrix[i][j] != 1)
                    matrix[i][j] = 1; // <----- write to the data by pointer
            }
        }
    }
}

int main()
{
    int  matrix[100][100];
    ......
    reflexive(m,n,matrix);
    ......
}

【讨论】:

  • for(int i = 1;i &lt;= m; i++) 可能不是他想要的。
  • @super 谢谢。我很马虎
【解决方案2】:

使用vector&lt;vector&lt;int&gt;&gt;并通过引用传递

【讨论】:

    【解决方案3】:

    在这里使用数组既乏味又容易出错。因此:

    #include <vector>
    
    std::vector<std::vector<int> > reflexive(std::vector<std::vector<int> > matrix)
    {
        for(int i = 0; i < matrix.size; i++){
            for(int j = 0; j < matrix[i].size; j++){
    ....
    
    int main()
    {
        std::vector<std::vector<int> > matrix(100, std::vector<int>(100));
        int m , n; //<<whereever they come from I guess? Saw no cin in your code. Have no set value right now.
        for(int i = 0; i < m; i++)
        {
            for(int j =0; j < n; j++)
            {
                cin>>matrix[i][j];
            }
        }
    }
    

    #include<array>
    
    ...
    
    std::array<std::array<int, 100>, 100> matrix;
    

    std::array 是固定大小的,std::vector 是动态的。同时了解std::list

    无论如何,您应该找到一个讨论它们的基本教程并阅读所有内容。重要标准。

    也就是说,特别是如果您想使用动态大小的数组,您无法保证每个子数组的大小都相同(“jagged 2d 数组),这在一个小程序,但在大局中应避免使用确保此属性的类。

    对于矩阵,一个简单的选择是使用处理矩阵的库,例如 Eigen。

    编辑:

    如果在某些时候你需要上面的代码在 const-correct 中:

    std::vector<std::vector<int> > reflexive(const std::vector<std::vector<int> >& input)
    {
        std::vector<std::vector<int> > output = input;
        ....
        return output;
    }
    

    (如果允许修改原始矩阵,则将其设为无效)

    【讨论】:

    • int **matrix 不是传递二维数组的方法,即使在 C 中也是如此。如果调用者试图将二维数组传递给这样的函数,代码将无法编译。
    • @Peter 的意思是我的回答集中在vector,因此删除了有关原始数组的部分。
    猜你喜欢
    • 2020-11-01
    相关资源
    最近更新 更多