Array als Parameter in einer Funktion

Gast #1966780
Lesenswert?

Hi Leute!

Ich möchte eine Funktion schreiben, die mir ein Spielfeld initilisiert. 
Mein Code-Ausschnitt:
1
#include<iostream>
2
#include<math.h>
3
#include<time.h>
4
#include<stdlib.h>
5
using namespace std;
6

7
char InitialisiereSpielfeld(char Spielfeld[6][7])
8
{
9
  int i, j;
10
  for(i=0; i<6; i=i+1)
11
  {
12
    for(j=0; j<7; j=j+1)
13
    {
14
      Spielfeld[i][j] = 'X';
15
      return Spielfeld[i][j];
16
    }
17
  }
18
}
19

20

21

22
int main()
23
{
24
    //char Spielfeld[6][7];
25
    int steine=0;
26
   
27

28
    InitialisiereSpielfeld();

Das Problem dabei ist jetzt, dass mir der Compiler einen Fehler meldet. 
Ich weiß aber grad nicht woran das liegt. Das Spielfeld der Größe 6x7 
soll mit lauter X initialisiert werden. Visual Studio unterringelt mir 
die schließende Klammer am Funktionsaufruf. Ich weiß aber nicht was da 
jetzt falsch sein soll.

Könnt ihr mir helfen?
#1966787
Lesenswert?

Tobias Mehrl schrieb:
> Das Problem dabei ist jetzt, dass mir der Compiler einen Fehler meldet.

Du meinst, er sagt nichts weiter außer "Fehler", ohne Zeilennummer oder 
Fehlerbeschreibung?

> Visual Studio unterringelt mir die schließende Klammer am
> Funktionsaufruf. Ich weiß aber nicht was da jetzt falsch sein soll.

Naja, oben bei der Definition der Funktion InitialisiereSpielfeld hast 
du vorgegeben, daß man ihr ein Spielfeld zu übergeben hat, aber beim 
Aufruf übergibst du keins.
Gast #1966801
Lesenswert?

Wenn ich jetzt meinen Code so ändere,
1
#include<iostream>
2
#include<math.h>
3
#include<time.h>
4
#include<stdlib.h>
5
using namespace std;
6

7

8

9
char InitialisiereSpielfeld(char Spielfeld[6][7])
10
{
11
  int i, j;
12
  for(i=0; i<6; i=i+1)
13
  {
14
    for(j=0; j<7; j=j+1)
15
    {
16
      Spielfeld[i][j] = 'X';
17
      return Spielfeld[6][7];
18
    }
19
  }
20
}
21

22

23

24
int main()
25
{
26
    char Spielfeld[6][7];
27
    int steine=0;
28
   
29

30
    InitialisiereSpielfeld(Spielfeld[6][7]);

dann ändert das nix daran, dass das Argument des Funktionsaufrufes immer 
noch unterringelt wird... Sprich ich denk es ist soweit alles in Ordnung 
bis auf das Argument des Funktionsaufrufes. Die Fehlermeldung die mir VS 
mit diesem Code hier meldet ist Folgende:

"'InitialisiereSpielfeld': Konvertierung des Parameters 1 von 'char' in 
'char [][7]' nicht möglich"
Gast #1966802
Lesenswert?

>unterringelt
?!?

>"'InitialisiereSpielfeld': Konvertierung des Parameters 1 von 'char' in
>'char [][7]' nicht möglich"
Du brauchst ein C Buch. Spielfeld[6][7] ist ein char, deine Funktion 
erwartet ein Array.

Und was soll das return da?
Gast #1966805
Lesenswert?

return soll mein Rückgabewert sein.

Die Funktion erwartet doch nicht nur ein Array, sondern ihr wird doch 
jetzt auch ein array übergegeben, oder etwa nich?

Ich soll ein Array mit chars füllen, dann deklariere ich auch ein 
char-Array.
#1966828
Lesenswert?

Tobias Mehrl schrieb:
> return soll mein Rückgabewert sein.
>
> Die Funktion erwartet doch nicht nur ein Array, sondern ihr wird doch
> jetzt auch ein array übergegeben, oder etwa nich?

Nein
1
int main()
2
{
3
    char Spielfeld[6][7];

damit ist 'Spielfeld' das komplette 2D-Array, 'Spielfeld[2]' wäre eine 
Zeile aus dem Array und 'Spielfeld[6][7]' ein Element aus einer Zeile 
aus dem Array

Mal abgesehen davon, dass Spielfeld[6][7] nicht existiert.
Gast #1966832
Lesenswert?

Ich besorg mir das C-Buch. Brauch aber dennoch jetzt eure Hilfe. Ich hab 
jetzt meinen Code so verändert:

Ich hab jetz in den main-Teil noch eine Eingabe eingebaut. Diese gibt 
mir aber nicht das gewünschte Spielfeld aus... Was ist da jetzt noch 
falsch?
1
#include<iostream>
2
#include<math.h>
3
#include<time.h>
4
#include<stdlib.h>
5
using namespace std;
6

7

8

9
char InitialisiereSpielfeld(char Spielfeld[6][7])
10
{
11
  int i, j;
12
  for(i=0; i<6; i=i+1)
13
  {
14
    for(j=0; j<7; j=j+1)
15
    {
16
      Spielfeld[i][j] = 'X';
17
      return Spielfeld[6][7];
18
    }
19
  }
20
}
21

22

23

24
int main()
25
{
26
  char Spielfeld[6][7];
27
    int steine=0, i, j;
28
  char x;
29
   
30

31
    char InitialisiereSpielfeld(char Spielfeld[6][7]);
#1966853
Lesenswert?

Tobias Mehrl schrieb:

> Ich hab jetz in den main-Teil noch eine Eingabe eingebaut. Diese gibt
> mir aber nicht das gewünschte Spielfeld aus... Was ist da jetzt noch
> falsch?

Zum einen das hier
Beitrag "Re: Array als Parameter in einer Funktion"



Zum anderen

> char InitialisiereSpielfeld(char Spielfeld[6][7])
> {
>   int i, j;
>   for(i=0; i<6; i=i+1)
>   {
>     for(j=0; j<7; j=j+1)
>     {
>       Spielfeld[i][j] = 'X';
>       return Spielfeld[6][7];

was macht der return da mitten in der Schleife?
Gast #1966865
Lesenswert?

@kbuchegg: Das return da in der Mitte der Schleife hat nix verloren. hab 
ich schon rausgemacht. ich konnte es bloß nocht mehr editieren.

Ich finde es bloß komisch, wenn ihr alle von Zeigern sprecht, ich aber 
in der Hochschule noch nichts von Zeigern gehört habe. Obwohl wir 
offiziell darüber noch nichts gelernt haben, soll ich jetzt Zeiger 
verwenden können? Das ist schon ein wenig komisch, oder?
#1966869
Lesenswert?

Tobias Mehrl schrieb:

> Ich finde es bloß komisch, wenn ihr alle von Zeigern sprecht, ich aber
> in der Hochschule noch nichts von Zeigern gehört habe.

So wie du das hast, passt das schon.

> Obwohl wir
> offiziell darüber noch nichts gelernt haben, soll ich jetzt Zeiger
> verwenden können? Das ist schon ein wenig komisch, oder?

:-)
In Wirklichkeit verwendest du jetzt schon Zeiger, auch wenn du es noch 
nicht weißt. Die C-Syntax
1
void foo( char Argument[] )
2
{
3
  ...

ist nichts anderes als eine versteckte Zeigerdefinition.
Aber lass dich dadurch jetzt nicht verwirren.

Merken musst du dir nur, dass Arrays bei Funktionsaufrufen anders 
funktionieren als normale Variablen. Bei normalen Variablen wird eine 
Kopie an eine Funktion übergeben. Änderst du innerhalb der Funktion den 
Parameter
1
void foo( int  i )
2
{
3
  i = 5;
4
}
5

6
int main()
7
{
8
  int k = 8;
9
  foo( k );
10
}

so ändert sich dadurch nicht das Argument des Aufrufers. Die Zuweisung 
von 5 an i verändert k nicht.

Bei Arrays ist das anders. Die werden anders übergeben. Eine Veränderung 
des 'Arrays' in der Funktion, würde das Array des Aufrufers verändern.
Gast #1966878
Lesenswert?

@kbuchegg:

Du sagst also, dass das hier schon soweit richtig ist. Wenn ich mir nun 
aber die Ausgabe (ja ich weiß ich programmiere C und nicht C++...) 
anschaue, dann kommt da kein Array mit X raus sondern irgendwas...
1
#include<iostream>
2
#include<math.h>
3
#include<time.h>
4
#include<stdlib.h>
5
using namespace std;
6

7

8

9
char InitialisiereSpielfeld(char Spielfeld[6][7])
10
{
11
  int i, j;
12
  for(i=0; i<6; i=i+1)
13
  {
14
    for(j=0; j<7; j=j+1)
15
    {
16
      Spielfeld[i][j] = 'X';
17
      return Spielfeld[6][7];
18
    }
19
  }
20
}
21

22

23

24
int main()
25
{
26
  char Spielfeld[6][7];
27
    int steine=0, i, j;
28
   
29

30
    char InitialisiereSpielfeld(char Spielfeld[6][7]);
31

32

33

34
  for(i=0; i<6; i=i+1)
35
  {
36
    for(j=0; j<7; j=j+1)
37
    {
38
      cout << Spielfeld[i][j];
39
    }
40
  }
41

42

43

44

45

46

47

48

49

50

51

52

53

54

55
 
56

57

58
    system("PAUSE");
59
    return 0;
60
}
#1966882
Lesenswert?

Tim T. schrieb:
> Ich wundere mich wieder mal, mit welcher Gelassenheit du Sachen erklärst
> die in jedem C-Buch stehen...

Einen gewissen Bonus kriegt jeder.
Ausserdem hat er sich bei seiner letzten Hausübung gar nicht dumm 
angestellt und sie eigentlich ganz gut und vor allen Dingen mit ein 
bischen Hilfestellung alleine gemeistert :-)

Einen Blackout kann jeder mal haben und gerade Arrays sind in C so eine 
Sache :-)

@Tobias
Das ist allerdings keine Entschuldigung dafür, kein Buch zu haben!
Du WIRST eines brauchen! Ich denke du merkst mitlerweile selber schon, 
dass es in C eine Menge Stolpersteine und Fallstricke gibt. Ohne 
systematischen Aufbau durch zb ein Buch, wird das nichts.
#1966890
Lesenswert?

Sag mal
1
int main()
2
{
3
  char Spielfeld[6][7];
4
    int steine=0, i, j;
5
   
6

7
    char InitialisiereSpielfeld(char Spielfeld[6][7]);

warum red ich mir eigentlich den Mund fusselig, wenn du dann nicht 
darauf reagierst?

Lies es von meinen Lippen ab

*   Das IST  kein Funktionsaufruf!
    Das ist ein Protoyp einer Funktion

*   Beim Aufruf einer Funktion gibt man nicht an, welches der
     Returntyp der Funktion ist

*  Man gibt auch nicht an, welches die Datentypen der Argumente sind.
   Wozu auch. Die Funktion ist ja bekannt und was auch immer man an
   eine Funktion übergeben will ... ich kenn doch den Datentyp
   der Variablen

*  und schon gar nicht gibt man ein einzelnes Element eines Arrays an
   wenn die Funktion das ganze Array haben will
1
    InitialisiereSpielfeld( Spielfeld );

oder hast du etwa strcpy so benutzt
1
int main()
2
{
3
  char Text[] = "Hallo world";
4
  char Kopie[20];
5

6
  char* strcpy( char Kopie[20], char Text[]);
7
}

nein, das hast du nicht. Du hast es so benutzt
1
int main()
2
{
3
  char Text[] = "Hallo world";
4
  char Kopie[20];
5

6
  strcpy( Kopie, Text );
7
}

völlig analog!
#1966906
Lesenswert?

Und das return
1
char InitialisiereSpielfeld(char Spielfeld[6][7])
2
{
3
  int i, j;
4
  for(i=0; i<6; i=i+1)
5
  {
6
    for(j=0; j<7; j=j+1)
7
    {
8
      Spielfeld[i][j] = 'X';
9
      return Spielfeld[6][7];
10
    }
11
  }
12
}

mitten in den Schleifen ist immer noch drinnen obwohl du vorher schon 
die Zusicherung gemacht hast, dass du es da entfernt hättest.
Gast #1966910
Lesenswert?

Karl heinz Buchegger schrieb:

> Wenn er das bei mir machen würde (global), würde ich das Programm
> ausdrucken und ihm den Ausdruck so lange um die Ohren hauen, bis nur
> noch Konfetti vorhanden ist :-)

Hatte auch schon solche Leute in der Übung sitzen, sobald die gemerkt 
haben das man globale Variablen benutzen kann, wurde fast nix mehr 
übergeben. War halt die Anweisung das es trotzdem die Punkte gab wenn 
das Programm die gewünsche Ausgabe hatte. Wo sowas hinführt ist eine 
andere Geschichte...
Gast #1966915
Lesenswert?

1
char InitialisiereSpielfeld(char Spielfeld[6][7])
2
{
3
  int i, j;
4
  for(i=0; i<6; i=i+1)
5
  {
6
    for(j=0; j<7; j=j+1)
7
    {
8
      Spielfeld[i][j] = 'X';
9
    }
10
  }
11
}
12

13

14

15
int main()
16
{
17
    char Spielfeld[6][7];
18
    int steine=0;
19
 
20
    InitialisiereSpielfeld(Spielfeld);
21
}
Gast #1966923
Lesenswert?

@Hans
Nehm es mir nicht übel, aber was soll das? Warum sollten die 
Schüler/Studenten denn ihre Aufgaben selber machen wenn sie hier (evn. 
nach etwas Meckerei) grundsätzlich eine fertige Lösung präsentiert 
bekommen?
Gast #1966959
Lesenswert?

Da es jetzt eh raus ist:
1
#include <iostream>
2

3
using namespace std;
4

5
const unsigned int x_max = 7;
6
const unsigned int y_max = 6;
7

8
void Spielfeld_Ausgabe( char ( *Spielfeld )[ x_max ] ) {
9

10
 unsigned int x, y;
11

12
 for( y = 0; y < y_max; y++ ) {
13
  for( x = 0; x < x_max; x++ ) 
14
   cout << Spielfeld[ y ][ x ];
15
  cout << endl;
16
 };
17
}
18

19
void Spielfeld_Init( char Spielfeld[ ][ x_max ] ) {
20

21
 unsigned int x, y;
22

23
 for( y = 0; y < y_max; y++ )
24
  for( x = 0; x < x_max; x++ ) 
25
   Spielfeld[ y ][ x ] = 'X';
26
}
27

28
int main( void ) {
29

30
 char Spielfeld[ y_max ][ x_max ];
31
 //unsigned int steine = 0;
32

33
 Spielfeld_Init( Spielfeld );
34
 Spielfeld_Ausgabe( Spielfeld );
35

36
 getchar();
37

38
 return 0;
39
}

Zumindest sollte das eine Frage aufwerfen, deren Antwort einen gewissen 
Lerneffekt beinhaltet...
Gast #1967177
Lesenswert?

Wenns denn sein muss:
1
--- C++
2
+++ C
3

4
- #include <iostream>
5
+ #include <stdio.h>
6

7
- using namespace std;
8

9
-   cout << Spielfeld[ y ][ x ];
10
-  cout << endl;
11
+   printf( "%c", Spielfeld[ y ][ x ] );
12
+  printf( "\n" );
Gast #1968349
Lesenswert?

Hey Leute!

Ich denke ich hab mein Problem, dass ihr hier alle so breittretet, 
alleine gelöst. Das war gestern ein Teilproblem bei der Programmierung 
einer Art 4-Gewinnt-Spiel. Hier ist mein alter Code und auch ein paar 
neue Teile zu denen ich gleich noch Fragen stellen werde.
1
#include<iostream>
2
#include<math.h>
3
#include<time.h>
4
#include<stdlib.h>
5
using namespace std;
6

7

8

9
//Funktion "InitilisiereSpielfeld"
10
char InitialisiereSpielfeld(char Spielfeld[7][7])
11
{
12
  int i, j;
13
  for(i=0; i<7; i=i+1)
14
  {
15
    for(j=0; j<7; j=j+1)
16
    {
17
      Spielfeld[i][j] = ' ';      //Spielfeld mit 'X' füllen
18
    }
19
  }
20

21
  for(i=0; i<1; i=i+1)
22
  {
23
    int k = 49;
24
    for(j=0; j<7; j=j+1)
25
    {
26
      Spielfeld[i][j] = k;
27
      k = k + 1;
28
    }
29
  }
30
  return Spielfeld[7][7];
31
}
32

33

34
//Funktion "Drucke Spielfeld"
35
char DruckeSpielfeld(char Spielfeld[7][7])
36
{
37
  int i, j;
38
  for(i=0; i<7; i=i+1)
39
  {
40
    cout << endl;
41
    for(j=0; j<7; j=j+1)
42
    {
43
      cout << Spielfeld[i][j];    //Spielfeld auf Bildschirm ausgebn
44
    }
45
  }
46
  return Spielfeld[7][7];
47
}
48

49

50
//Funktion "Setze Stein"
51
char SetzeStein(char Spielfeld[7][7], int spalte)
52
{
53
  Spielfeld[7][spalte] = 'X';
54
  return Spielfeld[7][7];
55
}
56

57

58

59
int main()
60
{
61
  char Spielfeld[7][7];
62
    int steine=0, spalte=0;
63

64
  InitialisiereSpielfeld(Spielfeld);
65
  DruckeSpielfeld(Spielfeld);
66

67

68
  cout << endl << "Spieler 1 bitte Spaltennummer eingeben: ";
69
  cin >> spalte;
70
  spalte = spalte - 1;
71

72
  SetzeStein(Spielfeld, spalte);
73
  DruckeSpielfeld(Spielfeld);
74

75

76
    system("PAUSE");
77
    return 0;
78
}

Ich hab hier quasi ein Spielfeld mit einer Spaltenzeile sowie dem 
eigentlichen Spielfeld von einer Größe von 6 Zeilen/7 Spalten 
programmiert. Nun hab ich mit der ersten Benutzerfrage nach der Spalte 
gefragt in dem der erste Stein (ein 'X') gesetzt werden soll. Dieser 
Stein soll ja nun in das Spielfeld eingesetzt werden. Und genau hier hab 
ich jetzt Probleme. Ich rufe die Funktion SetzeStein auf und versuche in 
Abhängigkeit von "spalte" den Stein in die unterste Zeile in die Spalte 
"spalte" zu setzen. Wenn ich den Code durchkompiliere, dann gibt er mir 
zwar zum zweiten mal ein Spielfeld aus aber ohne dem Stein 'X' an der 
erwarteten Stelle.

Ich weiß hier wieder mal nicht weiter. Könnt ihr mir ein paar Anstöße 
geben?

PS: Ich weiß nicht aber ich denke ich bin hier teilweise zu Unrecht 
verurteil worden, dass ich von irgendjemanden verlange mir meine 
Hausaufgabe zu machen. Ich frag vielleicht manchmal blöde, aber das 
sollte nicht der Grund sein hier auf mich teilweise doch recht 
"aggressiv" loszugehen. Gottseidank sind nicht alle User hier so...

Ich danke euch trotzdem schon mal für eure weitere Hilfe!

Edit: Dass ich cout benutze und die iostream eingebunden habe liegt 
einfach daran, dass sich ein cout einfacher und schneller schreiben 
lässt. Ich weiß, das ist schlechter / falscher Stil, aber sogar unser 
Lehrer macht es / hat es erlaubt...
Gast #1968367
Lesenswert?

Sorry, Leute!

Ich hab mich mit dem index der 1. dim. vertan.
1
//Funktion "Setze Stein"
2
char SetzeStein(char Spielfeld[7][7], int spalte)
3
{
4
  Spielfeld[7][spalte] = 'X';
5
  return Spielfeld[7][7];
6
}

Eine weitere Frage kommt aber sogleich:

Wie bringe ich dem Programm nun jetzt bei, dass der Stein des Spieler 2 
(der Stein von Spieler 2 ist ein "O") falls dieser auch die 1. Spalte 
wählt, über dem Stein des ersten Spielers zu liegen kommt?
#1968460
Lesenswert?

Du musst noch etwas verinnerlichen

Definierst du ein Array

char irgendwas[6];

so hat dieses Array 6 Einträge

irgendwas[0]
irgendwas[1]
irgendwas[2]
irgendwas[3]
irgendwas[4]
irgendwas[5]

zähl nach, das sind genau 6 Einträge.
Ein irgendwas[6] existiert nicht! Der höchste zulässige Index ist immer 
um 1 kleiner als die Zahl, die bei der Arraydefinition steht. Und ja, es 
ist ein schwerer Fehler darauf zugreifen zu wollen. Und ja, das gilt, 
egal wieviele Dimensionen ein Array hat.

In diesem Sinne
1
char InitialisiereSpielfeld(char Spielfeld[7][7])
2
{
3
  ....
4

5
  return Spielfeld[7][7];
6
}
7

8
char SetzeStein(char Spielfeld[7][7], int spalte)
9
{
10
  Spielfeld[7][spalte] = 'X';
11
  return Spielfeld[7][7];
12
}

Das sind alles No-No's

PS: wozu returnierst du in beiden Funktionen überhaupt etwas? Es gibt da 
nichts wirklich Sinnvolles, was man returnen könnte. Und das schreiben 
von 'X' an Spielfeld[7][.... geht natürlich gar nicht.
#1968469
Lesenswert?

Tobias Mehrl schrieb:

> Wie bringe ich dem Programm nun jetzt bei, dass der Stein des Spieler 2
> (der Stein von Spieler 2 ist ein "O") falls dieser auch die 1. Spalte
> wählt, über dem Stein des ersten Spielers zu liegen kommt?

Wie würdest du es denn mit der Hand machen, wenn dein Spielfeld ein 
karriertes Blatt Papier wäre?
Also ich würde in der angegebenen Spalte in der untersten Zeile anfangen 
und solange ein Feld nach oben gehen, solange bis ich auf ein freies 
Feld stosse. Dort kann dann der Stein abgelegt werden.
Oder du machst es genaqu anders rum, so wie es auch die Natur macht. Du 
fängst in der bewussten Spalte oben an und gehs Zeile für Zeile nach 
unten durch, bis du auf eine Zeile stößt in der schon ein Stein liegt 
oder du ganz unten angekommen bist. In der Zeile darüber bleibt dann der 
Stein liegen.

Einfach mal beobachten, wie das in der Natur funktioniert bzw. wie man 
selber das mit Papier und Bleistift machen würde. Aber genau beobachten, 
jedes Detail ist wichtig!
Gast #1968470
Lesenswert?

"Ein irgendwas[6] existiert nicht! Und ja, es ist ein schwerer Fehler
darauf zugreifen zu wollen."

Ich weiß, dass das nicht geht und auch gar keinen Sinn macht, denn im 
Speicher steht an dieser Stelle irgendwas aber bestimmt nicht das was 
man haben will. Ich weiß aber auch nicht, wo ich diesen Fehler gemacht 
haben soll...


"Und das schreiben von 'X' an Spielfeld[7][.... geht natürlich gar 
nicht."

Das war für mich eine einfache und anscheinend aber auch funktionierende 
Möglichkeit. Wie soll ich es besser machen?
#1968485
Lesenswert?

Tobias Mehrl schrieb:

> Ich weiß, dass das nicht geht

Warum machst du es dann?

> und auch gar keinen Sinn macht, denn im
> Speicher steht an dieser Stelle irgendwas aber bestimmt nicht das was
> man haben will. Ich weiß aber auch nicht, wo ich diesen Fehler gemacht
> haben soll...

zb hier

char InitialisiereSpielfeld(char Spielfeld[7][7])
{
  ....

  return Spielfeld[7][7];    <--------------
}

Es gibt in Spielfeld kein Element mit den Indizes [7][7] !
[6][6] ist das Maximum.

> "Und das schreiben von 'X' an Spielfeld[7][.... geht natürlich gar
> nicht."
>
> Das war für mich eine einfache und anscheinend aber auch funktionierende
> Möglichkeit.

So?
Tut es das wirklich?
Warum wohl taucht das X in deiner Ausgabe nicht auf?

> Wie soll ich es besser machen?

Indem du nicht auf Array Elemente zugreifst die nicht existieren!

Mal es dir auf

     0   1   2   3   4   5   6
   +---+---+---+---+---+---+---+
 0 |   |   |   |   |   |   |   |
   +---+---+---+---+---+---+---+
 1 |   |   |   |   |   |   |   |
   +---+---+---+---+---+---+---+
 2 |   |   |   |   |   |   |   |
   +---+---+---+---+---+---+---+
 3 |   |   |   |   |   |   |   |
   +---+---+---+---+---+---+---+
 4 |   |   |   |   |   |   |   |
   +---+---+---+---+---+---+---+
 5 |   |   |   |   |   |   |   |
   +---+---+---+---+---+---+---+
 6 |   |   |   |   |   |   |   |
   +---+---+---+---+---+---+---+

Das sind 7 Zeilen und 7 SPalten.
Wo genau soll da jetzt das Element [7][0] oder [7][1] oder 
[7][irgendwas] sein?
Die letzte Zeile/Spalte ist die mit dem Index 6 und nicht 7.
Gast #1968692
Lesenswert?

Warum nur, warum schaust du dir die Lösungen die bislang gepostet wurden 
nicht genau an???
Wenn du auch nur halbwegs anstalten gemacht hättest dir diese 
anzuschauen, wäre dir aufgefallen das keine meiner beiden Funktionen 
einen Rückgabewert hat. Aber anstatt das du dich fragst warum es 
trotzdem geht, fängst du wieder an chars zurückzugeben und das auch noch 
falsch.

Sorry aber bis du bewiesen hast nicht lernresistent zu sein, klink ich 
mich aus.
Gast #1970019
Lesenswert?

So, also nochmal von vorne:

Mein neuer Code:
1
#include<iostream>
2
using namespace std;
3

4

5
//Funktion "Initialisiere Spielfeld"
6
void InitialisiereSpielfeld(char Spielfeld[6][6])
7
{
8
  for(int i=0; i<7; i=i+1)
9
  {
10
    for(int j=0; j<7; j=j+1)
11
    {
12
      Spielfeld[i][j] = '+';
13
    }
14
  }
15
}
16

17

18
//Funktion "DruckSpielfeld"
19
void DruckeSpielfeld(char Spielfeld[6][6])
20
{
21
  for(int i=0; i<7; i=i+1)
22
  {
23
    cout << endl;
24
    for(int j=0; j<7; j=j+1)
25
    {
26
      cout << Spielfeld[i][j];
27
    }
28
  }
29
}
30

31

32

33

34
int main()
35
{
36
  char Spielfeld[6][6];
37

38
  InitialisiereSpielfeld(Spielfeld);
39
  DruckeSpielfeld(Spielfeld);
40

41

42

43
system("pause");
44
return 0;
45
}

Ich denke die Sache mit den Arraydefinitionen hab ich verstanden. Wenn 
ich nun dieses Programm ausführe und mit einem Druck auf Enter beenden 
möchte, dann meldet VS2010 diesen Fehler: Run-Time Failure #2 - Stack 
around the variable spielfeld was corrupted.

Ich weiß nicht wo der Fehler sein soll...
Gast #1970029
Lesenswert?

Ich will doch ein 7x7 Feld.

Das gibt's doch nicht. Ich hab doch die Vorlesung hier vorliegen. Bei 
der Definition des Arrays muss ich für ein 7x7 Feld schreiben:

char Spielfeld[7][7];

Wenn ich auf die Elemente zugreifen will, ist schon klar, dass das 
Elemten 7 nicht vorhanden ist, weils eine 7 nicht gibt...
Gast #1970033
Lesenswert?

Blöderweise gehts nämlich jetzt so. Wenn ich mir Debugger die Arraygröße 
anschaue, ist auf einmal auch 0-6 drin. Ich weiß nicht wer da jetzt grad 
recht hat...
1
#include<iostream>
2
using namespace std;
3

4

5
//Funktion "Initialisiere Spielfeld"
6
void InitialisiereSpielfeld(char Spielfeld[7][7])
7
{
8
  for(int i=0; i<7; i=i+1)
9
  {
10
    for(int j=0; j<7; j=j+1)
11
    {
12
      Spielfeld[i][j] = '+';
13
    }
14
  }
15
}
16

17

18
//Funktion "DruckSpielfeld"
19
void DruckeSpielfeld(char Spielfeld[7][7])
20
{
21
  for(int i=0; i<7; i=i+1)
22
  {
23
    cout << endl;
24
    for(int j=0; j<7; j=j+1)
25
    {
26
      cout << Spielfeld[i][j];
27
    }
28
  }
29
}
30

31

32

33

34
int main()
35
{
36
  char Spielfeld[7][7];
37

38

39

40
  InitialisiereSpielfeld(Spielfeld);
41
  DruckeSpielfeld(Spielfeld);
42

43

44

45
return 0;
46
}
Gast #1970039
Lesenswert?

Wenn es immer schlimmer wird, dann zeig mal mit dem Finger drauf und sag 
mir was falsch ist und wie ich es anders machen soll. Ganz explizit. 
Also, natürlich wenn du noch willst. Wenn nicht isses auch in Ordnung.
Gast #1970052
Lesenswert?

Du definierst erst ein 6x6 Feld, in der for-Schleife steht aber i<7. Das 
gibt 0 1 2 3 4 5 6 <--Problem!

Danach änderst du die Definition und wunderst dich das es dann 
funktioniert. Ich hab das Gefühl du gehst völlig planlos vor und hast 
keine Ahnung was du da überhaupt tust geschweige denn warum oder wie es 
funktioniert.

>Blöderweise gehts nämlich jetzt so. Wenn ich mir Debugger die Arraygröße
>anschaue, ist auf einmal auch 0-6 drin.
Das ist doch völlig logisch! char Spielfeld[7][7] definiert ein Array 
mit 7x7 Feldern, die Indexes gehen also von 0 bis 6.
Gast #1970056
Lesenswert?

Au mann, auch wenn ich mich raushalten wollte, ich schaffs einfach 
nicht:

Hier definierst du ein 6*6 Feld:
1
int main()
2
{
3
  char Spielfeld[6][6]; <--- GENAU DA TUST DU ES!
4

5
  InitialisiereSpielfeld(Spielfeld);
6
  DruckeSpielfeld(Spielfeld);
7

8

9

10
system("pause");
11
return 0;
12
}

Welches du auch sauber übergibst:
1
void InitialisiereSpielfeld(char Spielfeld[6][6]) <--- DA!

Nur dann greifst du wieder auf ein 7*7 Feld zu:
1
  for(int i=0; i<7; i=i+1) <--- HIER!  
2
  {
3
    for(int j=0; j<7; j=j+1) <--- UND HIER AUCH!
4
    {
5
      Spielfeld[i][j] = '+';
6
    }
7
  }


Kerl, ein 6*6 Feld hat jeweils pro Dimension die Indizes 0-5, also geht 
eine Abfrage <7 zwangsläufig in die Hose, da es Spielfeld[6][6] in einem 
6*6 Feld nicht gibt! Es gibt nur Spielfeld[0][0] bis Spielfeld[5][5] und 
0 bis 5 sind eben die 6 Felder.
Ist es wirklich so schwer zu verstehen das bei einer Zählweise ab 0 das 
Feld 5 das 6. ist?
Gast #1970058
Lesenswert?

Auf ein neues:

Hier mein Code:
1
#include<iostream>
2
using namespace std;
3

4

5
//Funktion "Initialisiere Spielfeld"
6
void InitialisiereSpielfeld(char Spielfeld[7][7])
7
{
8
  for(int i=0; i<7; i=i+1)
9
  {
10
    for(int j=0; j<7; j=j+1)
11
    {
12
      Spielfeld[i][j] = '+';
13
    }
14
  }
15

16
  for(int i=0; i<1; i=i+1)
17
  {
18
    int k = 49;
19
    for(int j=0; j<7; j=j+1)
20
    {
21
      Spielfeld[i][j] = k;
22
      k = k + 1;
23
    }
24
  }
25
}
26

27

28

29
//Funktion "DruckeSpielfeld"
30
void DruckeSpielfeld(char Spielfeld[7][7])
31
{
32
  for(int i=0; i<7; i=i+1)
33
  {
34
    cout << endl;
35
    for(int j=0; j<7; j=j+1)
36
    {
37
      cout << Spielfeld[i][j];
38
    }
39
  }
40
}
41

42

43

44
//Funktion BenutzerEingabe
45
int BenutzerEingabe(int Spalte)
46
{
47
  cout << endl << "Spieler 1, bitte gewaehlte Spalte eingeben: ";
48
  cin >> Spalte;
49

50
  return Spalte;
51
}
52

53

54

55
int main()
56
{
57
  char Spielfeld[7][7];
58
  int Spalte = 0;
59

60

61

62
  InitialisiereSpielfeld(Spielfeld);
63
  DruckeSpielfeld(Spielfeld);
64

65
  Spalte = BenutzerEingabe(Spalte);
66

67

68
return 0;
69
}

Stimmts etz?
Gast #1970073
Lesenswert?

Tobias Mehrl schrieb:
> Auf ein neues:
>
> Hier mein Code:
>
1
 //Funktion "Initialisiere Spielfeld"
2
 void InitialisiereSpielfeld(char Spielfeld[7][7])
3
 {
4
   for(int i=0; i<7; i=i+1)
5
   {
6
     for(int j=0; j<7; j=j+1)
7
     {
8
       Spielfeld[i][j] = '+';
9
     }
10
   }
11
 
12
   for(int i=0; i<1; i=i+1)
13
   {
14
     int k = 49;
15
     for(int j=0; j<7; j=j+1)
16
     {
17
       Spielfeld[i][j] = k;
18
       k = k + 1;
19
     }
20
   }
21
 }
Was soll den das schon wieder? Erst ein '+' in alle Felder schreiben und 
direkt danach eine Zahl?!? Und dann die Variable auch noch mitten in der 
Schleife deklariert.

>int k = 49;
Was willst du damit (= 49) bezwecken? Ich bin mir ziemlich sicher du 
hast da (wiedermal) was nicht verstanden. (Syntax ist richtig, aber ich 
habe da eine böse Vermutung.)

@Tim T.
>Au mann, auch wenn ich mich raushalten wollte, ich schaffs einfach
>nicht:
Das dürfte einigen so gehen...

Im Übrigen... Ich finde es ziemlich mutig solche - Verzeihung - 
Armutszeugnisse unter realem Namen zu posten. Wenn ich ein potentieller 
Arbeitgeber wäre würde ich es mir bestimmt dreimal überlegen dich 
einzustellen. Nicht das du nicht programmieren kannst, da hat ja jeder 
mal klein angefangen, aber du gehst völlig planlos vor und erwartest das 
andere die alles erklären anstatt dich selbst einzuarbeiten. Das du das 
in der Schule/Uni vermutlich gelernt haben solltest will ich gar nicht 
erst erwähnen...
#1970105
Lesenswert?

Tobias Mehrl schrieb:
> Auf ein neues:

Array mässig war deine letzte Variante richtig.

Du musst endlich anfangen zu untzerscheiden zwischen den Angaben

* wenn du ein Array definierst oder deklarierst
  Dort gibst du die ANZAHL der Elemente an, denn dort musst du
  beschreiben, wie etwas aussieht

  Defintionen sind zb hier

    char Spielfeld[7][7];        <--- Definition
  und hier
    void InitialisiereSpielfeld(char Spielfeld[7][7])  <--- Deklaration

  hier stehen die 7 für die Anzahl. Insbesondere letzters hättest
  du nämlich auch schreiben können als

    void InitialisiereSpielfeld(char Spielfeld[][7])

  weil der Compiler die erste Dimension nicht braucht um einen
  Zugriff auf das richtige Array Element zu lenken.

  Der Compiler will an diesen Stellen nur wissen, wie etwas aussieht.
  In deinem Fall, wie das Array aussieht.

* und den tatsächlichen Zugriffen selber
  wie zb hier

    Spielfeld[i][j] = '+';     <---  das ist etwas völlig anderes.
                                     Hier geht es nicht mehr um das
                                     Array als ganzes. Hier geht es
                                     darum 1 Element aus dem Array
                                     auszuwählen und damit etwas zu tun!

  oder

    Spielfed[6][5] = 'X';

  Bei den Zugriffen laufen die gültigen Indizes von 0 bis zur Anzahl
  der Elemente - 1 (weil bei 0 zu zählen angefangen wird).


Also trennen zwischen:

  Definition/Deklaration        ->  Anzahl der Elemente
  Verwendung bzw Zugriff auf
  ein Element des Arrays        -> Index


Genau das versuche ich dir schon seit einiger Zeit zu verklickern, wenn 
ich dir wieder und immer wieder sage, dass es in einem Array

   int   b[3];

die Elemente

   b[0], b[1], b[2]

gibt und du nachzählen sollst um dich davon zu überzeugen, dass das 
wirklich so ist!
Das sind 3 Elemente im Array, auch wenn der höchste zulässige Index 
genau um 1 kleiner ist als diese Anzahl!
Und ja, das gilt in allen Dimension, egal wieviele Dimensionen das Array 
hat.
Ein Array

   int irgendwas[3][4]

hat die Elemente

    [0][0]  [0][1]  [0][2]   [0][3]
    [1][0]  [1][1]  [1][2]   [1][3]
    [2][0]  [2][1]  [2][2]   [2][3]

sind genau 4 Spalten und 3 Zeilen, so wie es bei der Definition 
gefordert wurde. Und genau aus dem Grund ist der höchste zulässige 
Spaltenindex die 3 und der höchste zulässige Zeilenindex die 2 wenn auf 
Elemente des Arrays zugegriffen werden soll.
Gast #1970109
Lesenswert?

abc schrieb:

> Im Übrigen... Ich finde es ziemlich mutig solche - Verzeihung -
> Armutszeugnisse unter realem Namen zu posten. Wenn ich ein potentieller
> Arbeitgeber wäre würde ich es mir bestimmt dreimal überlegen dich
> einzustellen. Nicht das du nicht programmieren kannst, da hat ja jeder
> mal klein angefangen, aber du gehst völlig planlos vor und erwartest das
> andere die alles erklären anstatt dich selbst einzuarbeiten. Das du das
> in der Schule/Uni vermutlich gelernt haben solltest will ich gar nicht
> erst erwähnen...

Noch mutiger wird es, wenn man durch Assoziazion seines Nicknames 
(bandchef) und einer Suche seines Namens bei Google auf der ersten Seite 
etwas findet das zu einem Impressum mit Anschrift und Telefonnummer 
passt...
Gast #1970209
Lesenswert?

@Tim T.
Google macht automatisch Mehl aus dem Nachnahmen, die Planzenseite passt 
z.B. nicht. Es lässt sich aber trotzdem was finden... (Keine Details, 
jeder hat ein Recht auf Privatsphäre und ich möchte meine Adresse ja 
auch nicht im Netz finden!)
Gast #1975845
Lesenswert?

Ich hab jetzt mein bisher leider noch unvollständiges Programm 
zurückgestellt. Es funktioniert jetzt soweit, dass man mit 2 Spieler 
spielen kann. es wird als siegbedingung aber leider nur die vertikale 
anordnung der Spielsteine ausgewertet. Wen's interessiert: Im Anhang ist 
der gesamte Quellcode. Anhang deswegen, weil ziemlich viel Quellcode.

Die Namen-Geschichte is natürlich sehr brisant. Wie kann ich meinen 
gesamten Namen aus meinem Profil verschwinden lassen? Geht das 
überhaupt?
Angehängte Dateien:
Gast #1975868
Lesenswert?

Quellcode bitte als .c, sonst funktioniert die Syntaxhervorhebung nicht!

>int k = 49;
steht immer noch mitten in einer Schleife. Und warum zum Teufel =49?

In InitialisiereSpielfeld ist die erste Hälfte überflüssig, die '+' 
werden alle im zweiten Teil überschrieben.

Das einige Funktionen getrennt für Spieler 1 und 2 existieren ist 
idiotisch, das erhöht nur den Wartungsaufwand. Besser: Spieler als 
Parameter an die jeweilige Funktion übergeben.

>Die Namen-Geschichte is natürlich sehr brisant. Wie kann ich meinen
>gesamten Namen aus meinem Profil verschwinden lassen? Geht das
>überhaupt?
Ehrliche Meinung: An sowas denkt man bevor man sich anmeldet bzw. 
irgendwo im Netz Daten hinterlegt.
Gast #1975880
Lesenswert?

"Ehrliche Meinung: An sowas denkt man bevor man sich anmeldet bzw.
irgendwo im Netz Daten hinterlegt."

Das ist dann wohl für mich wohl Grund genug um meinen bisherigen Account 
zu löschen und neu anzumelden. Ich fine es aber dann von diesem Board 
auch ziemlich Idiotisch nach einem realten Namen überhaupt erst zu 
fragen. Man findet nämlich sowieso selten Boards wo das so gemacht wird. 
Zumindestens wird dieser dann nicht auch noch öffentlich angezeigt und 
einem keine andere Wahl gelassen wird als dies zu akzeptieren!
#1975891
Lesenswert?

1. Spielst du hier eigentlioch das Spiel "wieviele Leute kann
ich gleichzeitig beschäftigen"?
Tip: versuch doch erst mal eins vernünftig zu machen und zu
verstehen, bevor du die nächsten 10 anfängst.

2. Es wäre nett, Quelltext nicht als *.txt anzuhängen.
Das machen hier die Spacken, und als solcher will man sich
doch nicht geben.
#1976079
Lesenswert?

Nicht besonders gut.
Eher schon besonders schlecht gelöst.

Da tun sich Baustellen an allen Ecken und Enden auf.
Mit ein wenig Ehrgeiz kann da
* fast 50% Code eingespart werden. Und zwar ohne das der Code
  unübersichtlicher wird. Ganz im Gegenteil, ganz im Gegenteil
* einiges wesentlich eleganter gelöst werden. Und zwar auch von
  jemandem der gerade erst angefangen hat

Im übertragenen Sinne:
Das ganze sieht aus, wie eine Autoreparatur, bei der jemand mangels 
handwerklicher Fertigkeiten den herausgefallenen Scheinwerfer mit 
Klebeband wieder angeklebt hat. Hält zwar für den Augenblick, aber nach 
5km fällt alles auseinander.
#1976097
Lesenswert?

Ach jetzt versteh ich erst!

Das hier
1
  for(int i=0; i<1; i=i+1)
2
  {
3
    int k = 49;
4
    for(int j=0; j<7; j=j+1)
5
    {
6
      Spielfeld[i][j] = k;
7
      k = k + 1;
8
    }
9
  }
soll die Spaltenbeschriftung werden.

Aber das macht man doch anders. Das macht die Ausgabefunktion ganz von 
alleine. Deswegen muss man doch nicht das Spielfeld größer anlegen.
#1976119
Lesenswert?

abc schrieb:
> Karl heinz Buchegger schrieb:
>> Ach jetzt versteh ich erst!
>
> Herzlichen Glückwunsch ;-) Vielleicht kannst du mir ja sagen warum zum
> Teufel k mit 49 initialisiert wird?

:-)
Weil 49 der ASCII Code für '1' ist :-)
(ohne Flachs. Da hat jemand noch nicht begriffen, dass man auch mit 
Charactern rechnen kann, weil '1' für den Compiler auch nichts anderes 
als der ASCII Code des Zeichens ist, nur anders verpackt)

Hätte er es so geschrieben
1
void InitialisiereSpielfeld(char Spielfeld[7][7])
2
{
3
  char c = '1';
4

5
  for(int j=0; j<7; j=j+1)
6
  {
7
    Spielfeld[0][j] = c++;
8
  }
9

10
  for(int i=1; i<7; i=i+1)
11
  {
12
    for(int j=0; j<7; j=j+1)
13
    {
14
      Spielfeld[i][j] = '+';
15
    }
16
  }
17
}

hätte es auch ein Blinder mit Krückstock gesehen.
Ob Gefahr besteht, dass diese Beschriftung irgendwo überschrieben wird, 
bzw ob sie bei der "Auswertung" mit eingerechnet wird, will ich jetzt 
erst gar nicht länger überprüfen.
Gast #1976145
Lesenswert?

Karl heinz Buchegger schrieb:
> abc schrieb:
>> Karl heinz Buchegger schrieb:
>>> Ach jetzt versteh ich erst!
>>
>> Herzlichen Glückwunsch ;-) Vielleicht kannst du mir ja sagen warum zum
>> Teufel k mit 49 initialisiert wird?
>
> :-)
> Weil 49 der ASCII Code für '1' ist :-)
(5 Minuten Lachkrampf)
Das gibt es ja nicht!!! Auf ASCII-Code wär ich wohl nie gekommen, obwohl 
mir der Code für '0' (und somit für alle anderen Ziffern) bekannt ist.

Ich fürchtete ja das hätte mit der "Größe" der Variablen zu tun.
[UNFUG]
Wenn ich ein Array brauche schreibe ich <Typ> <Name>[<Anzahl Elemente>], 
für eine Zahl <Typ> <Name> = <Maximalwert>. (Nochmal: DAS IST BLÖDSINN!)
[/UNFUG]

Da bin ich ja beruhigt. :-)
#1976159
Lesenswert?

abc schrieb:

> Das gibt es ja nicht!!! Auf ASCII-Code wär ich wohl nie gekommen,

Ich hab auch seit gestern daran gefeilt. Ok, nicht die ganze Zeit, aber 
immerhin.
Auf die Idee, die Spielfeldbeschriftung im Spielfel selbst abzulegen, 
wäre ich wohl nie gekommen. Das macht optisch schöne Ausgaben ... 
interessant und ist mir tatsächlich in all den Jahren (auch nicht am 
Anfang) jemals in den Sinn gekommen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren