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

来源:互联网 发布:excel2013无法粘贴数据 编辑:程序博客网 时间:2024/05/16 09:16

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

实验要求是这样的:

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 \n",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地址指向的空间数据被新执行函数里面申请的局部变量所覆盖,所以得到的数据也变成了一些随机值。

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

0 1
原创粉丝点击