C-Programmierung - kennt sich jemand aus ?

Black Evil

In Memory of Torsten G.
Registriert
5. Juli 2004
Reaktionspunkte
21
Hallo !
Hier gibts doch bestimmt jemanden, der sich mit C auskennt. Momentan bin ich grad dabei, eine Matrizenmultiplikation zu realisieren, hab dabei aber leider ein kleines Problem : Das Unterprogramm ! Da es sich um zweidimensionale Feldern (Arrays) handelt, weiß ich nicht, wie man korrekt die Übergabewerte definiert bzw. Initialisiert. Vieleicht kann ja jemand helfen :

#include <stdio.h>


int matC [5][5];
int k;

//void matmulti ();


//****************************************************Hauptprogramm ANFANG****************************************************************

int main () {

int i =0;
int j =0;



printf("Matrizenmultiplikation\n");
printf("maximale Dimension der Matrizen 5 x 5 \n");



// Einlesen der Matrizenkoordinaten


int matA [5][5]; //Zweidimensionales Feld mit 5 Zeilen und 5 Spalten angelegt

for (i=0;i<5;i++) {

for (j=0; j<5; j++)
{
matA[j] = 0; // Hiermit wird die Matrize komplett auf 0 gesetzt


for(j=0;j<5;j++) {

printf("Zeilenweise Eingabe der Koordinaten Matritze A:");
scanf("%d", &matA[j]);
}
}

}


int matB [5][5]; //Zweidimensionales Feld mit 5 Zeilen und 5 Spalten angelegt


for (i=0;i<5;i++){


for (j=0; j<5; j++)
{
matB[j] = 0; // Hiermit wird die Matrize komplett auf 0 gesetzt


for(j=0;j<5;j++){


printf("Zeilenweise Eingabe der Koordinaten Matritze B:");

scanf("%d", &matB[j]);

}
}

}


//Unterprogramm aufrufen

matmulti (int matA[][5],int matB[][5] ) //Richtig ?? Es müssen doch eigendlich matA und matB als Übergabeparameter gelten


return 0 ;

} // main Ende


//****************************************************Hauptprogramm ENDE****************************************************************




//****************************************************Unterprogramm ANFANG**********************************************************

//Unterprogramm zur Matzizenmultiplikation

void matmulti (int matA[][5],int matB[][5]){

int matC [5][5];
int i;
int j;
int k;


for (i=0; i<5; i++)
{
for (j=0; j<5; j++)
{
matC[j] = 0; // Hiermit wird die Matrize komplett auf 0 gesetzt


for (k=0; k<5; k++)
{

matC[j] += matA[k] * matB[k][j];
}
}
}

// Ausgabe des Ergebnisses


printf(" Ergebnis-Matrix:\n");

for (i=0; i<5; i++)
{

for (j=0; j<5; j++)
{

printf("%d", matC[j]);
}

printf("\n");

}


}

//****************************************************Unterprogramm ENDE**********************************************************
 
Ich kann noch BASIC
Brauch jemand was in BASIC?
Kennt jemand überhaupt noch BASIC?
Gibt es überhäupt noch irgend etwas in BASIC?
Gab es eigentlich BASIC wirklich?
Oder habe nur umsonst seitenweise Stuz gelernt, wo es heutzutage gar nicht mehr gibt? In etwa so wie mit der DDR.
 
Da war mal was mit TurboPASCAL. Da war ich sogar richtig gut drin.
Aber eijentlich is ja eh allet datselbe.


Interressant fand ich die Honks, die InetBrowser für C64 entwickelt haben :eek: :daumen:
 
Basic-Kenntnisse helfen z.B. bei Actionscript.

Und wenn man mal programmieren gelernt hat, dann ist eine neue Sprache eigentlich nur eine kleine Hürde.
 
Danke an Rob für den Link, ich denke aber dass ist C++. Mein Code soll ja in C abgefasst sein. Ich finde es ehrlich gesagt sogar ziemlich schwer.

