发新话题
打印

一个无法理解的c源程序

题目:输入一个2*3的整数矩阵和一个3*2的整数矩阵,请使用指针数组实现这两个矩阵的相乘。! r8 l# c) Q5 C1 s* \; k
#include<stdio.h>- P+ b8 t( m9 _
main()
- g. B9 @* l+ L: K+ N' y" P{static int a[2][3],b[3][2],result[2][2];
* z/ O% ?0 ]! ^& Hint *p[3];$ ?0 O0 i. h3 m2 f/ @7 a
p[0]=a[0];p[1]=b[0];p[2]=result[0];
1 g! f7 {2 B1 {& qprintf("\n the 1st matrix;\n");
' C& V, U% S% E7 Q* ~for(int i=0;i<2;i++)
0 X  H5 M+ G; `! i- e, U+ C0 j, P{printf("new line:\n");2 h' w% D* ?4 t5 M7 E
for(int j=0;j<3;j++)  [; g! v* h# D" y( f6 v4 d) X
scanf("%d",p[0]+3*i+j);9 I6 P2 l$ Z7 f1 e) G0 b2 f; V9 L0 M
}
# P/ R9 i) W/ i$ s. g5 Rprintf("\n the 2st matrix;\n");6 C+ q: b- J3 x$ a/ _/ P1 u( w
for(int i=0;i<3;i++)
1 n7 L8 X- h7 y1 m  {{printf("new line:\n");
; L7 M4 ~1 s0 t' Ifor(int j=0;j<2;j++)
/ ?' C( b% A0 V  lscanf("%d",p[1]+2*i+j);! e" }7 i" O% `, H4 e- b6 h
}
/ b4 v% {) M" c; A$ R# ^/以下的开始相乘/
# e- S  W6 ?7 C; {& H) Bfor(int i=0;i<2;i++)# g8 F: z9 A( K, f# r: \: _
for(int j=0;j<3;j++)
, e. |8 y3 U3 @- L  b. u% u6 Hfor(int k=0;k<2;k++). X. V' m/ D' L* b" U0 D
*(p[2]+2*i+k)+=*(p[0]=3*i+j)*(*(p[1]+2*j+k));
5 ^1 A* @! z2 ], |for(int i=0;i<2;i++)
3 I' u4 o) [5 H9 w% Y{printf("\n");
9 K7 S- n  l6 Tfor(int j=0;j<2;j++)+ F" q- T/ [# I9 G6 Y2 W$ t6 _
printf("%d,",*(p[2]+2*i+j));
) ?: L* H4 ~0 L; }% Y) D}
. Y& z/ I& e7 z/ _7 J. S1 r2 g# @7 r}; m" V3 }! @3 s! t" r% h3 V
完毕。就是相乘的那一段不明白,请指教( o# c; c/ W9 Q1 \6 e
      

TOP

这段程序并不复杂啊,我不知道你具体是哪里不明白的。这里试着解释一下吧。) H# ~. i  ^' ^+ h$ P

9 ~( L6 g* P+ x; F  A0 }& `4 y8 B首先,你得知道两个矩阵相乘是怎么一回事。# i" R' T) B) C* \2 D1 m9 @
设A为{a[l][j]},B为{b[j][k]},A*B的结果为C,则C{c[l][k]}就是:3 l+ X% Y0 k& C, R
1)   c[m][n]=a[m][x]*b[x][n]  (1<=m<=l, 1<=n<=k, 1<=x<=j). _( L$ M) R" s2 _8 ]5 H5 \) l/ ~
(如果搞不清楚,就请写两个矩阵,然后试着乘乘,慢慢弄清楚吧。^_^)" k" q+ ~7 m& @! H. O: ?! [

/ ~, Z9 N/ K' D: h  ?如果弄清楚了以上所说,自然就会想到要实现两个矩阵的相乘,最直接的方法就是用三层循环。现在,我们看看源程序,它的方法正是这样的:4 ?# S, F5 ^8 b& |
for(int i=0;i<2;i++)
3 d# k( |0 O  v6 x$ F6 N$ r    for(int j=0;j<3;j++)
1 t0 X5 E: g3 p, Q         for(int k=0;k<2;k++) ; O$ z4 K# L# p8 Z, T! v4 l/ \' b0 z
            *(p[2]+2*i+k)+=*(p[0]+3*i+j)*(*(p[1]+2*j+k));
$ ]* i+ `2 y) V0 g其中,i,k分别为结果(也就是p[2])的行和列下标变量,i,j为第一个矩阵(p[0],也就是a[])的行列下标变量,j,k为第二个矩阵(p[1],也就是b[])的行列下标变量。而最后的那个式子正是1)的具体实现。# L  r0 F, L! R9 ?7 Z
) e: H% b9 y- g$ P5 y; `
一些细节:
1 f& O/ s: j3 i  I# F9 L1、对于一个矩阵A(m*n),让p指向a[0][0],则p+m*i+j指向a[l][j],上面的程序正是用这样的方法来访问矩阵中的数据的。5 n7 g- p% ~4 n5 f  W: h
2、*p表示取得p所对应的单元的内容,所以上面的程序中的“*”,有些是乘号,有些是取单元内容的运算符,不要搞混了。      

TOP

*(p[2]+2*i+k)+=*(p[0]+3*i+j)*(*(p[1]+2*j+k));
7 c7 T2 ^5 g9 f  f2 D0 r' n  {9 L) C& @error, please modify to:
, ?' A! Q3 [: l. y: H) |/ i( c  o( F*(p[2]+2*i+k)+=(*p[0]+3*i+j)*(*(p[1]+2*j+k)); - I: ], g" A* s3 G4 a

' {( b# h4 I. Z4 C3 c我主页也有一篇我99年写的三角矩阵的算法,C++实现,看起来更直观。:)      
-----------------------------------------
http://www.darkspy.org/blog

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

TOP

不对,原程序对,不用改      

TOP

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

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

TOP

为什么呀?% X5 c8 ?& s) N+ w
- M/ y6 ]: M2 X4 F* V; K' }$ x
还有一个问题
2 G( @  M3 n7 E3 y0 {7 J还是求矩阵的问题! F+ g, T4 X1 G- f. {1 [" ]
for(i=0;i<m;i++)
5 A' h9 \* w4 f* H$ [. R for(j=0;j<n;j++)# \2 l8 M) z( h; l% a/ z
{/ o) ?  m# R# x! d9 E. b" C# c2 Q
z[j]=0;# ~% B! X3 j! K1 \- O* P
for(l=0;l<k;l++)1 ~1 w% D8 a9 m0 k9 ?0 b/ j/ Z
  z[j]+=x[l]*y{l][j];
& S6 V5 x6 q5 C% |3 i }
" g; J" h8 h, G  I# n- q5 q- u三个循环的位置可以调换吗?; J* O# \! q+ q* e6 [1 P2 q
8 d8 `$ p" r0 T" F2 v
为什么要加z[j]=0;
6 v, e: {5 I3 y% U1 ?& l去掉这句,然后i,j,l都从1开始,这样可以吗?2 n' `5 h* f1 t2 J; z& w- I1 \
. l3 m2 E) H+ B- B9 Q2 [% `
      

TOP

发新话题