发新话题
打印

一个无法理解的c源程序

题目:输入一个2*3的整数矩阵和一个3*2的整数矩阵,请使用指针数组实现这两个矩阵的相乘。
) D8 }% Z+ `) H5 v& K3 p#include<stdio.h>) I. P' m' @' }' |
main()" ^% h- s1 i  v
{static int a[2][3],b[3][2],result[2][2];) \/ m" j1 V' |. x' c8 h
int *p[3];
4 W2 j, K! A( `$ b) {6 {p[0]=a[0];p[1]=b[0];p[2]=result[0];" f5 U% Z, S9 y
printf("\n the 1st matrix;\n");
6 d( }" w' V2 o2 f3 i& V; vfor(int i=0;i<2;i++)
( k" t8 D: t" F{printf("new line:\n");
3 n8 E' I% t1 O6 [8 s" _; ^for(int j=0;j<3;j++). u, S; t, b5 P8 e4 p
scanf("%d",p[0]+3*i+j);& S% m4 o6 |& X4 X& B& |
}3 C4 U$ T0 B& K; ]) l3 K2 ?0 e
printf("\n the 2st matrix;\n");/ {  |7 t; ^  l4 L5 w
for(int i=0;i<3;i++)/ f4 Y% m" u# D$ P7 Q
{printf("new line:\n");& W8 @- B: T4 ^4 I
for(int j=0;j<2;j++)
+ b- C# o: E  P  H; Q! _scanf("%d",p[1]+2*i+j);8 `5 s5 N" x$ ?1 |
}# X8 P. _5 O  f3 n  B0 I: c
/以下的开始相乘/
9 c0 f0 D% Z" {. O6 V8 K1 Ffor(int i=0;i<2;i++)8 F' R" E( N% u. O8 l
for(int j=0;j<3;j++)  t2 L5 [  x! m& F, J  L
for(int k=0;k<2;k++)
( {: [/ [9 f! B*(p[2]+2*i+k)+=*(p[0]=3*i+j)*(*(p[1]+2*j+k));
8 a& D. @7 a8 z7 \6 Y8 V- yfor(int i=0;i<2;i++)
9 b7 a/ b9 t" p2 l( Z' b{printf("\n");4 Y  C, [# q- k- ?9 j  I1 v
for(int j=0;j<2;j++)
# z  p: F( O0 N0 I& Rprintf("%d,",*(p[2]+2*i+j));
9 E7 f9 @) x' n7 ~, q0 u}
% \9 }, `+ C+ t& v+ M4 g}
$ z4 x6 I7 ], y5 {8 K% f完毕。就是相乘的那一段不明白,请指教( a# x) d, V; [8 }0 M4 Z
      

TOP

这段程序并不复杂啊,我不知道你具体是哪里不明白的。这里试着解释一下吧。
; |; J, Q8 w! {  L- S
4 L% ]: c4 m# F7 L* w首先,你得知道两个矩阵相乘是怎么一回事。. L/ o) [) l8 j. N
设A为{a[l][j]},B为{b[j][k]},A*B的结果为C,则C{c[l][k]}就是:
3 l* N6 Q( I' j. G) Y2 v+ N& U6 e1)   c[m][n]=a[m][x]*b[x][n]  (1<=m<=l, 1<=n<=k, 1<=x<=j)
2 J* s9 x5 A# w8 y5 p  }(如果搞不清楚,就请写两个矩阵,然后试着乘乘,慢慢弄清楚吧。^_^)
! c* c2 i% m5 H( w$ q
! O; j$ W4 p, i2 @如果弄清楚了以上所说,自然就会想到要实现两个矩阵的相乘,最直接的方法就是用三层循环。现在,我们看看源程序,它的方法正是这样的:7 x; Q7 H! t+ C0 l* q  O
for(int i=0;i<2;i++) 9 s, U1 H$ p" P; K
    for(int j=0;j<3;j++) ' g+ `( h8 G% L6 k% A6 ?
         for(int k=0;k<2;k++) 5 P) N& f; h- O- x, q: l
            *(p[2]+2*i+k)+=*(p[0]+3*i+j)*(*(p[1]+2*j+k)); ( S* l6 E/ ~8 N% W3 n
其中,i,k分别为结果(也就是p[2])的行和列下标变量,i,j为第一个矩阵(p[0],也就是a[])的行列下标变量,j,k为第二个矩阵(p[1],也就是b[])的行列下标变量。而最后的那个式子正是1)的具体实现。/ _. s4 Q8 {, S4 P" o! `

9 H9 P' j; k4 D0 l* e一些细节:
( K. p% @& T0 j8 k6 D" i1 y& N0 Q8 q1、对于一个矩阵A(m*n),让p指向a[0][0],则p+m*i+j指向a[l][j],上面的程序正是用这样的方法来访问矩阵中的数据的。; f* N! W: ]8 M  V5 t+ o
2、*p表示取得p所对应的单元的内容,所以上面的程序中的“*”,有些是乘号,有些是取单元内容的运算符,不要搞混了。      

TOP

*(p[2]+2*i+k)+=*(p[0]+3*i+j)*(*(p[1]+2*j+k));
+ x9 u) G& b3 `, gerror, please modify to:
# j& ^2 a, f; Y, I6 v. j*(p[2]+2*i+k)+=(*p[0]+3*i+j)*(*(p[1]+2*j+k));
& G$ X9 q3 ^% n$ B
( F0 w, `9 ]$ k- C! j" _我主页也有一篇我99年写的三角矩阵的算法,C++实现,看起来更直观。:)      
-----------------------------------------
http://www.darkspy.org/blog

自大的人把宗教当迷信,无知的人把迷信当宗教

TOP

不对,原程序对,不用改      

TOP

gcc 2.95.3 can not compile      
-----------------------------------------
http://www.darkspy.org/blog

自大的人把宗教当迷信,无知的人把迷信当宗教

TOP

为什么呀?+ L/ `9 [9 y  H, Z: H

+ d4 r4 J5 h, X" z0 ?) Q还有一个问题
7 z  n9 ~. z# N) h& h还是求矩阵的问题
7 y$ L/ K$ t, H6 |9 G6 sfor(i=0;i<m;i++); b7 z' p- c0 X: {- O9 j" r3 }
for(j=0;j<n;j++)1 [# w! N+ Y* c; M
{2 D1 T4 d& G. ]* L2 t& c
z[j]=0;% ]$ ~. }, Y0 L" ^
for(l=0;l<k;l++)
! f  r* v. V2 i, Z- z/ }% U% r  z[j]+=x[l]*y{l][j];0 V3 K- V! q3 L: {# f5 g
}+ @" L2 o& G- t+ k5 r& n. @+ u
三个循环的位置可以调换吗?
# l, K; e( z3 l3 k4 P* r0 C0 e; w- c+ j
为什么要加z[j]=0;% u9 q( ^% g  u" T
去掉这句,然后i,j,l都从1开始,这样可以吗?
: x2 Z% |" ^6 \. U: Y  J' n1 @- T  }  i/ C
      

TOP

发新话题