Aber wo habe ich denn in meinem Code noch Fehler ? Meiner Meinung nach müßte alles, bis auch den Aufruf de Unterprogramms stimmen.
 
Basic-Kenntnisse helfen z.B. bei Actionscript.

Und wenn man mal programmieren gelernt hat, dann ist eine neue Sprache eigentlich nur eine kleine Hürde.

Wer kennt sich in Futurerama oder so aus?
War da nicht mal eine Roboter-Sekte, in deren Tempel über dem Altar stand:

10 SIN
20 GOTO HELL
Ein schlicht weg einfaches, aber einfache geniales Prorgramm.
Wenn es denn so war.
 
muhaha, das sieht ja furchtbar aus

c-kenntnisse sind nicht unbedingt erforderlich, sofern man in der lage ist zu abstrahieren, du hast redundanten code...das geht schicker...und wozu i und j mit 0 initialisieren? das machst du bereits in den schleifen (die man zusammenfassen kann).

edit: im übrigen ist das computerunterforum da eher zu empfehlen ;-)
 
Hilft dir das evtl. weiter?

-------------------------

/*

Title : Matrixmultiplikation
LastEdit: 02/11/1999
Author : Johnsonbaugh, R.
Source : Johnsonbaugh, R.: Application Programming in ANSI C
System : ANSI-C

---------------------------------------------------------------------
*/

/* Programm zur Multiplikation zweier Matrizen */


#include <stdio.h>
#include <stdlib.h>

#define MAXSIZE 20

/* Deklaration der Funktionen zum .. */
void
store( int m[ ][ MAXSIZE ], int n ), /* Einlesen */
mult( int m1[ ][ MAXSIZE ], int m2[ ][ MAXSIZE ],
int m3[ ][ MAXSIZE ], int n ), /* Multiplizieren */
print( int m[ ][ MAXSIZE ], int n ); /* Ausgeben */

main()
{
int n;
int m1[ MAXSIZE ][ MAXSIZE ],
m2[ MAXSIZE ][ MAXSIZE ],
m3[ MAXSIZE ][ MAXSIZE ];

/* Daten in m1 and m2 einlesen, dann Kontrollausgabe */
printf( "Input matrix size: " );
scanf( "%d", &n );
printf( "Input first matrix by row\n" );
store( m1, n );
printf( "\nMatrix m1:\n" );
print( m1, n );
printf( "\nInput second matrix by row\n" );
store( m2, n );
printf( "\nMatrix m2:\n" );
print( m2, n );

/* Multipliziere m1 mit m2, Ergebnis in m3 */
mult( m1, m2, m3, n );

/* Ergebnisse anzeigen */
printf( "\nProdukt m3:\n" );
print( m3, n );

return EXIT_SUCCESS;
}

/* Multiply matrix m1 by matrix m2, storing the
* product in matrix m3, where all three matrices are
* n by n in size:
* n-1
* m3[ i ][ j ] = SUM m1[ i ][ k ] * m2[ k ][ j ]
* k=0
* and 0 <= i,j < n.
*/
void mult( int m1[ ][ MAXSIZE ],
int m2[ ][ MAXSIZE ],
int m3[ ][ MAXSIZE ],
int n )
{
int i, j, k;

for ( i = 0; i < n; i++ )
for ( j = 0; j < n; j++ ) {
m3[ i ][ j ] = 0;
for ( k = 0; k < n; k++ )
m3[ i ][ j ] += m1[ i ][ k ] * m2[ k ][ j ];
}
}

/* Store data in matrix by row.
*/
void store( int m[ ][ MAXSIZE ], int n )
{
int i, j;

for ( i = 0; i < n; i++ )
for ( j = 0; j < n; j++ )
scanf( "%d", &m[ i ][ j ] );
}

