kiep_schmeiling
Anmeldungsdatum: 5. April 2008
Beiträge: 59
Wohnort: Deutschland
|
Hi,
ich habe gewisse Probleme bei der Übergabe eines zweidimensionalen Arrays, dessen größe durch Benutzereingabe bestimmt wird, an eine Funktion:
void fn(int xlarge, int ylarge ,int feld[][<was kommt hier rein>])
{
//irgenwelche Anweisungen
}
int main ()
{
int xlarge;
int ylarge;
cout<<"\nGib die Groeße in X-Richtung ein:";
cin>>xlarge;
cout<<"\nGib die Groeße in Y-Richtung ein:";
cin>>ylarge;
int feld[xlarge][ylarge];
fn(xlarge, ylarge, feld);
return 0;
}
Wenn ich nun in besagte eckige Klammer [ylarge] schreibe, meckert er, ylarge sei dort noch nicht definiert, wenn ich sie frei lasse meckert er, man müsst die Größe in alle Dimensionen außer in die Erste angeben. Wie löst man denn dieses Problem?
|
ItIsAFeature
Anmeldungsdatum: 3. September 2008
Beiträge: 5
|
In der Initialisierung die ints mit 0 initialisieren. Dann hat er einen Wert und der Compiler meckert nicht mehr.
In der Funktion übergibst du einfach den namen des arrays sonst nix. Der ist gleichbedeutend mit einem konstanten Pointer auf das erste Element.
D.h. die Anfangsadresse des Arrays wird übergeben.
Sollten dir Pointer nichts sagen, würd ich mich da mal schlau machen.
Denn das Wissen wirst du brauchen, wenn du mit den Daten weiter arbeiten willst.
|
stfischr
Anmeldungsdatum: 1. März 2007
Beiträge: 19197
|
Warum nimmst du nicht einfach vector? Das ist für variable Arrays gemacht.
|
kiep_schmeiling
(Themenstarter)
Anmeldungsdatum: 5. April 2008
Beiträge: 59
Wohnort: Deutschland
|
Vielen Dank, dass mit dem Freilassen funktioniert. @stfischr:
Weil ich von vector noch nie was gehört hab 😳
Ich kenne nur verkettete Listen (vllt. ist das sogar das gleiche?), wobei mir die auch schon dubios erscheinen...
Bin ja auch grad am lernen...
|
Vardamir
Anmeldungsdatum: 26. März 2009
Beiträge: 271
|
Standard Template Library, das würde ich auch empfehlen. Mehrdimensionale Arrays, oder Arrays im Allgemeinen sind äußerst unflexibel und fehleranfällig
|
stfischr
Anmeldungsdatum: 1. März 2007
Beiträge: 19197
|
|
oxe1976
Anmeldungsdatum: 5. Februar 2008
Beiträge: 759
|
kiep schmeiling schrieb: int xlarge;
int ylarge;
cout<<"\nGib die Groeße in X-Richtung ein:";
cin>>xlarge;
cout<<"\nGib die Groeße in Y-Richtung ein:";
cin>>ylarge;
int feld[xlarge][ylarge];
Wenn ich nun in besagte eckige Klammer [ylarge] schreibe, meckert er, ylarge sei dort noch nicht definiert, wenn ich sie frei lasse meckert er, man müsst die Größe in alle Dimensionen außer in die Erste angeben.
Das ist murks, du kannst die Array Groesse so nicht definieren. Die Werte xlarge/ylarge werden erst zur Laufzeit bestimmt, der Compiler moechte das Array aber schon zur Compilezeit anlegen.
Du musst das Array hier dynamisch anlegen bzw. allokieren (mit 'new') Ansonsten wuerde ich auch sagen, schau Dir die STL an (Standard Template Library), da gibs eine Menge Container Klassen (vector, list, etc.). Vorrausgesetzt natuerlich, das Du die STL benutzen kannst/darfst. Gruss
|
phst
Anmeldungsdatum: 24. Juni 2007
Beiträge: 527
|
oxe1976 schrieb: kiep schmeiling schrieb: int xlarge;
int ylarge;
cout<<"\nGib die Groeße in X-Richtung ein:";
cin>>xlarge;
cout<<"\nGib die Groeße in Y-Richtung ein:";
cin>>ylarge;
int feld[xlarge][ylarge];
Wenn ich nun in besagte eckige Klammer [ylarge] schreibe, meckert er, ylarge sei dort noch nicht definiert, wenn ich sie frei lasse meckert er, man müsst die Größe in alle Dimensionen außer in die Erste angeben.
Das ist murks, du kannst die Array Groesse so nicht definieren. Die Werte xlarge/ylarge werden erst zur Laufzeit bestimmt, der Compiler moechte das Array aber schon zur Compilezeit anlegen.
Du musst das Array hier dynamisch anlegen bzw. allokieren (mit 'new')
Das funktioniert durchaus, es handelt sich um eine Erweiterung des GCC, die im C99-Standard definiert ist und wohl auch in den nächsten C++-Standard kommen wird. Der Parameter ließe sich dann als int** definieren. Die Verwendung von STL-Klassen oder noch besser die vollständige Vermeidung von mehrdimensionalen Arrays ist aber auf jeden Fall zu bevorzugen.
|
Hello_World
Anmeldungsdatum: 13. Juni 2006
Beiträge: Zähle...
|
phst schrieb: Das funktioniert durchaus, es handelt sich um eine Erweiterung des GCC, die im C99-Standard definiert ist und wohl auch in den nächsten C++-Standard kommen wird.
Nein, die nächste C++-Version wird dieses Feature nicht enthalten. Es ist prinzipiell unzuverlässig, da es sehr leicht zu Stack Overflows führen kann. Der Parameter ließe sich dann als int** definieren.
Nein, wenn überhaupt dann als int [i][j], wobei i und j andere Parameter der gleichen Funktion sind. Allerdings gibt es im vorliegenden Fall keinen Grund, auf eine gcc-Erweiterung zurückzugreifen, da es mit std::vector eine Lösung gibt, die mit Standard-C++ auskommt.
|
oxe1976
Anmeldungsdatum: 5. Februar 2008
Beiträge: 759
|
Hello World schrieb: phst schrieb: Der Parameter ließe sich dann als int** definieren.
Nein, wenn überhaupt dann als int [i][j], wobei i und j andere Parameter der gleichen Funktion sind. Allerdings gibt es im vorliegenden Fall keinen Grund, auf eine gcc-Erweiterung zurückzugreifen, da es mit std::vector eine Lösung gibt, die mit Standard-C++ auskommt.
Wobei das dann auch wieder die gcc Erweiterung ist (siehe hier): void fn(int xlarge, int ylarge, int feld[xlarge][ylarge]); Diese Loesung sollte vermieden werden, das sie nicht dem Standard entspricht und was gcc spezifisches ist. Besser waere soetwas:
void fn(unsigned xlarge, unsigned ylarge, int* feld);
...
int* feld = new int[xlarge*ylarge];
fn(xlarge, ylarge, feld);
delete [] feld;
Noch besser waere (wie schon gesagt std::vector:
void fn(unsigned xlarge, unsigned ylarge, std::vector<int>& feld);
...
std::vector<int> feld(xlarge*ylarge, 0);
fn(xlarge, ylarge, feld);
Zugriff waere bei beiden Faellen (position x1/y1): feld[ ylarge * x1 + y1 ] – EDIT: Ohne Gewaehr ☺
|
Hello_World
Anmeldungsdatum: 13. Juni 2006
Beiträge: Zähle...
|
oxe1976 schrieb: Wobei das dann auch wieder die gcc Erweiterung ist (siehe hier):
Die Relevanz dieses Links ist gleich null. Er bezieht sich auf gcc 2.95.3, welcher völlig veraltet ist und C99 noch nicht kennt. Wie gesagt ist dieses Feature in C99 enthalten, in C++ aber nicht. Besser waere soetwas:
void fn(unsigned xlarge, unsigned ylarge, int* feld);
...
int* feld = new int[xlarge*ylarge];
fn(xlarge, ylarge, feld);
delete [] feld;
Nein, das ist schlecht. fn kann eine Exception werfen, womit der Speicher verloren wäre. Noch besser waere (wie schon gesagt std::vector:
void fn(unsigned xlarge, unsigned ylarge, std::vector<int>& feld);
...
std::vector<int> feld(xlarge*ylarge, 0);
fn(xlarge, ylarge, feld);
Auch das ist nicht sinnvoll. Wenn er ein zweidimensionales Array will, dann soll er doch eines bekommen: vector<vector<int> > ist viel einfacher, als die Indizes von Hand auszurechnen. Außerdem ist es Exception-sicher.
|
oxe1976
Anmeldungsdatum: 5. Februar 2008
Beiträge: 759
|
Hello World schrieb: Nein, das ist schlecht. fn kann eine Exception werfen, womit der Speicher verloren wäre.
fn() kann auch ein exit machen, oder ...
Kein vollstaendiges Beispiel. Es geht halt darum das der Speicher dynamisch allokiert wird und nicht statisch vom Compiler.
Auch das ist nicht sinnvoll. Wenn er ein zweidimensionales Array will, dann soll er doch eines bekommen: vector<vector<int> > ist viel einfacher, als die Indizes von Hand auszurechnen.
Einfacherer Zugriff, gebe ich dir Recht. Aber meine Loesung hat performance/Speicher Vorteile ...
Außerdem ist es Exception-sicher.
Wieso?
|
phst
Anmeldungsdatum: 24. Juni 2007
Beiträge: 527
|
oxe1976 schrieb: Auch das ist nicht sinnvoll. Wenn er ein zweidimensionales Array will, dann soll er doch eines bekommen: vector<vector<int> > ist viel einfacher, als die Indizes von Hand auszurechnen.
Einfacherer Zugriff, gebe ich dir Recht. Aber meine Loesung hat performance/Speicher Vorteile ...
Das ist nicht so sehr vergleichbar, da es sich bei vector< vector<int> > eigentlich nicht um ein mehrdimensionales Feld, sondern um ein Feld von Feldern handelt.
Außerdem ist es Exception-sicher.
Wieso?
Weil der Destruktor der vector-Klasse auch beim Auftreten von Ausnahmen ausgeführt wird.
|
Marc_BlackJack_Rintsch
Ehemalige
Anmeldungsdatum: 16. Juni 2006
Beiträge: 4563
Wohnort: Berlin
|
@oxe1976: Wenn es um Performance geht wären Boost's multi_array s vielleicht einen Blick wert: http://www.boost.org/doc/libs/1_38_0/libs/multi_array/doc/user.html
|