今天遇到一个很恼人的问题,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 65000
using 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*/