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

1

17.07.2011, 14:55

Problem mit 2-Dimensionalen Array, Zeigerübergabe und Strukturen

Ich steh grad etwas aufm Schlauch. Egal was ich versuche, es funktioniert nicht ?( .

Ich möchte mittels einer Struktur ein Schachbrettartiges Feld erstellen.
Hier erstmal die Struktur:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
#include <iostream>

using namespace std;

struct S_Spielfeld
{
    bool besetzt;
    bool Farbe;
};


Als Instanz möchte ich ein einen 2-dimensionalen Array erstellen

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
#include "KlassenHeader.hpp"
#include "FunktionenHeader.hpp"

int main()
{   
    const int Höhe = 7;
    const int Breite = 7;
    S_Spielfeld *a_Spielfeld[Höhe] [Breite];

    SpielfeldBerechnen(Höhe,Breite,&a_Spielfeld);
    SpielfeldSchreiben(Höhe,Breite,&a_Spielfeld);
}


In zwei Funktionen wird einmal geguckt, welche Farbe das Feld hat, und dann das Feld geschrieben:

C-/C++-Quelltext

1
2
void SpielfeldBerechnen(const int Höhe,const int Breite,S_Spielfeld *a_Spielfeld[] []);
void SpielfeldSchreiben(const int Höhe,const int Breite,S_Spielfeld *a_Spielfeld[] []);


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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include "FunktionenHeader.hpp"
#include "KlassenHeader.hpp"

//SpielfeldBerechnen()
//
//Berchnet, ob ein Feld schwarz oder weiß ist
//
void SpielfeldBerechnen(const int Höhe,const int Breite,S_Spielfeld *a_Spielfeld[] [])
{   
    for (int x = 0; x <= Höhe; x++)
    {
        for (int y = 0; y <= Breite; y++)
        {
            if (x % 2 == 0 && y % 2 == 0)
            {
                *a_Spielfeld[x] [y].Farbe = true;
            }
            else if (x % 2 != 0 && y % 2 != 0)
            {
                *a_Spielfeld[x] [y].Farbe = true;
            }
            else
            {
                *a_Spielfeld[x] [y].Farbe = false;
            }
        }
    }
}
//SpielfeldBerechen()
//


//SpielfeldSchreiben()
//
//Schreibt das Spielfeld
//
void SpielfeldSchreiben(const int Höhe,const int Breite,S_Spielfeld *a_Spielfeld[] [])
{
    for (int x = 0; x <= Höhe; x++)
    {
        for (int y = 0; y <= Breite; y++)
        {
            if (*a_Spielfeld[x] [y].Farbe == false)
            {
                cout << "|||";
            }
            else
            {
                cout << "   ";
            }
        }
        cout << endl;
    }
}
//SpielfeldSchreiben()
//


Und nun weiß ich nicht, wie die Instanz richtig als Parameter übergebe.
Ob ich es nun so wie im Code mache oder die Größenangaben festlege, beides wird als Fehler markiert.
Auch bei weglassen der [] wird ein Fehler angezeigt.

Deklariere ich den Array global, funktioniert alles, jedoch möchte ich hierauf verzichten.
Wie muss ich nun einen mehrdimensionalen Array per Zeiger richtig übergeben?

Achja, ich habe <iostream> mal nur in der einen Headerdatei eingefüg, genauso wie den std namespace.
Ist das so in Ordnung oder sollte ich lieber jedesmal neu einfügen? :D

GR-PA

Treue Seele

Beiträge: 326

Wohnort: Daheim

Beruf: Faulenzer

  • Private Nachricht senden

2

17.07.2011, 15:16

http://www.cplusplus.com/doc/tutorial/arrays/

Zitat

Achja, ich habe <iostream> mal nur in der einen Headerdatei eingefüg, genauso wie den std namespace.
Ist das so in Ordnung oder sollte ich lieber jedesmal neu einfügen? :D

1) Siehe dazu: http://msdn.microsoft.com/en-us/library/…v=vs.71%29.aspx
2) du solltest using namespace meiden, dadurch wird der Sinn von namespaces zerstört (wenn dann nur einzelne Bestandteile also z.B. using std::cout;)
Signaturen werden überbewertet

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

3

17.07.2011, 15:35

Ein 2D Array mit der Höhe 3 und Breite 10 ist das gleiche wie ein normales Array mit der Größe 3*10.
Das

C-/C++-Quelltext

