牛骨文教育服务平台(让学习变的简单)
博文笔记

关于C++二维数组的返回问题

创建时间:2014-11-27 投稿人: 浏览次数:2489

今天帮同学调试一个程序,实验里面要求需要用函数返回一个二元数组,原本十分钟可以解决的问题花掉了很多时间。

实验要求是这样的:

1、矩阵(一)
编写C++程序完成以下功能:
(1)假定矩阵大小为4×5(整型数组表示);
(2)定义矩阵初始化函数,可以从cin中输入矩阵元素;
(3)定义矩阵输出函数,将矩阵格式化输出到cout;
(4)定义矩阵相加的函数,实现两个矩阵相加的功能,结果保存在另一个矩阵中;
(5)定义矩阵相减的函数,实现两个矩阵相减的功能,结果保存在另一个矩阵中;
(6)定义三个矩阵:A1、A2、A3;
(7)初始化A1、A2;
(8)计算并输出:A3 = A1加A2,A3 = A1减A2。


按照要求,addMatrix()、subMatrix()函数的输入为两个二维数组,同时返回一个二维数组

开始时尝试各种返回方式

int[][] addMatrix(int A1[][5], int A2[][5]))
{
    int A[4][5];
    for (int i=0;i<4;i++)
        for (int j=0;j<5;j++)
            A[i][j]=A1[i][j]+A2[i][j];
    return A;
}

编译时报错

error: expected unqualified-id before "[" token

然后尝试了下面的写法

int*[] addMatrix(int A1[][5], int A2[][5]))
{
    int A[4][5];
    for (int i=0;i<4;i++)
        for (int j=0;j<5;j++)
            A[i][j]=A1[i][j]+A2[i][j];
    return A;
}

编译时报错

error: expected initializer before "[" token

最后采用了下面一种写法

int** addMatrix(int A1[][5],int A2[][5])
{
    int A[4][5];
    for (int i=0;i<4;i++)
        for (int j=0;j<5;j++)
            A[i][j]=A1[i][j]+A2[i][j];
    return (int**)A;
}

这一下可以编译通过,然后编写了下面一段测试程序:

#include <stdio.h>
#include <iostream>
using namespace std;

int** addMatrix(int A1[][5],int A2[][5])
{
    int A[4][5];
    for (int i=0;i<4;i++)
        for (int j=0;j<5;j++)
            A[i][j]=A1[i][j]+A2[i][j];
    return (int**)A;
}
int main()
{
    int A1[][5]={{1,2,3,4,5},
                {1,2,3,4,5},
                {1,2,3,4,5},
                {1,2,3,4,5}};
    int A2[][5]={{1,2,3,4,5},
                {1,2,3,4,5},
                {1,2,3,4,5},
                {1,2,3,4,5}};
    int **A=addMatrix(A1,A2);
    for (int i=0;i<4;i++)
    {
        for (int j=0;j<5;j++)
            cout<<A[i][j]<<" ";
        cout<<endl;
    }
    return 0;
}

虽然可以编译通过,但是在执行到cout语句时程序就会崩溃,在用visual调试的时候发现返回的地址并不能被访问,原理暂时不清楚,后面又百度到了下面的这种写法

#include <stdio.h>
#include <iostream>
using namespace std;

int (*addMatrix(int A1[][5],int A2[][5]))[5]
{
    int A[4][5];
    for (int i=0;i<4;i++)
        for (int j=0;j<5;j++)
        {
            A[i][j]=A1[i][j]+A2[i][j];
            printf("%d %d %d 
",A[i][j],A1[i][j],A2[i][j]);
        }
    return A;
}

int main()
{
    int A1[][5]={{1,2,3,4,5},
                {1,2,3,4,5},
                {1,2,3,4,5},
                {1,2,3,4,5}};
    int A2[][5]={{1,2,3,4,5},
                {1,2,3,4,5},
                {1,2,3,4,5},
                {1,2,3,4,5}};
    int (*A)[5]=addMatrix(A1,A2);
    for (int i=0;i<4;i++)
    {
        for (int j=0;j<5;j++)
            cout<<A[i][j]<<" ";
        cout<<endl;
    }
    return 0;
}

编译没有问题,运行也不会崩溃,但是结果全部是错的


通过调试可以看到,返回的数组类型为int[5]*,并不是我们需要的int*[5]。同时,通过汇编调试我们还可以看到,当程序在执行输出操作的时候,A地址所指向的数据会被改变,这不难理解,由于A地址的内存空间是我们在函数里面申请的,也就是说A数组属于局部变量,局部变量的数据存储在堆栈里面,当函数执行完毕后局部变量所占的内存就被释放掉,被释放并不意味着该地址所指向的空间的值会被清零,C++不会干这么没效率的事,释放只是告诉系统环境这一块区域可以再分配,这也就是为什么我们看到开始部分输出的数据是正确的,但是随着函数的重复调用,A地址指向的空间数据被新执行函数里面申请的局部变量所覆盖,所以得到的数据也变成了一些随机值。

综上所述,如果一定要通过函数来修改二维数组的话,可以通过参数的方式传入,或者通过结构体的形式返回,直接返回二维数组麻烦而且意义不大。

声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。