Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

CBenni::O

1x Contest-Sieger

Beiträge: 1 145

Wohnort: Stuttgart

  • Private Nachricht senden

11

06.12.2010, 15:53

[...] oder würdet ihr sagen ich soll direkt versuchen mit Vektoren zu arbeiten?

Eindeutig.
Und 2D-felder machen so gut wie nie Sinn, man kann genauso gut ein eindimensionales verwenden; das spart schleifen ohne ende:

pseudo-code:

C-/C++-Quelltext

1
2
3
4
5
6
7
int getFieldNum(int x,int y){return x+y*fieldSizeX;}
...
for(int i=0;i<(FieldSizeX*FieldSizeY);i++)
{
field[i]=0;
}
field[getFieldNum(1,3)]=37;

Ist meiner imho immer besser als Zweidimensionale Arrays/Vektoren, es sei denn, du willst die Größe des Felds in Echtzeit verändern.

mfg CBenni::O
Ein Mitglied der VEGeiCoUndGraSonMaWiGeS Bewegung.
42!
Aufräumen kann jeder, nur das Genie überblickt das Chaos!
Metal will never die!
1. Sppro Gamecontest - mein Beitrag

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

12

06.12.2010, 16:01

Schiffe versenken mit einem Vektor? Also DAS finde ich völlig danaben. Ein Vektor ist etwas dynamisches und völlig unnötig für das Problem. Der Array ist hier schon genau die richtige Wahl.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

13

06.12.2010, 16:03

Obwohl jetzt wohl auf dynamische Arrays gewechselt wurde, möchte ich noch gern einen Nachtrag zum ersten Problem machen. Dieses müsste sich (habs nicht getestet) lösen lassen, indem man die Größe eines Elementes des Arrays abfragt, was ja dann die Größe eines Arrays der zweiten Dimension wäre:

C-/C++-Quelltext

1
2
3
int arr[5][3]; 
cout << sizeof(arr)/sizeof(int); // 15 
cout << sizeof(arr[0])/sizeof(int); // gesucht! 3

CBenni::O

1x Contest-Sieger

Beiträge: 1 145

Wohnort: Stuttgart

  • Private Nachricht senden

14

06.12.2010, 17:34

ja, so kann das funktionieren, allerdings wird sizeof(var) im gegebsatz zu sizeof(typ) zur laufzeit ausgewertet (?), was man evtl vermeiden sollte ;)

EDIT: sry, hab da was falsch verstanden, wie es scheint...

mfg CBenni::O
Ein Mitglied der VEGeiCoUndGraSonMaWiGeS Bewegung.
42!
Aufräumen kann jeder, nur das Genie überblickt das Chaos!
Metal will never die!
1. Sppro Gamecontest - mein Beitrag

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

15

06.12.2010, 17:37

allerdings wird sizeof(var) (...) zur laufzeit ausgewertet

Nein, wird es nicht.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Werwofl

Treue Seele

  • »Werwofl« ist der Autor dieses Themas

Beiträge: 100

Beruf: Fachinformatiker für Anwendungsentwicklung

  • Private Nachricht senden

16

07.12.2010, 10:45

Schiffe versenken mit einem Vektor? Also DAS finde ich völlig danaben. Ein Vektor ist etwas dynamisches und völlig unnötig für das Problem. Der Array ist hier schon genau die richtige Wahl.
Aber was ist denn das Problem wenn ich es dynamisch anlege? Ich muss doch nur darauf achten dsas ich den Speicher wieder freigebe, also wieso ist das daneben?

Das ist von mir ja nur ein Programm um meine Programmierskills zu verbessern, also ausführliche Antworten finde ich immer gut :)

@CBenni::O: Ja stimmt ich könnte mir die Schleifen sparen aber mir fiel das im ersten moment leichter mit einem 2-Dimensionialen Array/Vektor zu arbeiten. Danke Für den Tipp ;)

GR-PA

Treue Seele

Beiträge: 326

Wohnort: Daheim

Beruf: Faulenzer

  • Private Nachricht senden

17

07.12.2010, 16:14

Einen vector fände ich hier schon in Ordnung. Ein vector ist eigentlich nur ein Array auf dem Heap mit einer guten Schnittstelle... Alternativ könnte man (wenn man unbedingt etwas statischeres haben will) auch ein valarray oder ein bitset verwenden. Letzteres naturlich nur für den Fall das ein Feld nur die Werte 1 und 0 annehmen kann.

Da du ausführliche Antworten möchstest hole ich dann mal weiter aus:
Echte mehrdimensionale Arrays gibt es nicht. Echte Mehrdimensionalität lässt sich nur mit den Standardcontainern (vector, list, etc.) erreichen.
Ein eindimensionales Array entspricht im Quellcode einem Zeiger, genauer: einem Zeiger auf das erste Element dieses Arrays. Der Operator [] lässt sich nämlich nicht nur auf Arrays anwenden, sondern auf jeden Zeiger.

