Matrix in C mit Doppelzeiger
-
Hallo, ich bin c-Novize und mache gerade eine Übung aus einem Buch, in welcher ich eine Matrix mit Doppelzeigern bearbeite. Das Programm hat 3 Subroutinen: Speicher reservieren, einlesen, ausgeben. Leider kriege ich immer nur Nullen oder komische Zahlen ausgegeben, unabhängig davon, was ich eingebe. Ich vermute mal, schon die erste Subroutine ist falsch. Sieht einer den Fehler? Ich würde es ja sonst mit einem normalen Doppelfeld machen. Aber malloc und calloc geben nun mal Zeiger aus und ich weiß also nicht, wie ich für normale Doppelfelder Speicher reservieren sollte. Ich fand das mit den Doppelzeigern ganz komfortabel, aber offensichtlich habe ich es noch nicht ganz verstanden.
#include<stdio.h> #include<stdlib.h> /* Funktionsdeklaration */ double ** erzeuge_matrix(int *n); void lies_matrix(double **matrix,int *n); void print_matrix(double **matrix,int *n); /* Hauptprogramm */ main() { int *n=(int *) malloc(sizeof(int)); printf("Geben Sie die Matrixdimension ein. "); scanf("%d",n); double **A=erzeuge_matrix(n); lies_matrix(A,n); print_matrix(A,n); } /* Funktionsdefinition */ double ** erzeuge_matrix(int *n) { int i,j; double **matrix=(double**) calloc(*n,sizeof(double*)); if(matrix==NULL) return NULL; for(i=0;i<*n;i++) { *(matrix+i)=(double*) calloc(*n,sizeof(double)); if(*(matrix+i)==NULL) { for(j=0;j<i;j++) { free(*(matrix+j)); free(matrix); return NULL; } } } return matrix; } void lies_matrix(double **matrix,int *n) { int i,j; for(i=0;i<*n;i++) { for(j=0;j<*n;j++) { printf("m[%d][%d]=",i,j); scanf("%f",*(matrix+i)+j); } } } void print_matrix(double **matrix, int *n) { int i,j; for(i=0;i<*n;i++) { for(j=0;j<*n;j++) { if(j<*n-1) printf("%d",*(*(matrix+i)+j)); else printf("%d=\n",*(*(matrix+i)+j)); } } }
-
Compiliere immer mit allen Warnungen!
test.c:57: warning: format ‘%f’ expects type ‘float *’, but argument 2 has type ‘double *’ test.c:69: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘double’ test.c:70: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘double’
Kümmere dich darum, dann funktioniert es auch. Respekt, das sieht insgesamt sehr richtig aus (außer dass du ganz am Ende nichts freigibst), die meisten machen das beim ersten Mal falsch.
Du brauchst übrigens nicht überall Zeiger verwenden, nur weil A ein Doppelzeiger ist, es spricht nichts dagegen n als normalen int zu behandeln.
Und das Casten des malloc-Ergebnisses gilt übrigens eher als schlechter Stil, das ist C++.
-
So würde z.B. eine korrekter Umgang mit dem "Doppelzeiger" aussehen, mit Eingabeprüfung, Speicherfreigabe,...
Beachte: für double gilt bei scanf der Formatparameter "%lf", bei printf jedoch "%f". (Das war eine Compilerwarnung).#include<stdio.h> #include<stdlib.h> /* Funktionsdeklaration */ double **erzeuge_matrix(int n); void lies_matrix(double **matrix,int n); void print_matrix(double **matrix,int n); /* Hauptprogramm */ int main() { int n; printf("Geben Sie die Matrixdimension ein. "); if( 1==scanf("%d",&n) ){ double **A=erzeuge_matrix(n); if( A ) {lies_matrix(A,n); print_matrix(A,n); while( n-- ) free(A[n]); free(A);}} return 0; } /* Funktionsdefinition */ double ** erzeuge_matrix(int n) { int i,j; double **matrix=calloc(n,sizeof(double*)); if(matrix==NULL) return NULL; for(i=0;i<n;i++) { matrix[i]=calloc(n,sizeof(double)); if(matrix[i]==NULL) { for(j=0;j<i;j++) { free(matrix[j]); free(matrix); return NULL; } } } return matrix; } void lies_matrix(double **matrix,int n) { int i,j; for(i=0;i<n;i++) { for(j=0;j<n;j++) { printf("m[%d][%d]=",i,j); if( 1!=scanf("%lf",&matrix[i][j]) ) exit(1); } } } void print_matrix(double **matrix, int n) { int i,j; for(i=0;i<n;i++) { for(j=0;j<n;j++) { printf("\nm[%d][%d]=%f",i,j,matrix[i][j]); } } }
-
Vielen Dank Sepp! Da habe ich wohl nicht genau genug gelesen. Scanf braucht lf hinter dem Platzhalter für double. Jetzt geht es. Doch nur ein Syntaxfehler.
-
Hallo Wutz. Diese verkürzte Schreibweise mit der Bedingung bei if und while kenne ich noch gar nicht.
@Sepp: Ist das mit der Speicherfreigabe am Ende nicht egal wenn das Programm sowieso endet?
-
Obi-Wan schrieb:
Ist das mit der Speicherfreigabe am Ende nicht egal wenn das Programm sowieso endet?
Schon nur sollte man sich das nicht angewöhnen und immer selbst freigeben.
-
Obi-Wan schrieb:
@Sepp: Ist das mit der Speicherfreigabe am Ende nicht egal wenn das Programm sowieso endet?
Nur wenn da hinterher ein Betriebssystem ist, das sich Speicher von beendeten Programmen zurückholt. Das ist zwar der normalfall, muss aber nicht sein. C Programme sind auch auf Plattformen portierbar, auf denen dies nicht so ist.