Konstrukt erlaubt
-
danke für die Antwort
Ich habe mich schlecht ausgedrückt. Also der Code funktioniert, die Frage war nur ob man so machen kann, oder ob das schlechter Stil ist. Also darf man das, oder lieber einen anderen Weg?
P.s oh ich hab das aus dem Kopf geschrieben. Ich meinte natürlich
char *x[10][10] = {\0}
-
Nadascha schrieb:
Also der Code funktioniert
Das wundert mich. Zeig mal den ganzen Code.
-
Der ist zu Hause
Wieso sollte man einem Array keinen Wert zuweisen können? Soetwas hier geht ja auf jeden Fall? for( i = 0; i < x; i++) count[i] = 0;
Es geht nur darum ob es bei einem 2 dimensionalen Array möglich ist eine Dimension weg zu lassen. Und ob man ein Array mit Hilfe von {\0} initialisieren kann. Wie gesagt war der Code aus dem Kopf geschrieben. Ob das nun ein Zeiger ist, oder ein int oder char ist eigentlich egal. Man könnte also auch sowas nehmen:
int count[x][y]; for( i = 0; i < x; i++) count[i] = z;
-
Nadascha schrieb:
Wieso sollte man einem Array keinen Wert zuweisen können?
Damit die Sprache klein bleibt.
Man einem Array als ganzes keinen Wert zuweisen:
int array1[SIZE] = {0}; array1[0] = 42; // das geht, weil array1[0] kein Array ist int array2[SIZE][SIZE] = {0}; array2[0] = 42; // das geht nicht, weil array2[0] ein Array ist // (von den Typen gar nicht zu sprechen)
Man kann ein Array von Arrays mit {42} initialisieren. Dann werden alle Elemente, die man nicht angegeben hat, auf 0 gesetzt.
-
Sicher, dass das nicht funktioniert? Ist der Index-Operator nicht ganz einfach eine Pointer-Addition?
MfG SideWinder
-
SideWinder schrieb:
Sicher, dass das nicht funktioniert? Ist der Index-Operator nicht ganz einfach eine Pointer-Addition?
Ziemlich sicher.
Kleiner Exkurs für Nadascha: wenn etwas auf der linken Seite einer Zuweisung stehen darf, heisst es in C "lvalue". Ein Array-Typ heisst "incomplete", wenn die Grösse des Arrays nicht bekannt ist. "const" ist ein Schlüsselwort, das den Compiler anweist, die Änderung eines Objektes nicht zu gestatten.
Damit sollte der Absatz 6.3.2.1 des C99-Standards (TC2) klar sein, dort steht:
A modifiable lvalue is an lvalue that does not have array type, does
not have an incomplete type, does not have a const-qualified type, and if it is a structure
or union, does not have any member (including, recursively, any member or element of
all contained aggregates or unions) with a const-qualified type.
-
Der Index-Operator ist nur Pointerarithmetik, aber in diesem Fall halt mit einem int(*)[10]. Dementsprechend ist das Ergebnis ein int[10], und das kannst du nicht als lvalue benutzen - wie mngbd ja schon gesagt hat.
Was die Initialisierung angeht, die werden zwar vermutlich die meisten Compiler fressen, schöner ist aber trotzdem
int x[10][10] = { { 0 } };
Auf die Art warnt gcc auch mit -Wall nicht.
-
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?