C-/C++-Quelltext

1
2
3
4
5
6
int* ein_zeiger;
//...
// das
ein_zeiger[5] = 1234; 
// entspricht
*(ein_zeiger + 5) = 1234; // Dereferenziert den Zeiger auf einen Wert der um 5*sizeof(int) hinter "ein_zeiger" liegt (Google: Zeigerarithmetik)


Mehrdimensionale Arrays entsprechen im Speicher einem eindimensionalen Array. Folgendes 2D-Array:
1, 4, 6
11, 7, 2
3, 12, 8
5, 9, 0
Sieht im Speicher so aus: 1, 4, 6, 11, 7, 2, 3, 12, 8, 5, 9, 0
Es werden also die Zeilen hintereinandergereiht.
[3][1] entspricht also [3 * Spalten + 1] hier: [3][1] = [3 * 3 + 1] = [10] = 9

Im Quellcode sind zweidimensionale Arrays Arrays aus Arrays, weshalb sie vom Typ her einem Zeiger auf einen Zeiger ihres Types entsprechen. Hier fangen die Probleme an.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
int ein_feld[5][5];
ein_feld[1][2] = 0; // vollkommen ok: greift auf das 3. Element in der 2. Zeile zu

int** ein_doppelzeiger = ein_feld; // auch ok, ein_doppelzeiger zeigt jetzt ebenfalls auf einen Zeiger, der auf das erste Element zeigt
ein_doppelzeiger[1][2] = 0; // FEHLER! Dieser Code kann nicht funktionieren, weil der Compiler ja nicht wissen kann, welche Dimensionen das Feld hat, auf das ein_doppelzeiger zeigt
// müsste so aussehen:
(*ein_doppelzeiger) // dereferenziert Zeiger, jetzt hat man den Zeiger auf das erste Element
[1*5 + 2] // eigentlich ist es blos eindimensional
= 0;


Das ist das Problem bei mehrdimensionalen Feldern. Um diese z.B. an Funktionen übergeben zu können müssen die Dimensionen (mindestens alle bis auf die letzte) entweder von der Funktion festgeschreiben oder an sie übergeben werden. Beispiel:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
void ErsteFunktion(int feld[5][5])
{
    for (int row = 0; row < 5; ++row)
        for (int col = 0; col < 5; ++col)
            feld[row][col] = 0; // vollkommen ok
}

void ZweiteFunktion(int feld[5][])
{
    for (int row = 0; row < 5; ++row)
        for (int col = 0; col < 5; ++col)
            feld[row][col] = 0; // auch ok: die Größe der letzten Dimension wird nicht zum berechnen der Position benötigt
}

void DritteFunktion(int feld[][])
{
    for (int row = 0; row < 5; ++row)
        for (int col = 0; col < 5; ++col)
            feld[row][col] = 0; // macht nicht was man vllt. erwarten könnte, Dimensionen unbekannt => Index kann nicht berechnet werden
}

void VierteFunktion(int** feld, size_t num_cols)
{
    for (int row = 0; row < 5; ++row)
        for (int col = 0; col < 5; ++col)
        {
            feld[row][col] = 0; // klappt nicht
            feld[row * num_cols + col] = 0; // klappt und ist auch die einzige Möglichkeit
        }
}


Auf dem Heap können mehrdimensionale Arrays nur direkt in ihrer eindimensionalen Form, in der sie sowieso im Speicher liegen, erzeugt werden.

Ein mehrdimensionales Array ist also sehr umständlich zu handhaben, birgt viele Fehlerquellen und sorgt dafür, das der Code entweder unflexibel (Dimensionen fest vorgegeben) oder umständlicher (jede Funktion muss die Dimensionen mit übergeben bekommen) wird. Außerdem wird er auch auf jedem Fall schwerer nachvollziehbar und unübersichtlicher.

Mit einem vector könntest du dieses Problem sehr elegant umgehen. Ein vector<vector<int> > ist auch im Speicher zweidimensional. Der Overhead gegenüber einem Array (jeder vector im vector so wie der vector selbst speichert noch zusätzliche Dinge wie seine Größe) ist in deinem Fall vollkommen vernachlässigbar.
Dafür kannst du dann bequem mit Iteratoren arbeiten und hast vor allem echte Mehrdimensionalität!

Besonders "dynamisch" ist ein vector übrigens auch nicht. Intern ist er einfach nur ein Array auf'm Heap...

Es kann aber natürlich auch nicht schaden, zur Übung mit Arrays zu arbeiten. Im Gegenteil. Bei einem größerem Projekt würde ich dir allerdings dringend zu vector raten, außer wenn es sehr gute Gründe gibt Arrays zu verwenden. (z.B. Arbeiten über DLL-Grenzen hinaus, C-Bibliotheken, Speicher-overhead verringern, etc.)


PS: Ich hab mal wieder Langeweile xD
Signaturen werden überbewertet

Werbeanzeige