Konstrukt erlaubt
-
seldon schrieb:
Was die Initialisierung angeht, die werden zwar vermutlich die meisten Compiler fressen
Nicht die meisten, sondern: alle. Sonst wären sie keine.
Das liegt einfach daran, dass jedes Element eines Arrays, das nicht angegeben wird, mit Null initialisiert wird; und das gilt rekursiv.
seldon schrieb:
schöner ist aber trotzdem
int x[10][10] = { { 0 } };
Auf die Art warnt gcc auch mit -Wall nicht.
Ist doch egal, was der gcc sagt. Wenn dich das so sehr stört, mach eben ein -Wno-missing-braces dazu.
-
O.k. Jetzt verstehe ich es schon ein kleines bisschen besser. Vielen Dank
Also ist ein zweidimensionales Array quasi ein Array aus Arrays?
Ich hätte warten sollen, bis ich zu Hause bin um den Code zu posten. Aber mich hatte das so gewurmt. Hier ist der Code, der bei mir geht, mich aber verwirrt hatte
int parseLine(char *cStream, char *cDelim) { int i=0; int j=0; char aArray[MAXROW][MAXCOL] = {'\0'}; /*Also hier werde ich dann {{'\0'}} schreiben? Ich hatte gelesen, dass arrays eigentlich automatisch initalisiert werden. Aber beim Debuggen sah das ganz anders aus. Dort stand noch Speichermüll*/ char *pos; pos = strrchr (cStream, cDelim); if (pos) { while(pos) { strcpy(aArray[i],pos+1); cStream[pos - cStream ]='\0'; pos = strrchr (cStream, cDelim); i++; } strcpy(aArray[i],cStream); for (i=MAXROW-1;i>=0;i--) { printf("aArray=%s",aArray[i]); /*Das wunderte mich. Ich spreche das Array nur in der ersten Dimension an, aber es geht*/ } } else printf("Nix\n"); return 0; }
Sorry nochmal, das ich evtl. für Verwirrung gesorgt habe.
-
Nadascha schrieb:
Also ist ein zweidimensionales Array quasi ein Array aus Arrays?
Exakt.
Ein Array ist einfach eine Aneinanderreihung von Objekten im Speicher. Ein Objekt kann selbst ein Array sein. Deshalb kann man ein 2d-Array[zeilen][spalten] immer auch als 1d-Array[zeilen * spalten] auffassen, auch bei der Initialisierung.
char aArray[MAXROW][MAXCOL] = {'\0'}; /*Also hier werde ich dann {{'\0'}} schreiben? Ich hatte gelesen, dass arrays eigentlich automatisch initalisiert werden. Aber beim Debuggen sah das ganz anders aus. Dort stand noch Speichermüll*/
'\0' ist das gleiche wie 0. Ein char-Array "abc" kann im Speicher zB so aussehen:
(hexadezimal) 61 FF FF FF 62 FF FF FF 63 FF FF FF 00 FF FF FF a b c \0
Die Bytes, die ich hier auf FF gesetzt habe, können da sein, müssen aber nicht. Wenn sie da sind, haben sie irgeneinen undefinierten Wert. Sie können da sein, weil viele Maschinen schneller auf Adressen zugreifen können, die durch eine bestimmte Zahl teilbar sind, in dem Fall 4. Ob sie da sein sollen, kann man vielleicht beim Compiler einstellen. Wenn sie da sind, machen sie keine Probleme, solange man nur über Array-Indizes oder Zeiger-Operationen auf die Zeichen zugreift, weil der Compiler weiss, ob sie da sind. Wenn sie da waren, haben sie vielleicht deinen Debugger verwirrt.
printf("aArray=%s",aArray[i]); /*Das wunderte mich. Ich spreche das Array nur in der ersten Dimension an, aber es geht*/
aArray[i] ist ein Array von char (ein String). Wenn man aArray[i] an printf() übergibt, wird es zu einem Zeiger auf das erste Zeichen. Im C-Slang sagt man: aArray[i] ist ein gültiger Wert, aber nicht gültig als lvalue.
Nadascha schrieb:
Sorry nochmal, das ich evtl. für Verwirrung gesorgt habe.
Hier für Verwirrung sorgen ist eine gute Sache.
-
Klasse! Vielen Dank! Ich hoffe ich habe es jetzt:
Also hätte ich versucht einen Wert zu zuweisen hätte es geknallt. (Weil kein lvalue) Aber bei der Ausgabe gibt es keinen Fehler, weil fprint konvertiert das Array zu einem Zeiger auf des erste Element. Deshalb kann ich hier strcpy(aArray[i],pos+1); auch zur nächsten Adresse springen. Und wenn ich auf ein Array mittels x[i] zugreife, zerfällt er dann auch in einen Zeiger? Oder nur bei Übergabe an Funktionen?
Ich werde mir heute Abend noch einmal das hier durchlesen. http://www.dclc-faq.de/kap2.htm#2.10 Scheinbar sind Arrays in C etwas anders "gestrickt" .
-
mngbd schrieb:
Ein Array ist einfach eine Aneinanderreihung von Objekten im Speicher. Ein Objekt kann selbst ein Array sein. Deshalb kann man ein 2d-Array[zeilen][spalten] immer auch als 1d-Array[zeilen * spalten] auffassen, auch bei der Initialisierung.
Kann man nicht. Es ist nicht garantiert, dass alle zweite Dimensionen am Stück im speicher stehen.
2D: Es ist ein Array von einem Array - Dereferenziert kriegt man ein Array (bzw. einen Zeiger).
1D: Es ist ein Array - Dereferenziert kriegt man den Wert.
-
Nadascha schrieb:
Und wenn ich auf ein Array mittels x[i] zugreife, zerfällt er dann auch in einen Zeiger? Oder nur bei Übergabe an Funktionen?
In jedem Ausdruck wird ein Zeiger daraus, ausser als Operand von sizeof. Bei Übergabe an Funktionen, bei Ausdrücken wie array[i], ganz egal. array[i] ist das gleiche wie *(array + i).
Janjan schrieb:
Kann man nicht. Es ist nicht garantiert, dass alle zweite Dimensionen am Stück im speicher stehen.
Wie jetzt? Bei einem Array von Objekten ist garantiert, dass sie alle nacheinander sind, ausser die Objekte sind Arrays, dann... was passiert dann eigentlich?
Janjan schrieb:
2D: Es ist ein Array von einem Array - Dereferenziert kriegt man ein Array (bzw. einen Zeiger).
Was jetzt, Zeiger oder Array?
-
mngbd schrieb:
'\0' ist das gleiche wie 0. Ein char-Array "abc" kann im Speicher zB so aussehen:
(hexadezimal) 61 FF FF FF 62 FF FF FF 63 FF FF FF 00 FF FF FF a b c \0
Ich bin mir gar nicht mehr so sicher, dürfen eigentlich Füllbytes in einem char-Array sein?
-
Wie jetzt? Bei einem Array von Objekten ist garantiert, dass sie alle nacheinander sind, ausser die Objekte sind Arrays, dann... was passiert dann eigentlich?
Dann müßte es eine neue Dimension sein? Also würde es dann nur eine "Ebene" weiter rutschen. Also ein Array aus Arrays die Arrays beinhalten. Ist das so richtig? Ganz grob könnte man dann sagen, es gibt eigentlich nur 1d arrays. Im Speicher werden die dann so abgelegt: [0][0][0] -> [0][0][1] -> [0][1][1] usw?
-
Nadascha schrieb:
Ganz grob könnte man dann sagen, es gibt eigentlich nur 1d arrays. Im Speicher werden die dann so abgelegt: [0][0][0] -> [0][0][1] -> [0][1][1] usw?
Genau. Nur dass sich bei den Typen, die Arrays von Arrays sind, der Compiler um die Dimensionen kümmert:
#include <stdio.h> int main(void) { int array[2][2][2] = {{{1,2},{3,4}},{{5,6},{7,8}}}; // oder gleichwertig: // int array[2][2][2] = {1,2,3,4,5,6,7,8}; for (int a = 0; a < 8; a++) printf("array[%d] -> %d\n", a, ((int *)array)[a]); putchar('\n'); for (int a = 0; a < 2; a++) for (int b = 0; b < 2; b++) for (int c = 0; c < 2; c++) printf("array[%d][%d][%d] -> %d\n", a, b, c, array[a][b][c]); return 0; }
-
mngbd schrieb:
'\0' ist das gleiche wie 0. Ein char-Array "abc" kann im Speicher zB so aussehen:
(hexadezimal) 61 FF FF FF 62 FF FF FF 63 FF FF FF 00 FF FF FF a b c \0
Das war Blödsinn. Ich verwechsle das immer mit Strukturen.
Ein char-Array "abc" sieht im Speicher genau so aus, wenn man ASCII annimmt, und ein Byte acht Bits hat:
61 62 63 00 a b c \0
-
mngbd schrieb:
Nadascha schrieb:
Also ist ein zweidimensionales Array quasi ein Array aus Arrays?
Exakt.
Nicht immer!
-
Wieso machst Du immer den Smily unter jedes Posting
-
ArrayFan 2010 schrieb:
mngbd schrieb:
Nadascha schrieb:
Also ist ein zweidimensionales Array quasi ein Array aus Arrays?
Exakt.
Nicht immer!
Wann denn nicht?
-
Ich habe jetzt meine alten Bücher rausgekramt, da ich ja wirklich alles vergessen habe. Im Bjarne Stroustrup Buch steht das auch so. Ist zwar C++, aber es bezog sich auf auf C. Also im Prinzip nur ein 1d Array (also ein linearer Speicher), in dem die einzelnen Element nacheinander folgend sind.
Danke für die Hilfe.
Hätte ja aber eigentlich schon bei strcpy(aArray[i],pos+1); merken müssen was Sache ist. Bin aber erst bei printf stutzig geworden.
-
Nadascha schrieb:
Also im Prinzip nur ein 1d Array (also ein linearer Speicher), in dem die einzelnen Element nacheinander folgend sind.
Exakt.
So steht's auch im Standard. Nur nicht verwirren lassen!