结构体完美解决二维数组返回值问题

来源:互联网 发布:gopro编辑 windows 编辑:程序博客网 时间:2024/05/16 20:30

今天遇到一个很恼人的问题,C的返回值怎么返回一个矩阵呢,我们都知道矩阵是用二维数组

存储的。于是就涉及到返回值的问题了。
返回值两个作用
1.程序返回到调用语句处继续进行
2.回送一个数值
函数停止运行并返回到调用程序有两个方法:
1.执行到最后一个语句
2.遇到return,也就是用到了返回值的第一个作用
非空函数都会返回一个值,根据文献上说,根据作用分为三种:
1.返回一个计算值
2.返回信息值,-1,0,1等,例如write()成功返回写入的字节数,失败为-1
3.没明确返回值,就是一个return
上面的三种情况只有第一种符合我要找的问题,就是返回一个计算结果,可是我的计算结果

不是一个数啊,是一个矩阵呢!怎么返回一个矩阵呢?
后来,我想到了,地址在计算机中存储,就是以数值的形式。那么我返回结果矩阵的地址不

就是行了吗?

于是就有了:

int Matrix_Multiply(int A[2][2],int B[2][2]){ int C[2][2]; /*  *  calculate...  */ return C;  }



D:\Program Files\CodeBlocks\cpp\MATRIX_MULTIPLY\main.cpp||In function 'int

Matrix_Multiply(int (*)[2], int (*)[2])':|
D:\Program Files\CodeBlocks\cpp\MATRIX_MULTIPLY\main.cpp|68|error: invalid

conversion from 'int (*)[2]' to 'int'|
D:\Program Files\CodeBlocks\cpp\MATRIX_MULTIPLY\main.cpp|64|warning: address

of local variable 'C' returned|
出错了,返回值是一个地址,所以是int型数据应该没问题,可是编译器说不能把int(*)[2]

赋值给int,我立马想到,地址也有区别。这个int(*)[2]是指向一维数组的指针,没错,C被

隐式转化成指向一维数组的指针,当然不能赋值给指向数的指针。
修改后:

int (* Matrix_Multiply(int A[2][2],int B[2][2]))[2]{ int C[2][2]; /* your code... */ return C;} 



编译器通过!
可是我是矩阵链相乘啊。可是说我的Matrix_Multiply参数应该是一个三维数组A[4][2][2]
也不难,只要将返回值一直保持是指向一维数组的指针就行了。
于是:

int  (*MATRIX_CHAIN_MULTIPLY_INT(int A[5][2][2],int S[][length+1],int i,int j))[2]{    int (*B1)[2],(*B2)[2];    if(i == j)        return A[i];    if(j == i+1)        return Matrix_Multiply(A[i],A[j]);    else    {        B1=(MATRIX_CHAIN_MULTIPLY_INT(A,S,i,S[i][j]));        B2=(MATRIX_CHAIN_MULTIPLY_INT(A,S,S[i][j]+1,j));        return Matrix_Multiply(B1,B2);    }}



可是,当我把int (*Result2)[2]=MATRIX_CHAIN_MULTIPLY_INT(TEST2,s,1,4);我就彻底

傻眼了,因为这是个指针!指针指向了计算结果,如果这个指针指向的地方时stack呢?这个

地方的内容会被回收!回收!!回收!!!
如果是打印出来的话,我们就会看到以下结果:
64 2293272
2293728 1
如果你把printf这语句放前一点,就是这个结果:
64 64
229**** 229*****(忘记了)
也就是说这个回收的比较慢一点,就被我看到了。

如果是debug的话,我们就会看到这个结果:
单步后:
64 64
64 64 (也就是正确结果)
单步后:
64 2293272
2293728 1
也就是说计算结果只存在一条语句的时间,就被销毁了。
我查了下:
1.局部变量、函数存放在栈区,
2.全局变量、静态局部变量存放在数据区
3.动态分配的变量存放在堆区
4.凡是全局变量,static变量都产生在静态区上他们的生存周期为整个程序的生存周期,而

在函数中用到的局部变量都是产生在栈上面的,等到函数调用完成它们也从栈上消失。
注意到第4条,函数MATRIX_CHAIN_MULTIPLY_INT调用完之后stack上的数据就被销毁,所以

我返回一个内存的地址根本就是自己找抽!!!
以上我的方法就是一个渣!!!
只能返回一个矩阵了!
我的函数MATRIX_CHAIN_MULTIPLY_INT应该怎么写返回值呢?
Who can tell me?
Who can help ne?
还是自己靠自己吧,用结构体完美解决!
struct Matrix
{
  int num[N][N];
};
总是绕着一维指针二维指针很麻烦,如果把二维数据包装成一个单位,编码就简单很多很多

了!!
附上源码:
 

/*ouyang's code*/#include <iostream>#include "stdio.h"#include "stdlib.h"#define N 2#define length 4#define MAX 65000using namespace std;struct Matrix{  int num[N][N];};struct Matrix  Matrix_Multiply(struct Matrix *A,struct Matrix *B){    struct Matrix C;    for(int i=0;i<N;i++)        for(int j=0;j<N;j++)        {            C.num[i][j]=0;            for(int k=0;k<N;k++)            {                C.num[i][j]+=A->num[i][k]*B->num[k][j];            }        }    return C;}int s[length+1][length+1];void MATRIX_CHAIN_ORDER(int p[]){    int n=length;    int m[length+1][length+1];    for(int i=1;i<=n;i++)    {        m[i][i]=0;    }    for(int l=2;l<=n;l++)    {        for(int i=1;i<=n-l+1;i++)        {            int j=i+l-1;            m[i][j]=MAX;            for(int k=i;k<=j;k++)            {                int q=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];                if(q<m[i][j])                {                    m[i][j]=q;                    s[i][j]=k;                }            }        }    }}void PRINT_OPTIMAL_PARENS(int s[][length+1],int i,int j){    if (i == j) {     printf("A%d",i); } else {        printf("(");   PRINT_OPTIMAL_PARENS(s,i,s[i][j]);   PRINT_OPTIMAL_PARENS(s,s[i][j]+1,j);        printf (")"); }}struct Matrix  MATRIX_CHAIN_MULTIPLY(struct Matrix TEST[],int S[][length+1],int i,int j){    struct Matrix B1,B2;    if(i == j)        return TEST[i];    if(j == i+1)        return Matrix_Multiply(&TEST[i],&TEST[j]);    else    {        B1=MATRIX_CHAIN_MULTIPLY(TEST,S,i,S[i][j]);        B2=MATRIX_CHAIN_MULTIPLY(TEST,S,S[i][j]+1,j);        return Matrix_Multiply(&B1,&B2);    }}void getNumber(struct Matrix *A){    for(int i=0;i<N;i++)    {        for(int j=0;j<N;j++)        {            printf("%d ",A->num[i][j]);        }        printf("\n");    }    printf("\n");}int main(){    struct Matrix A,B,C,D,Result;    A.num={{1,1},{1,1}};    B.num={{1,1},{1,1}};    C=Matrix_Multiply(&A,&B);    D=Matrix_Multiply(&B,&C);    getNumber(&A);    getNumber(&B);    getNumber(&C);    getNumber(&D);    struct Matrix Test[5]={{},A,B,C,D};    int p[length+1]={2,2,2,2,2};    MATRIX_CHAIN_ORDER(p);    PRINT_OPTIMAL_PARENS(s,1,4);    Result=MATRIX_CHAIN_MULTIPLY(Test,s,1,4);    printf("\n");    getNumber(&Result);    return 0;}/*code end*/