void print( int m[ ][ MAXSIZE ], int n )
{
int i, j;

for ( i = 0; i < n; i++ ) {
for ( j = 0; j < n; j++ )
printf( "%d ", m[ i ][ j ] );
putchar( '\n' );
}
}

-------------------------------


Ansonsten habe ich noch eine zweite Variante aus einem Skript, das ich für meine Vorlesung bekommen habe.

Bis denne!
 
des der code nich besonders schön is, is doch mal völlig nebensächlich.
du musst den aufruf einfach so schreiben
matmulti(matA, matB);
un nix weiter

achja un die funktion was du da als "unterprogramm" bezeichnest muss vor die main oder du musst vor der main eine forward declaration machen wie du auch schon im ansatz drin hast:
//void matmulti ();
muss dann heißen:
void matmulti (int matA[][5],int matB[][5]);
 
Warum übergibst Du nicht einen Pointer? Macht bestimmt mehr Sinn. Und die Matrizen sollten dynamisch angelegt werden und nicht als lokale Variablen.
 
Vielen Dank für eure Hilfe !

Pointer übergeben habe ich versucht, aber ohne Erfolg aufgrund mangelndem Verständnis. Auch ist das nicht unbedingt gefordert. Wichtig ist das Unterprogramm bzw. mit Unterprogrammen zu arbeiten. Dynamisch Felder sind meines Wissens in C nicht möglich, im Gegensatz zu C++.
Mittlerweile habe ich den Code auch schon etwas verfeinert und benutzerfreundlicher gestaltet. Das Programm läuft auch schon, doch leider ist das Ergebnis bzw. die Ergebnismatrize schlecht. Es werden nur wilde Zahlen ausgegeben, was daran liegen mag, dass die Felder A und B vor dem Einlesen der Koordinaten komplett (wie in der Berechnung der Ergebnismatrize bereits berücksichtigt) mit Nullen überschrieben werden müssen da sie vorher mit willkürlichen Werten belegt sind.

Hat dazu jemand noch einen Hinweis parat und kann mir helfen ??

hier der Code :
#include <stdio.h>
#include <math.h>


#define max 5 //definiert eine dynamische Variable mit maximalem Wert (5)
double matC [max][max];
int k;

void matmulti (double matA[][max],double matB[][max]);


//****************************************************Hauptprogramm ANFANG****************************************************************

int main () {

int as=0; //Spalten matrixA
int az=0; //Zeilen matrixA
int bs=0; //Spalten matrixB
int bz=0; //Zeilen matrixB
int i=0; //Zählvariable
int j=0; //Zählvariable
int f=0; //Zählvariable
int g=0; //Zählvariable

double matA[max][max]; //MatrixA mit maximal 5x5 Feldern angelegt (dynamische Variable)
double matB[max][max]; //MatrixB mit maximal 5x5 Feldern angelegt (dynamische Variable)
//double matC[max][max]; //ergebnis Matrix

while(1){

printf("\n################################################################################");

printf("\n Programm zur Multiplikation zweier Matrixen gewuenschter Groesse\n");

printf("\n################################################################################\n");


printf("\n\n\n Bitte beachten: Die maximalen Dimensionen von 5x5 duerfen nicht \n ueberschritten werden\n\n\n");

printf(" Dimensionen der Matrixen festlegen\n\n\n");

printf(" Zeilenanzahl der Matrix A ?\n");

printf(" Zeilen = ");

scanf("%d",&az);

printf(" Spaltenanzahl der Matrix A ?\n");

printf(" Spalten = ");

scanf("%d",&as);

printf(" \n Zeilenanzahl der Matrix B ?\n");

printf(" Zeilen = ");

scanf("%d",&bz);

printf(" Spaltenanzahl der Matrix B ?\n");

printf(" Spalten = ");

scanf("%d",&bs);

/*if (az<=5,as<=5,bz<=5,bs<=5)break;

else printf(" Es sind nur Matrizen bis 5x5 zulaessig !");

return 1;*/


if(as==bz) break;

else printf(" Berechnung nicht möglich!! \n");
}


// Kontrollausgabe
printf("\n \n Die Matrix A hat das Format %i x %i \n", as, az);
printf(" Die Matrix B hat das Format %i x %i \n", bs, bz);
printf("\n\n\n Koordinaten der Matrix A eingeben (%d Werte)", as*az);


// Matrizenkoordinaten A einlesen
for (i = 0; i < az; i++){ //as -> az -> sonst wirds falsch angezeigt (bei den anderen auch - bist anscheined durcheinandergekommen)
printf(" \n Zeile %d = ", i+1);


for (j = 0; j < as; j++)
scanf(" %d", & matA[j]);
}

// Kontrollausgabe Matrix A
for (i = 0; i < az; i++)
{ printf("\n");
for (j = 0; j < as; j++)
printf("%d ",matA[j]);

}

printf("\n\n\n Koordinaten der Matrix B eingeben (%d Werte)", bs*bz);

// Matrizenkoordinaten B einlesen
for (i = 0; i < bz; i++){
printf(" \n Zeile %d = ", i+1);
for (j = 0; j < bs; j++)
scanf(" %d", & matB[j]);
}

// Kontrollausgabe Matrix B
for (i = 0; i < bz; i++){
printf("\n");
for (j = 0; j < bs; j++)
printf(" %d ",matB[j]);

}

//Unterprogramm aufrufen

matmulti(matA,matB);


return 0 ;

} // main Ende


