Hallo, ich habe unten mal ein kleines c beispiel angehängt, in dem ein 2dim. feld auf 2 unterschiedliche arten un weisen angelegt wird, einmal statisch und einmal dynamisch. wenn ein 2dim. feld statisch angelegt wird, dann liegen die zellen ja alle hintereinander im speicher : feld[2][3]; speicher: 00 01 02 10 11 12 wenn das ganze jetzt dynamisch angelegt wird, dann kann man, so wie ich jetzt ja, vorerst speicher für ein eind. feld voller zeiger allokieren, die dann jeweils auf speicher zeigen indem die eigentlichen daten liegen, siehe bsp.: #define DIMX 2 #define DIMX 3 voif function(void) { int x[DIMX][DIMY]; int **y; int i; y=(**int)malloc(DIMX*sizeof(*int)); for (i=0; i<DIMX; i++) { y[i] =(*int)malloc(DIMY*sizeof(int)); } } meine frage, wie bekommt der kompiler die umsetzung von : g=x[1][2]; und g=y[1][2]; auf die reihe, da dahinter ja eigentlich zwei völlig unterschiedliche strukturen: y[c][d] entspricht *(*(y+a)+b) x[c][d] entspricht *(x + (a*DIMY) + b) liegen hin!? m.
maddin wrote: <Im Prinzip korrekter Source Code. Die Syntax Fehler ignorieren wir mal. Du solltst dir aber abgewöhnen, den Returnwert von malloc zu casten.> > > meine frage, wie bekommt der kompiler die umsetzung von : > > g=x[1][2]; > und > g=y[1][2]; > > auf die reihe, da dahinter ja eigentlich zwei völlig unterschiedliche > strukturen: Der Compiler weiss aber, dass x als 2-D Array definiert wurde > x[c][d] entspricht *(x + (a*DIMY) + b) Ganz genau. Das kann er Compiler aber nur machen, wenn er weiss, dass x als T x[][] angelegt wurde > y[c][d] entspricht *(*(y+a)+b) Yep.
Man kanns auch so sehen (und so wird es der Compiler auch machen) Die Ersetzung c[d] <-> *(c + d) gilt nur bei 'einfachen' Datentypen wie int, char, Pointer, etc. Das Datentypergebnis von x[c] ist aber, in deinem Fall, int[]. Und damit kann diese Äquivalenz nicht benutzt werden.
Hallo KHB, >> Du solltst dir aber abgewöhnen, den Returnwert von malloc zu casten<< danke für den hinweis, auch wenn ich selbst in meinem "nur beispiel" nicht weis wo du dieses problem gefunden hast, habe ich das übersehen!? >>Der Compiler weiss aber, dass x als 2-D Array definiert wurde<< das habe ich mir auch schon gedacht, compiler sind echt eine komplexe erfindung, ich bewundere immer wieder was alles möglich ist. >>Ganz genau. Das kann er Compiler aber nur machen, wenn er weiss, dass x als T x[][] angelegt wurde<< was meinst du mit T? ein struktur!? gruß, m.
Hi,
>>Man kanns auch so sehen (und so wird es der Compiler auch machen)
Die Ersetzung
c[d] <-> *(c + d)
gilt nur bei 'einfachen' Datentypen wie int, char, Pointer, etc.
Das Datentypergebnis von
x[c]
ist aber, in deinem Fall, int[]. Und damit kann diese
Äquivalenz nicht benutzt werden.<<
darüber muss ich einen moment grübeln.
m.
ps.: die sache mit dem c und d kam dadurch das ich es mit a und b hier
nicht posten konnte da das forum der meinung war ich würde spam posten
:-)
maddin wrote: > Hallo KHB, >>> Du solltst dir aber abgewöhnen, den > Returnwert von malloc zu casten<< > > danke für den hinweis, auch wenn ich selbst in meinem "nur beispiel" > nicht weis wo du dieses problem gefunden hast, habe ich das übersehen!? zb. hier: y=(**int)malloc(DIMX*sizeof(*int)); (wenn wir mal von der falschen Pointer Syntax absehen) Den Return Wert von malloc nie casten. In C ist der cast unnötig. malloc liefert einen void* und der ist in C zuweisungskompatibel zu allen Pointern. Auf der anderen Seite kann dieser cast einen Fehler verstecken. Nämlich dann, wenn kein Protoyp für malloc in Sicht ist. Dann muss der Compiler laut C Regeln davon ausgehen, dass malloc einen int zurückliefert. Ein int muss aber nicht unbedingt dieselbe Größe wie ein Pointer haben. Ist der cast nicht da, dann bemerkt das der Compiler und gibt einen Fehler. Mit dem cast jedoch, wird das Typprüfsystem übergangen und der Compiler akzeptiert diese Zuweisung wieder besseren Wissens. Ein Cast ist immer eine Waffe! Man muss ihn weise und sparsam einsetzen. Ist ein Cast unnötig, dann ist es immer besser ihn wegzulassen. Wenn dein Compiler aber ohne Cast meckert, dann ist das dann kein C Compiler, sondern ein C++ Compiler. In dem Fall sollte man aber malloc überhaupt nicht benutzen (es gibt auch Ausnahmen), sondern stattdessen mit new arbeiten. > >>>Der Compiler weiss aber, dass > x als 2-D Array definiert wurde<< > > das habe ich mir auch schon gedacht, compiler sind echt eine komplexe > erfindung, ich bewundere immer wieder was alles möglich ist. > >>>Ganz genau. Das kann er Compiler aber nur machen, wenn > er weiss, dass x als > T x[][] > angelegt wurde<< > > was meinst du mit T? ein struktur!? Ein Datentyp. T steht für die 'einfachen' Datentypen, wie int, char, Pointer, float, double, struct ...
maddin wrote: > > darüber muss ich einen moment grübeln. Das ist wie in der Physik. Will man schnell abklären, ob eine Formel grundsätzlich stimmen kann, dann vergleicht man einfach die Einheiten. Bsp: Symbol Bedeutung Einheit s Weg m (Meter) t Zeit s (Sekunde) v Geschwindigkeit m/s a Beschleunigung m/s^2 s = v * t kann daher stimmen. Links steht als Einheit m. Rechts steht als Einheit m/s * s -> m. Auf beiden Seiten ergibt sich also für die Einheit m s = v / t kann daher nicht stimmen. Linke Seite: m rechte Seite: m/s / s -> m / s^2 Damit unterscheiden sich die linke und die rechte Seite in den Einheiten und die Formel ist daher Quatsch Ähnlich hier. Nur heist das nicht Einheit sondern Datentyp T * a; (a ist ein Pointer auf T, T steht wieder für int, char, etc.) *a da a ein Pointer auf T ist, ergibt *a das T selbst. (int * b; wenn b den Datentyp int* hat, dann hat *b den Datentyp int) T a[]; a ist ein Array von T. Ein einzelnes Element von A hat daher den Datentyp T. T b[][]; b ist ein 2D Array von T. Eine Zeile des Arrays hat daher den Typ T[]. Ein einzelnes Element wiederrum davon hat den Typ T
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.