1
S_Spielfeld a_Spielfeld[Breite][Höhe];

ist also Äquivalent zu:

C-/C++-Quelltext

1
S_Spielfeld a_Spielfeld[Breite*Höhe];

Daraus folgt, dass du dir die Position im Array selbst berechnen kannst :D

C-/C++-Quelltext

1
S_Spielfeld a_Spielfeld[5][3];

ist also das gleiche wie

C-/C++-Quelltext

1
S_Spielfeld a_Spielfeld[5+3*Breite];

Das brauchst du weil du 2D Arrays nicht ohne weiteres so als Parameter übergeben kannst, dass du die Indexoperatoren wie gewohnt nutzen kannst.

Achja, man gibt in der Regel Breite(x Koordinaten) mal Höhe(y Koordinaten)(in dieser Reihenfolge an) und nicht Höhe mal Breite.
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

4

17.07.2011, 17:06

Zitat

Der Link ist aufjedenfall interessant :D .
Allerdings bin ich mir immer noch nicht sicher, was ich nun verwenden soll.

Zitat

using std::cout;
using std::cin;
using std::endl;
So wäre es besser? :)


Danke erstmal für die Hilfe mit den Arrays.
Jedoch gibt mir der Debugger jetzt nen Haufen Fehler aus, aus denen ich nicht schlau werde. 8|

Zitat

funktionenheader.hpp(1): error C2061: Syntaxfehler: Bezeichner 'S_Spielfeld'
funktionenheader.hpp(2): error C2061: Syntaxfehler: Bezeichner 'S_Spielfeld'
Das ist die Datei funktionenheader:

C-/C++-Quelltext

1
2
void SpielfeldBerechnen(const int Breite, const int Höhe, S_Spielfeld *a_Spielfeld[]);
void SpielfeldSchreiben(const int Breite, const int Höhe, S_Spielfeld *a_Spielfeld[]);


Und hier nochml die Struktur(natürlich auch in einer Headerdatei):

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>

using std::cout;
using std::cin;
using std::endl;

struct S_Spielfeld
{
    bool besetzt;
    bool Farbe;
};


Ich wollte mal mit mehreren Headerdateien experimentieren. Im Code wird kein Fehler angezeigt, trotzdem hab ich mal testweise per #include die Struktur-Datei in die Funktionen-Datei eingefügt, allerdings mit folgendem Ergebnis:

Zitat

klassenheader.hpp(8): error C2011: 'S_Spielfeld': 'struct' Typneudefinition
klassenheader.hpp(8): Siehe Deklaration von 'S_Spielfeld'
Was mache ich hier falsch?

Um Ordnung zu bewahren, schreib ich den Rest lieber später rein :whistling:

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

5

17.07.2011, 17:14

Zitat

funktionenheader.hpp(1): error C2061: Syntaxfehler: Bezeichner 'S_Spielfeld'

Das kommt wenn er der Kompiler S_Spielfeld nicht kennt. Du musst sie erstmal mit struct S_Spielfeld; deklarieren.

Zitat

klassenheader.hpp(8): error C2011: 'S_Spielfeld': 'struct' Typneudefinition

Schau dir mal Includeguards an. Das dürfte helfen :D

C-/C++-Quelltext

1
void SpielfeldBerechnen(const int Breite, const int Höhe, S_Spielfeld *a_Spielfeld[]);

hier ist entweder das * oder die [] zu viel.

C-/C++-Quelltext

1
void SpielfeldBerechnen(const int Breite, const int Höhe, S_Spielfeld a_Spielfeld[]);

So ists besser :thumbsup:

Achja, Umlaute im Quelltext sind ganz schlecht... solltest du vermeiden.(vielleicht gleich englische Bezeichner nehmen?)
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

6

17.07.2011, 18:13

pack dir dein 2dimensionales (oder auch noch mehr dimensional) einfach in ein struct und übergib das struct
oder noch besser, nimm std::vector<std::vector<int>>...

7

17.07.2011, 19:10

Zitat

Schau dir mal Includeguards an. Das dürfte helfen :D
Hat geholfen :D .

Zitat

hier ist entweder das * oder die [] zu viel.


C-/C++-Quelltext
1
void SpielfeldBerechnen(const int Breite, const int Höhe, S_Spielfeld a_Spielfeld[]);