//****************************************************Hauptprogramm ENDE****************************************************************




//****************************************************Unterprogramm ANFANG**********************************************************

//Unterprogramm zur Matzizenmultiplikation

void matmulti (double matA[][max],double matB[][max]){


int i;
int j;
int k;


for (i=0; i<max; i++){

for (j=0; j<max; j++){

matC[j] = 0; // Hiermit wird die Matrix C komplett auf 0 gesetzt


for (k=0; k<5; k++){


matC[j] += matA[k] * matB[k][j];
}
}
}

// Ausgabe des Ergebnisses


printf(" \n \n Ergebnis-Matrix:\n \n");

for (i=0; i<5; i++){


for (j=0; j<5; j++){


printf("%d", matC[j]);
}

printf("\n");

}


} //Unterprogramm Ende

//****************************************************Unterprogramm ENDE**********************************************************
 
Erstmal sind deine Matrizen vom Typ double, du liest aber integer daten ein
-> scanf("%d" ... anstatt z.B. scanf("%f ...
Die daten werden also mit dem falschen Datentyp eingelesen.

Das nächste ist, dass du die Komplette Matrix multiplizierst, die im Speicher vorhanden ist, also 5x5. Du lässt es aber zu die anzahl der Zeilen und Spalten festzulegen. Daher solltest du diesen wert an die Multiplikationsfunktion auch übergeben:

void matmulti (double matA[][max],double matB[][max], int zeilen, int spalten);

Dynamische Felder sind natürlich auch in C möglich. Man reserviert einfach Speicher, wie der reservierte Speicher interpretiert wird, ist dem Programmierer überlassen.
 
Erstmal sind deine Matrizen vom Typ double, du liest aber integer daten ein
-> scanf("%d" ... anstatt z.B. scanf("%f ...
Die daten werden also mit dem falschen Datentyp eingelesen.

Danke für den Hinweis, da wär ich nicht so schnell drauf gekommen.

Das nächste ist, dass du die Komplette Matrix multiplizierst, die im Speicher vorhanden ist, also 5x5. Du lässt es aber zu die anzahl der Zeilen und Spalten festzulegen. Daher solltest du diesen wert an die Multiplikationsfunktion auch übergeben:

void matmulti (double matA[][max],double matB[][max], int zeilen, int spalten);

Das hab ich mir zwar auch schon gedacht, jedoch können die Dimensionen der Matrizen A und B im Hauptprogramm ja unterschiedlich sein. Welche soll ich da denn übergeben ?

Dynamische Felder sind natürlich auch in C möglich. Man reserviert einfach Speicher, wie der reservierte Speicher interpretiert wird, ist dem Programmierer überlassen.

Wußte ich bislang auch noch nicht.

Danke für die netten Tipps ! Werd gleich mal sehen, dass ich mein Programm entsprechend verbesser. Glaubst du denn, dass eines davon ursächlich dafür sein könnte das meine Ergebnis-Matzize lauter Nullen aufweist ?
 
Glaubst du denn, dass eines davon ursächlich dafür sein könnte das meine Ergebnis-Matzize lauter Nullen aufweist ?

Ich denke, das hat vorallem mit dem Datentyp zu tun. Integer wird als Zweikomplement dargestellt, double dagegen mit mantisse und exponent.
Dazu kommt noch, das bei einem 32-bit system Integer 32-Bit hat und double 64-Bit.
Da du Integer 32-Bit einließt und Berechnungen mit double 64-Bit machst und Zahl mit Zweikomplementdarstellung einließt anstelle einer Gleitkommadarstellung kann nichts sinnvolles rauskommen.

Landen die einglesenen Integer Daten z.B. im Teil des Exponenten, sind die Werte immer 0, denn 0 hoch x ist 0.
 
Ja, vielen Dank ! Das Problem habe ich sogar soeben dank deiner Hilfe lösen können. Die Matrizen werden nun korrekt berechnet und ausgegeben, jedoch wird immer , wie von dir bereits gesagt, die komplette Matrize berechnet, also 5x5 und somit bei der Berechnung zweier 2x2 Matritzen ebenfalls eine 5x5 ausgegeben, entsprechend mit Nullen aufgefüllt. Ich müßte also, wie due auch bereits erwähnt hast, irgendeinen Anhaltswert für die Dimension der Ergebnismatrix übergeben und verwenden. Nur wie ?

Wenn ich beispielsweise versuche, az und bs (A-Spalten und B-Zeilen) als Größenangabe zu übergeben, sagt er mir, das keine 4 Werte als Übergabeparameter erlaubt seien.
So etwa : matmulti(matA,matB,az,bs); bzw. void matmulti (int matA[][max],int matB[][max], az, bs)


Hast du einen Tipp, wie ich auch diesen Schönheitsfehler weg bekomme ??
 
Die Funktionsdefinition und der Aufruf sehen eigentlich richtig aus. Hast du die Deklaration auch geändert?
Ggf. fehlt auch ein Komma in der deklaration oder definition der Funktion.
 
Heissen Dank für den Hinweis an aicpr ! Die Deklaration war tatsächlich noch falsch.
Jetzt läuft das Programm schonmal fehlerfrei.

Einige Schönheitsfehler möchte ich jedoch noch beheben. Welche ästhetischen Änderungen wären denn noch empfehlenswert ?? Ich programmiere erst seit kurzer Zeit und habe die üblichen Tricks noch nicht drauf.

Außerdem stört mich folgendes : Bei der Eingabe der Koordinaten springt der Cursor nach dem zweiten Wert immer nach ganz links. (siehe Screenshot unten) Schön wäre, wenn die Koordinaten nebeneinander oder zumindest untereinander angeordnet wären.

Unbenannt-1.jpg
[/URL][/IMG]
 
Also Leute - vielen Dank für eure Hilfe !! Das hat soweit hingehauen.
Wenn ich nochmal ´ne Frage hab, meld ich mich wieder.

Das mit dem nach links springenden Cursor könnte man übrigens beheben, indem man mit scanf () mehrere Werte einlesen lässt,
obwohl ich mir nicht sicher bin, ob dies bei variablen Werteanzahlen möglich ist...

edit: sag mal, hat jemand von euch vieleicht Maschinenbauinformatik studiert, oder ist noch dabei ?
 
Zurück