Hallo LUG,
ich habe ein kleines Problem in einem C Programm, an dem ich schon fast verzweifle. Auf die Gefahr hin, hier damit offtopic zu sein möchte ich es trotzdem einmal kurz schildern:
<Beispiel> #include <stdlib.h> #include <stdio.h>
int fill(int *feld); // Prototyp
void main() { int feld[20][6]; fill(feld); exit(0); }
int fill(int *feld) { int a,b;
for(b=0;b<20;b++) { for(a=0;a<6;a++) feld[b][a]=10; } return(1); } </Beispiel>
Ganz kurze Erklärung: Ich möchte ein zweidimensionales Feld von Integern in der Main-Funktion statisch definieren. Auf dieses Feld möchte ich aber auch mit anderen, aus main() aufgerufenen Funktionen zugreifen können und dachte, dass mit dem Übergeben der Adresse des Feldes tun zu können. Doch irgendwie scheint das bei Feldern mit Dimensionen >1 nicht zu klappen? In meinem C/C++ Lernbuch habe ich dazu nichts gefunden und wäre sehr dank- bar, wenn mir jemand einen kleinen Tipp geben könnte.
Ein frohes Weihnachtsfest wünscht Euch allen
Matthias
-- matthias.petermann@gmx.de
Ganz kurze Erklärung: Ich möchte ein zweidimensionales Feld von Integern in der Main-Funktion statisch definieren. Auf dieses Feld möchte ich aber auch mit anderen, aus main() aufgerufenen Funktionen zugreifen können und dachte, dass mit dem Übergeben der Adresse des Feldes tun zu können. Doch irgendwie scheint das bei Feldern mit Dimensionen >1 nicht zu klappen? In meinem C/C++ Lernbuch habe ich dazu nichts gefunden und wäre sehr dank- bar, wenn mir jemand einen kleinen Tipp geben könnte.
Was passiert wenn du die Variablen static initialisierst?
Ein frohes Weihnachtsfest wünscht Euch allen
Schöne Weihnachen die auch!
Matthias
Bye, Sebastian
On Fri, Dec 22, 2000 at 11:46:52PM +0100, Matthias Petermann wrote:
Hallo LUG,
ich habe ein kleines Problem in einem C Programm, an dem ich schon fast verzweifle. Auf die Gefahr hin, hier damit offtopic zu sein möchte ich es trotzdem einmal kurz schildern:
Also so wahnsinnig OT ist das ja eigentlich nicht.
<Beispiel> #include <stdlib.h> #include <stdio.h>
int fill(int *feld); // Prototyp
void main() { int feld[20][6]; fill(feld);
Du könntest hier einsetzen fill ((int*) feld); allerings ist das ein ziemlicher dirty hack.
exit(0); }
int fill(int *feld) { int a,b;
for(b=0;b<20;b++) { for(a=0;a<6;a++) feld[b][a]=10; }
Zusätzlich müßtest du das noch als eindimensionalen Array hier benutzen, also feld[b*20+a]=10;
return(1); }
</Beispiel>
Ganz kurze Erklärung: Ich möchte ein zweidimensionales Feld von Integern in der Main-Funktion statisch definieren. Auf dieses Feld möchte ich aber auch mit anderen, aus main() aufgerufenen Funktionen zugreifen können und dachte, dass mit dem Übergeben der Adresse des Feldes tun zu können. Doch irgendwie scheint das bei Feldern mit Dimensionen >1 nicht zu klappen? In meinem C/C++ Lernbuch habe ich dazu nichts gefunden und wäre sehr dank- bar, wenn mir jemand einen kleinen Tipp geben könnte.
Ansonsten könnte man es ja mal mit "vector<vector<int> >" versuchen. Mehr mach ich heute morgen nicht :).
Ein frohes Weihnachtsfest wünscht Euch allen
Irgendwie endet jede Mail, die ich derzeit bekomme, mit einem derartigen Satz :).
Matthias
Ulf
Noch ein kleiner Nachtrag. Das Programm kann mit >1-dimensionalen Arrays gar nicht funktionieren aus einem einfachen Grund.
Bekanntermaßen werden Arrays im Speicher so angelegt:
int a[4]
(Bytes) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | a[0] | a[1] | a[2] | a[3] |
Wenn ich jetzt einen mehrdimensionalen Array verwende, ist die Anordnung im Speicher folgendermaßen:
int a[2][2]
(Bytes) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | a[0][0] | a[0][1] | a[1][0] | a[1][1] |
d.h. wenn ich einem array z.B. "int feld[20][6]" anlege, dann "weiß" der Compiler, daß feld[0][0] und feld[1][0] genau 6 x sizeof(int) voneiander entfernt sind. Da die Zahlen bei der Array-Deklaration statisch sind, weiß das die Funktion, an die der Anfangszeiger des Arrays übergeben wird, nicht mehr; der Aufruf feld[2][2] ist hier mehrdeutig, da die exakte Position im Speicher für den Compiler nicht bestimmbar ist.
Lösungsmöglichkeiten (zumindest was mir jetzt einfällt): 1. das, was ich heute morgen schon gemailt habe (static cast + eindimensionale Behandlung in der Funktion)
2. vector<vector<int> > verwenden
3. den Array global setzen.
4. einen Array von int-Pointern (die dann ihrerseits wieder auf Arrays zeigen können), ähnlich wie bei "char ** argv"
5. eine rudimentäre Klasse schreiben, die den Zugriff auf den Array kapselt. Wenn du mit dem Array noch mehr anstellen willst als nur Daten zu speichern, wäre das sogar zu empfehlen.
ciao, Ulf
PS: da mir die ganzen Weihnachtsgrüße allmählich zum Hals raushängen, wünsche ich hier schon mal vorausschauend ein gesundes neues Jahr :).
On Friday 22 December 2000 23:46, Matthias Petermann wrote:
Hallo LUG,
ich habe ein kleines Problem in einem C Programm, an dem ich schon fast verzweifle. Auf die Gefahr hin, hier damit offtopic zu sein möchte ich es trotzdem einmal kurz schildern:
<Beispiel> #include <stdlib.h> #include <stdio.h>
int fill(int *feld); // Prototyp
int fill(int feld[][6]);
void main() { int feld[20][6]; fill(feld); exit(0); }
int fill(int *feld)
int fill(int feld[][6])
{ int a,b;
for(b=0;b<20;b++) { for(a=0;a<6;a++) feld[b][a]=10; } return(1); }
</Beispiel>
Ganz kurze Erklärung: Ich möchte ein zweidimensionales Feld von Integern in der Main-Funktion statisch definieren.
<tutnixzurSache> es ist nicht statisch! Dann müßte static davor stehen oder das Feld müßte global definiert sein.
Main mag zwar die Funktion sein, die das ganze Programm über aufgerufen ist, aber nichts desto trotz nur eine Funktion. => Es ist also auch durchaus erlaubt main von einer anderen Stelle des Programmes aus aufzurufen (nichts anderes macht die Initialisierungsroutine aus libgcc.a). </tutnixzursache>
Auf dieses Feld möchte ich aber auch mit anderen, aus main() aufgerufenen Funktionen zugreifen können und dachte, dass mit dem Übergeben der Adresse des Feldes tun zu können. Doch irgendwie scheint das bei Feldern mit Dimensionen >1 nicht zu klappen? In meinem C/C++ Lernbuch habe ich dazu nichts gefunden und wäre sehr dank- bar, wenn mir jemand einen kleinen Tipp geben könnte.
Wenn Du Felder mit variablen Dimensionen nutzen willst solltest Du Dir eine Klasse definieren (evtl. gibt's das schon in der STL).
Konrad
On Sat, Dec 23, 2000 at 02:10:39PM +0100, Konrad Rosenbaum wrote:
Wenn Du Felder mit variablen Dimensionen nutzen willst solltest Du Dir eine Klasse definieren (evtl. gibt's das schon in der STL).
Je nachdem, was man damit machen will, gibt es sogar mehrere Klassen in der STL (vector, map, list). Einige Klassen bieten sogar hash-Zugriff an (was gerade bei random access bedeutend schneller ist). Selber sowas programmieren ist IMHO normalerweise nicht der beste Weg (Ausnahme: man will das Programmieren dieser Klassen lernen), da idR die Standardklassen schneller sind.
Konrad
Ulf
Konrad, Sebastian, Ulf - vielen Dank für Eure Tipps. Ich bin gerade nach Hause gekommen und werde mich gleich mal daran machen, das alles auszuprobieren. Ich werde euch in meiner Facharbeit dankend erwähnen ;)
Matthias
-- matthias.petermann@gmx.de
Hallo Konrad,
ich habe Deine Lösung verwendet und alles funktioniert wie gewünscht. Ich habe aber noch eine zusätzliche Frage:
Deine Variante für den Prototyp ist folgende:
int fill(int feld[][6]);
Ich hatte in meinen eigenen "Versuchen" vorher schon int fill(int feld[][]); probiert, jedoch ohne Erfolg. Warum muss für die zweite Dimension die Größe des Feldes mit angegeben werden und wie würde das z.B. bei dreidimensionalen Feldern aussehen?
Vielen Dank,
Matthias
-- matthias.petermann@gmx.de
On Sun, Dec 24, 2000 at 12:32:43PM +0100, Matthias Petermann wrote:
Hallo Konrad,
Ich heiß zwar nicht Konrad, mail aber trotzdem mal :).
ich habe Deine Lösung verwendet und alles funktioniert wie gewünscht. Ich habe aber noch eine zusätzliche Frage:
Deine Variante für den Prototyp ist folgende:
int fill(int feld[][6]);
Ich hatte in meinen eigenen "Versuchen" vorher schon int fill(int feld[][]); probiert, jedoch ohne Erfolg. Warum muss für die zweite Dimension die Größe des Feldes mit angegeben werden und
Wie schon einmal gemailt, benötigt der Compiler die Informationen, wie weit er von feld[n][x] nach feld[n+1][x] springen muß. Da das abhängig ist von der (statischen) Größe der zweiten Dimension des Arrays, muß diese explizit angegeben werden, da es sonst mehrdeutig wird. Wenn du "feld[][]" angibst, ist eben unbekannt, wie weit der Sprung von z.B. feld[0][0] nach feld[1][0] ausfällt. Wenn du hingegen "feld[][6]" angibst, ist das bekannt, nämlich 6xsizeof(int) = 24 bytes.
wie würde das z.B. bei dreidimensionalen Feldern aussehen?
"int feld[][constant x][constant y]" müßte dann gehen.
Vielen Dank,
Matthias
Ulf
Hallo Ulf,
ich denke, jetzt hab ich das verstanden. Klar, wenn der Compiler die Größe der Felder nicht kennt, weiß er nicht, wie weit er springen muss.
Also nochmals vielen Dank an alle die mir geholfen haben,
Matthias
-- matthias.petermann@gmx.de
lug-dd@mailman.schlittermann.de