So ists besser :thumbsup:
Funktioniert, allerdings kriege ich es nicht hin, das ganze als Zeiger zu übergeben, egal wie ich es schreibe.
Das spuckt die Debugkonsole aus:

Zitat

c:\users\**********\documents\visual studio 2010\projects\mein schach\mein schach\main.cpp(10): error C2664: 'SpielfeldBerechnen': Konvertierung des Parameters 3 von 'S_Spielfeld *(*)[49]' in 'S_Spielfeld *' nicht möglich
1> Die Typen, auf die verwiesen wird, sind nicht verknüpft; die Konvertierung erfordert einen reinterpret_cast-Operator oder eine Typumwandlung im C- oder Funktionsformat.

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
31
32
33
34
35
36
37
38
void SpielfeldBerechnen(const int Breite, const int Höhe, S_Spielfeld *a_Spielfeld);//aus der Headerdatei

///////////////////////////////////////////////////
void SpielfeldBerechnen(const int Breite,const int Höhe,S_Spielfeld *a_Spielfeld)//aus der Funktionen Quelldatei
{
for (int x = 0; x <= Breite; x++)
{
for (int y = 0; y <= Höhe; y++)
{
if (x % 2 == 0 && y % 2 == 0)
{
a_Spielfeld[x + y * Breite].Farbe = true;
}
else if (x % 2 != 0 && y % 2 != 0)
{
a_Spielfeld[x + y * Breite].Farbe = true;
}
else
{
a_Spielfeld[x + y * Breite].Farbe = false;
}
}
}
}

/////////////////////////////////
#include "KlassenHeader.hpp"//hier noc die maindatei
#include "FunktionenHeader.hpp"

int main()
{
const int Breite = 7;
const int Höhe = 7;
S_Spielfeld *a_Spielfeld[Breite * Höhe];

SpielfeldBerechnen(Breite, Höhe, &a_Spielfeld);
SpielfeldSchreiben(Breite, Höhe, &a_Spielfeld);
}


Aufjedenfall aber ein Dankeschön erstmal :D

Zitat

pack dir dein 2dimensionales (oder auch noch mehr dimensional) einfach in ein struct und übergib das struct
oder noch besser, nimm std::vector<std::vector<int>>...
Wusste garnicht, dass man auch ganze Strukturen übergeben kann :D .
Mit Vektoren hab ich noch nicht gearbeitet.
Aber ic werds mir für später merken :P .

Edit: Mir ist gerade aufgefallen, das ich den Zeiger garnicht mit 0 initialisiert habe.
Ehrlich gesagt bin ich grad am überlegen wie man das bei einem Array überhaupt macht 8| .

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Rexona for men« (17.07.2011, 19:20)


NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

8

17.07.2011, 19:19

C-/C++-Quelltext

1
2
3
S_Spielfeld a_Spielfeld[Breite * Höhe];

SpielfeldBerechnen(Breite, Höhe, a_Spielfeld);

Versuchs mal damit.
Dort übergibst du bereits einen Zeiger. Ein Array kann oft (d.h. nicht immer) wie ein Zeiger auf das erste Element behandelt werden. Mehr dazu kannst du in einem guten Nachschlagewerk nachlesen.

C-/C++-Quelltext

1
2
for (int x = 0; x <= Breite; x++)
for (int y = 0; y <= Höhe; y++)

Das ist ebenfalls falsch. Da gehört jeweils < hin sonst kriegst du eine Zugriffsverletzung. ;)
Präinkrement (++x) ist übrigens auch zu bevorzugen.
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

9

17.07.2011, 19:28

Zitat

Versuchs mal damit.
Dort übergibst du bereits einen Zeiger. Ein Array kann oft (d.h. nicht immer) wie ein Zeiger auf das erste Element behandelt werden. Mehr dazu kannst du in einem guten Nachschlagewerk nachlesen.
Nächste Frage: Was ist ein gutes Nachschlagwerk :D

Zitat

Das ist ebenfalls falsch. Da gehört jeweils < hin sonst kriegst du eine Zugriffsverletzung. ;)
Präinkrement (++x) ist übrigens auch zu bevorzugen.
Hat den letzten Fehler beseitigt.
Hätt ich als nächstes gefragt :P .

So, dann kann ich jetzt neue Fehlern erstell... äh weitermachen. :whistling:

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

10

17.07.2011, 19:39

Nächste Frage: Was ist ein gutes Nachschlagwerk :D

The C++ Programming Language ist wohl das beste.
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

Werbeanzeige