<span style='color:blue'>老师给了一个关于矩阵相乘的aufgabe,本来这个东西并不很难,可是里面牵扯到了指针我就犯傻了,我是初学者,希望能有人指点一下该怎么做,明天就要交了啦。多谢了!</span><br /><br />Aufgabe 3a)<br />===========<br />Das Produkt einer n1xn2 Matrix A und einer n2xn3 Matrix B ist eine n1xn3 Matrix<br />C mit den Komponenten<br />c[j]=a[0]*b[0][j]+a[1]*b[1][j]+...+a[n2-1]*b[n2-1][j]<br /><br />Es soll eine Funktion matmul geschrieben werden, mit der man beliebige Matrizen<br />(zweidimensionale double-Felder) multiplizieren kann, wobei nur vorausgesetzt<br />wird, dass die Spaltenzahl des ersten Feldes gleich der Zeilenzahl des zweiten<br />ist.<br /><br />Eine Funktion, die eine 3x2 Matrix A mit einer 2x4 Matrix B multipliziert, was<br />eine 3x4 Matrix C ergibt, koennte so definiert werden:<br />void matmul(double A[][2],double B[][4],double C[][4]) {...}<br />Da hier die erste Dimension der Felder A, B und C nicht in den Datentyp der<br />formalen Parameter eingeht, kann man diese Funktion leicht verallgemeinern zu<br />einer Funktion, die eine n1x2 Matrix A mit einer 2x4 Matrix B multipliziert,<br />was eine n1x4 Matrix C ergibt:<br />void matmul(double A[][2],double B[][4],double C[][4],int n1) {...}<br />Damit ist noch nicht viel gewonnen. Die Funktion ist immer noch viel zu <br />speziell. Z.B. kann man damit keine 3x3 mit einer 3x3 Matrix multiplizieren.<br /><br />Der Aufruf einer brauchbaren Funktion zur Multiplikation einer beliebigen<br />n1xn2 Matrix A mit einer n2xn3 Matrix B sollte so aussehen:<br />matmul(A,B,C,n1,n2,n3);<br />Hierzu muss man die Funktion wie folgt definieren:<br /><br />void matmul(void *A,void *B,void *C,int n1,int n2,int n3)<br />{<br />double *a=(double*)A,*b=(double*)B,*c=(double*)C;<br /> :<br /> :<br />}<br /><br />An einen Pointer auf void kann man jeden beliebigen (nicht const und nicht<br />volatile) Pointer-Typ ohne cast zuweisen. Deshalb kann man die Funktion mit<br />beliebeigen Feld-Typen als aktuellen Parametern fuer die void*-Parameter<br />aufgerufen werden. Die void*-Parameter erhalten beim Aufruf der Funktion als<br />Werte die Anfangs-Adressen der Speicherbereiche fuer die Felder A, B und C.<br />In der Funktion werden diese Adressen zunaechst ueber einen cast umgewandelt<br />in Pointer auf double. Damit kann man a, b und c in der Funktion verwenden wie<br />eindimensionale Felder der Speicherbereiche der zweidimensionalen Felder A, B<br />und C. Ein doppelt indizierter Zugriff muss dann gemaess der Speicherabbildung<br />in einen einfach indizierten Zugriff umgewandelt werden.<br /><br />Erstellen Sie die Funktion matmul und eine main-Funktion zum Test von matmul.<br /><br />Hier noch einige Spezialfaelle des Matrizen-Produktes:<br /><br />1) Inneres Produkt (Skalarprodukt) zweier Vektoren:<br /> 1xn2 Matrix mal n2x1 Matrix ergibt 1x1 Matrix, d.h. Skalar.<br /> double v1[1][3]={1,2,3},v2[3][1]={4,5,6},v3[1][1];<br /> matmul(v1,v2,v3,1,3,1);<br /> => v3 : 32<br /><br />2) Aeusseres Produkt (Tensorprodukt) zweier Vektoren:<br /> n1x1 Matrix mal 1xn3 Matrix ergibt n1xn3 Matrix.<br /> double v1[3][1]={1,2,3},v2[1][3]={4,5,6},v3[3][3];<br /> matmul(v1,v2,v3,3,1,3);<br /> 4 5 6<br /> => v3 : 8 10 12 <br /> 12 15 18<br /><br />3) Produkt eines Skalars mit einem Vektor:<br /> 1x1 Matrix mal 1xn3 Matrix ergibt 1xn3 Matrix.<br /> double v1[1][1]={2},v2[1][3]={1,2,3},v3[1][3];<br /> matmul(v1,v2,v3,1,1,3);<br /> => v3 : 2 4 6<br /><br />4) Produkt eines Vektors mit einem Skalar:<br /> n1x1 Matrix mal 1x1 Matrix ergibt n1x1 Matrix.<br /> double v1[3][1]={1,2,3},v2[1][1]={2},v3[3][1];<br /> matmul(v1,v2,v3,3,1,1);<br /> 2<br /> => v3 : 4<br /> 6<br /><br />5) Produkt eines Skalars mit einem Skalar:<br /> 1x1 Matrix mal 1x1 Matrix ergibt 1x1 Matrix.<br /> double v1[1][1]={2},v2[1][1]={3},v3[1][1];<br /> matmul(v1,v2,v3,1,1,1);<br /> => v3 : 6<br /><br />Aufgabe 3b)<br />===========<br />Schreiben Sie eine Funktion <br />void safematmul(void *A,void *B,void *C,int n1,int n2,int n3) {...}<br />Diese soll eine sichere Version der matmul-Funktion von aufg01 sein. "Sicher"<br />soll dabei bedeuten, dass die Funktion auch dann noch richtig arbeitet, wenn<br />einer der beiden Faktoren gleichzeitig als Ergebnis angegeben wird. D.h. auch<br />die Aufrufe<br />matmul(a,b,a,n1,n2,n3);<br />matmul(a,b,b,n1,n2,n3);<br />matmul(a,a,a,n1,n2,n3);<br />sollen richtige Ergebnisse liefern.<br />Hinweis: Sie muessen fuer das Ergebnis (Produktmatrix) zunaechst mit new Spei-<br />cherplatz bereitstellen. In diesen Hilfsspeicher wird das Ergebnis geschrieben.<br />Erst ganz zum Schluss der Rechnung wird das Ergebnis dann in den Speicherbe-<br />reich der eigentlichen Ergebnisvariablen kopiert. Hierzu koennen Sie memcpy von<br />aufg02 verwenden.<br />Vergessen Sie nicht, den mit new angeforderten Speicherbereich am Ende der <br />Funktion mit delete wieder freizugeben!<br />Testen Sie Ihr Programm. |