PaterSigmund
Anmeldungsdatum: 24. Dezember 2007
Beiträge: Zähle...
|
Hallo allerseits!
Ich bin noch Programmier Anfänger und werd ist durch meine abneigung gegen sämltiche Sprachen (egal ob analog oder digital) auch immer bleiben. Leider hab ich haber 2 Semester Programmieren und muss mich damit befassen.
Momentan hab ich folgendes Problem. Ich hab mir aus nem PseudoCode unseres Profs mir den MergeSort zusammengereimt. Es hatt auch gut funktioniert. Nur war gestern mein Laptop der Meinung den Geist aufzugeben. Also ich dann wider zurück ans Reissbrett und von vorn angefangen. Bin auch eigentlich fertig. Nur will es nicht. Ich hab mal mit ein paar Programmen aus dem Netz verglichen und finde den Fehler nicht. Von daher wollt ich euch mal um Hilfe bitten. Sprache C a ist das Array das die unsortierten Zahlen beinhalten b ist das Array welches als zwischen Speicher genutzt wird l ist die linkeste Position (initalisiert mit 0) r ist die rechteste Position (initialisiert mit N-1)
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 | void mergesort(double a[N], double b[N], int l, int r)
{
int mitte, i, j, k, m;
if(r>l)
{
mitte=(l+r)/2;
mergesort(a, b, l, mitte);
mergesort(a, b, mitte+1, r);
i=l;
j=mitte+1;
k=l;
while(i<=mitte && j<=r)
{
if(a[i]<=a[j])
b[k++]=a[i++];
else
b[k++]=a[j++];
}
while(i<=mitte)
b[k++]=a[i++];
while(j<=r)
b[k++]=a[j++];
for(m=0; m<N; m++)
a[m]=b[m];
}
}
|
Schonmal ein großes Danke im voraus. Bin hier nämlich echt am Verzweifeln. Programmieren ist nunmal nicht meins.
Bearbeitet von redknight: Syntax angepasst (Listenstruktur und codeblock mit Zeilennummern)
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17604
Wohnort: Berlin
|
Das N gehört hier (double a[N], double b[N], int l, int r)
nicht rein. M.a.W. Du hast einen Fehler vom Compiler erhalten - dann solltest Du das auch sagen, und die Meldung zitieren, wenn Du sie schon nicht verstehst, um sie selbst zu behandeln. Dann wäre es auch nett das ganze in ein Testprogramm zu bauen, daß man es rasch ausprobieren kann - das muß sonst jeder für sich machen. Der Scope der Variablen ist viel zu groß - man muß überall schauen, ob m, j, k, l, r noch gebraucht werden, wer daran rumgespielt hat. Teils tragen die Bezeichner eine Bedeutung (l, r) und dann sieht es aus wie ein uninspirierte Reihe Buchstaben (j, k, l) - nur daß es für l gerade nicht gilt. Was funktioniert noch nicht - was passiert, was sollte passieren, wie soll der Algorithmus denn arbeiten? Wir machen eigentlich keine Hausaufgaben.
|
PaterSigmund
(Themenstarter)
Anmeldungsdatum: 24. Dezember 2007
Beiträge: 161
|
Das N gehört hier (double a[N], double b[N], int l, int r) nicht rein. M.a.W. Du hast einen Fehler vom Compiler erhalten - dann solltest Du das auch sagen, und die Meldung zitieren, wenn Du sie schon nicht verstehst, um sie selbst zu behandeln.
Warum sollte das da nicht rein gehören? Also weder Eclipse nich gcc schmeissen mir da in Fehler raus. Der Scope der Variablen ist viel zu groß
Was ist ein Scope??
uninspirierte Reihe Buchstaben (j, k, l)
i, j, k sind lauf Variablen. Hab die eigentlich bisher immer von i angefangen alphabetisch weiter geführt
Was funktioniert noch nicht - was passiert, was sollte passieren, wie soll der Algorithmus denn arbeiten?
Das Feld was er übergeben bekommt, sortiert er nicht. Er gibt an und für sich nur Müll raus. Obwohl das Programm nach dem Ausschlussverfahren gut funkionieren sollt. Das Feld bekommt er:
20
19
15
2
12
16
7
8
1
14
11
20
13
3
17
5
18
4
6
9
10 Und das Feld bekomm ich zurück nach dem Aufruf:
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
15.000000
19.000000 Wir machen eigentlich keine Hausaufgaben.
Das ist mir durchaus bewusst. Aber Programmieren ist wie gesagt nicht meins. Und da ich sogar soweit geh, das ich nach dem Ausschlussverfahren Programmier. Versuch ich die Leute zu fragen, die davon Ahnung haben. In der Hoffnung dabei was zu lernen.
Dann wäre es auch nett das ganze in ein Testprogramm zu bauen
Ja ok hast recht, sorry.
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 | #include <stdio.h>
#define N 10
void ausgabe(double a[N]);
void mergesort(double a[N], double b[N], int l, int r);
int main()
{
double a[]={10,5,4,2,1,9,7,6,3,4}, b[N];
int tmp, i;
for(i=0; i<N; i++)
b[i]=0;
printf("\nBitte wählen Sie:\n"
" 1) Mergesort (2 Array)\n"
" 2) Beenden\n");
scanf("%d",&tmp);
switch(tmp)
{
case 1: printf("Mergesort (2 Array)\n");
mergesort(a, b, 0, N-1);
break;
case 2: return 0;
}
ausgabe(a);
return 0;
}
void ausgabe(double a[N])
{
int i;
for(i=0; i<N; i++)
printf("%lf\n", a[i]);
}
void mergesort(double a[N], double b[N], int l, int r)
{
int mitte, i, j, k, m;
if(r>l)
{
mitte=(l+r)/2;
mergesort(a, b, l, mitte); //Rekursive Spaltung in rechten und linken Block
mergesort(a, b, mitte+1, r);
i=l;
j=mitte+1;
k=l;
while(i<=mitte && j<=r) //Sortieren der Teilbereiche der Größe nach
{
if(a[i]<=a[j])
b[k++]=a[i++];
else
b[k++]=a[j++];
}
while(i<=mitte) //Zusammenführen der Teilstücke
b[k++]=a[i++];
while(j<=r)
b[k++]=a[j++];
for(m=0; m<N; m++) //Rückschreiben in Array. Wobei hier der Schritt nicht notwendig ist, da man auch das Hilfsarray ausgeben könnte.
a[m]=b[m];
}
}
|
Bitte korrigiert mich, wenn ich das Programm falsch verstanden hab. EDIT:
Habs gefunden.
Die letzte for schleife muss m=l und m<k laufen... warum auch immer
Bearbeitet von redknight: Auch hier codeblock mit Zeilennummern und highlighting gewählt
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17604
Wohnort: Berlin
|
gcc mergesort.c -Wall --pedantic -o mergesort
mergesort.c: In function ‘ausgabe’:
mergesort.c:39: warning: ISO C90 does not support the ‘%lf’ gnu_printf format
mergesort.c:50:42: warning: C++ style comments are not allowed in ISO C90
mergesort.c:50:42: warning: (this will be reported only once per input file) Warum sollte das da nicht rein gehören? Also weder Eclipse nich gcc schmeissen mir da in Fehler raus.
Soweit ich weiß prüft der Compiler nicht, ob das Array wirklich 10 Elemente hat. Zudem wurde aus dem alten Codefragment nicht klar, daß N an der Stelle 10 ist, weil es der Präprozessor ersetzt hat. Womit wir bei einer Unsitte sind:
#define N 10
Verwende const statt define - das drückt besser aus, was gemeint ist, und ist für verschiedene Werkzeuge besser zu handhaben.
Was ist ein Scope??
Der Scope ist der Sichtbarkeitsbereich einer Variablen, das ist in C der umschließende Block - in Abwesenheit eines solchen die Datei oder Kompilierungseinheit - beginnend mit der Zeile, in der die Variable deklariert ist. 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 | void mergesort(double a[N], double b[N], int l, int r)
{
int mitte, i, j, k, m;
if(r>l)
{
mitte=(l+r)/2;
mergesort(a, b, l, mitte); //Rekursive Spaltung in rechten und linken Block
mergesort(a, b, mitte+1, r);
i=l;
j=mitte+1;
k=l;
while(i<=mitte && j<=r) //Sortieren der Teilbereiche der Größe nach
{
if(a[i]<=a[j])
b[k++]=a[i++];
else
b[k++]=a[j++];
}
while(i<=mitte) //Zusammenführen der Teilstücke
b[k++]=a[i++];
while(j<=r)
b[k++]=a[j++];
for(m=0; m<N; m++) //Rückschreiben in Array. Wobei hier der Schritt nicht notwendig ist, da man auch das Hilfsarray ausgeben könnte.
a[m]=b[m];
}
}
|
Hier also für mitte, i, j, k, m ab Zeile 3 bis zum Ende der Funktion mergesort, selbst wenn r ⇐ l ist. Wer den Code umbaut muß ängstlich die ganze Funktion überprüfen, ob nicht die Variablen bereits zuvor verwendet wird, oder später nochmal gebraucht wird, insbesondere ob an späterer Stelle der letzte Wert benötigt wird. Zum Beispiel genügt es für m, wenn es ganz unten i.d. for-Schleife deklariert wird:
for (int m = 0; m < N; m++)
a[m] = b[m]; Man könnte dann auch problemlos den Bezeichner i wiederverwenden. Sowas wird auch bei Zählvariablen gerne gemacht.
void ausgabe(double a[N]);
void mergesort(double a[N], double b[N], int l, int r);
int main()
{
double a[]={10,5,4,2,1,9,7,6,3,4}, b[N];
Wieso deklarierst Du doubles, und benutzt dann ints?
Das Feld was er übergeben bekommt, sortiert er nicht. Er gibt an und für sich nur Müll raus. Obwohl das Programm nach dem Ausschlussverfahren gut funkionieren sollt.
Was für ein Ausschlussverfahren?
Das ist mir durchaus bewusst. Aber Programmieren ist wie gesagt nicht meins. Und da ich sogar soweit geh, das ich nach dem Ausschlussverfahren Programmier. Versuch ich die Leute zu fragen, die davon Ahnung haben. In der Hoffnung dabei was zu lernen.
Wenn das Pflichtprogramm im Studium ist, so daß Du es 2 Semester belegen mußt, dann solltest Du sehen, daß Du es zu "Deinem" machst. Immerhin wirst Du, wenn Du das Studium abschließt, wie jemand behandelt, der das 2 Semester lang gemacht hat. Ich will von keinem Arzt behandelt werden, der nicht weiß, wie ein Doppelblindtest aussieht, weil das nicht seins ist, oder von einem Banker beraten werden, der keinen Zinseszins berechnen kann. Beim Verstehen helfe ich gerne, beim Pfuschen nicht. Also so gehst Du weiter vor: Da das Programm rekursiv arbeitet, und die Rekursion nicht am Ende der Funktion steht, sondern soweit oben, versteht man es nicht, ohne ganz durch die Rekursion durchgegangen zu sein - dafür sind 10 Elemente aber bischen viel. Um es im Kopf durchzugehen nimmt man so wenig Argumente wie möglich, ohne daß dabei die Aufgabe verloren geht. 1 Element kann man nicht groß sortieren - 2 sind auch zu wenig, und 3 sehr knapp. Also nimm 4 Elemente, die nicht sortiert sind.
a[] = {10,5,4,8};
const int N = 4;
l = 0
r = 4-1 = 3;
wäre der erste Aufruf.
mitte=(l+r)/2;
// (0+3)/2 = 1.5 = 1;
b wird, wie Du selbst gemerkt hast, i.d. aufrufenden Funktion gar nicht benutzt - man kann also b in mergesort deklarieren, und auf das herumreichen verzichten. Oder nicht? Hat es eine spezielle Bewandtnis, daß b immer herumgereicht wird? Wenn nicht - (r > l) also (3 > 0) ist wahr. Dies
mergesort (a, l, mitte);
mergesort (a, mitte+1, r);
wird also zu
mergesort (a, 0, 1);
mergesort (a, 2, 3);
Der erste Aufruf führt zu
mitte = (0 + 1) /2 = 0.5 = 0
r > l also 1 > 0 ist auch true.
mergesort (a, l=0, mitte=0);
im nächsten Aufruf aber zu (a, 0, 0), r ist dann nicht mehr größer als l, und so wird der ganze Block übersprungen, und die Funktion kehrt unverrichteter Dinge zurück - insbesondere ohne eine weitere Rekursion ausgelöst zu haben.
mergesort (a, mitte+1=1, r=1) führt auch zu einem r==l im nächsten Aufruf - auch diese Funktion steigt also nicht tiefer herab. Hier geht es also erstmal weiter. int i = l; // l = 0
int j = mitte + 1; // mitte = 0 => j = 1
int k = l; // k = 0
int b[N]; // früher wird b nicht gebraucht
while (i <= mitte && j <= r) // (0 <= 1 && 1 <= 1) initial: true
{
if (a[i] <= a[j]) // a(0) <= a(1) ? 10 <= 5 => false
b[k++] = a[i++];
else
b[k++] = a[j++]; // b(0) = a(1) = 5; k = 1, j= 2
}
Nach einem Durchlauf ist diese Schleife abgearbeitet, denn j=2 > r=1. Jetzt geht es wie weiter?
while (i <= mitte) // i=0, mitte = 0 => true
b[k++] = a[i++]; // b(1) = a(0) = 10. Danach ist i=1 > mitte.
while (j <= r) // ist schon falsch.
b[k++] = a[j++];
b(0) und b(1) sind jetzt das, was a(1) und a(0) waren, also getauscht. Ich erlaube mir runde Klammern hier zu benutzen, weil sich das rascher tippen läßt. Jetzt kommt m ins Spiel:
for (int m = 0; m < N; m++)
a[m] = b[m];
Obwohl wir nur die Elemente 0 und 1 getauscht haben läuft m von 0 bis N. Damit wird a(2) bis a(3) jetzt Null. Das ist doch kaum gewollt - oder?
|
PaterSigmund
(Themenstarter)
Anmeldungsdatum: 24. Dezember 2007
Beiträge: 161
|
Soweit ich weiß prüft der Compiler nicht, ob das Array wirklich 10 Elemente hat. Zudem wurde aus dem alten Codefragment nicht klar, daß N an der Stelle 10 ist, weil es der Präprozessor ersetzt hat.
Ich hab mal die N's weggemacht. Aber dann bekomm ich eine ganze Menge Fehlermeldungen. Und die eckigen Klammern kann ich ja nicht wegmachen, da ich ja anonsten nur noch einen int hab.
Verwende const statt define - das drückt besser aus, was gemeint ist, und ist für verschiedene Werkzeuge besser zu handhaben.
Zum Beispiel genügt es für m, wenn es ganz unten i.d. for-Schleife deklariert wird:
Sorry, wir haben es halt so gelernt. Und da ich sonst keine Referenz hab orientier ich mich halt an dem was mir beigebracht wird. Werds aber dann versuchen zu ändern. Ist ja nicht so als ob ich nicht lernwillig wär ^^
Wieso deklarierst Du doubles, und benutzt dann ints?
Die Aufgabenstellung war halt "sortiere double" und benutz halt da jetzt int, weil se halt schneller von der Hand gehen. Und double die ja auch handeln kann. Solang keine Rechenoperationen gemacht werden.
Was für ein Ausschlussverfahren?
Das läuft wie folgt. Ich hol mir den Pseudo Code aus der Aufgabenstellung. Erstelle das Konstrukt so wie ich es für richtig halte. Und arbeite mich dann von oben nach unten. Und schaue welche Parameter oder Indizies am wahrscheinlichsten sind. Danach arbeite ich alle Warnungen ab. Und faszinierender Weise funktioniert das meistens.... bis es halt nicht funkionert. Und dann häng ich da.
dann solltest Du sehen, daß Du es zu "Deinem" machst
Glaub mir, dass versuch ich wirklich. Aber ich bekomm es irgendwo nicht hin. Damals Basic hatte ich ganz gut im Griff. Auch AWL von den SPS'en war nicht so das Problem. Aber das hier raubt mir echt den Nerv. Wobei es bei keinem Programm so schwer war wie bei diesem.
Beim Verstehen helfe ich gerne, beim Pfuschen nicht.
Das Pfuschen ist auch nicht meine Absicht. Denn das bringt weder mir, noch meinem Ego, noch meinem späteren Brötschengeber etwas.
Und vielen Dank für deine Ausführliche Erklärung des Programmes und dessen Ablaufs. Ich werd es mir noch paar mal durchlesen müssen um es zu verstehen, aber das liegt definitiv nicht an Deiner Schreibe. Sonder eher an meiner "Blockade" dem Programmieren gegenüber.
Obwohl wir nur die Elemente 0 und 1 getauscht haben läuft m von 0 bis N. Damit wird a(2) bis a(3) jetzt Null. Das ist doch kaum gewollt - oder?
Ne nicht wirklich er muss von links laufen bis zu dem Wert den k angenommen hat. Also die Größe von b.
Oder?
|
deprecated
Anmeldungsdatum: 21. Dezember 2009
Beiträge: 91
Wohnort: Wien
|
| for(m=0; m<N; m++) //Rückschreiben in Array. Wobei hier der Schritt nicht notwendig ist, da man auch das Hilfsarray ausgeben könnte.
a[m]=b[m];
|
Sorry, aber der Kommentar ist Unsinn. Du rufst die Funktion ja rekursiv auf, also muss die Arbeit auch wieder zurück nach a. (Weil du ja immer von a nach b merged.) PaterSigmund schrieb: Ne nicht wirklich er muss von links laufen bis zu dem Wert den k angenommen hat. Also die Größe von b.
Oder?
Nein. Du sortiest ja immer nur den Teil von l bis r. Wenn du vom Anfang bis zum Ende des Arrays b nach a kopierst, dann überschreibst du beim ersten Mal, die ganzen Daten in a mit nicht initialisierten Werten.
| while(l <= r)
{
a[l] = b[l];
l++;
}
|
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17604
Wohnort: Berlin
|
PaterSigmund schrieb: Soweit ich weiß prüft der Compiler nicht, ob das Array wirklich 10 Elemente hat. Zudem wurde aus dem alten Codefragment nicht klar, daß N an der Stelle 10 ist, weil es der Präprozessor ersetzt hat.
Ich hab mal die N's weggemacht. Aber dann bekomm ich eine ganze Menge Fehlermeldungen.
So? Welche denn?
Und die eckigen Klammern kann ich ja nicht wegmachen, da ich ja anonsten nur noch einen int hab.
Das hat auch niemand vorgeschlagen.
void mergesort (double a[], int l, int r)
würde ich vorschlagen, als ein 'Double-a-Array', oder besser noch
void mergesort (double[] a, int l, int r)
Ein Double-Array a. Beides ist möglich, aber letzteres verbreiteter.
Sorry, wir haben es halt so gelernt. Und da ich sonst keine Referenz hab orientier ich mich halt an dem was mir beigebracht wird. Werds aber dann versuchen zu ändern. Ist ja nicht so als ob ich nicht lernwillig wär ^^
Es gibt Sprachen - Pascal, soweit ich weiß - da ist es zwingend notwendig die Variablen am Beginn einer Funktion zu deklarieren. Da geht's dann nicht anders.
Wieso deklarierst Du doubles, und benutzt dann ints?
Die Aufgabenstellung war halt "sortiere double" und benutz halt da jetzt int, weil se halt schneller von der Hand gehen. Und double die ja auch handeln kann. Solang keine Rechenoperationen gemacht werden.
Okay. Sinnvolle Begründung.
dann solltest Du sehen, daß Du es zu "Deinem" machst
Glaub mir, dass versuch ich wirklich. Aber ich bekomm es irgendwo nicht hin. Damals Basic hatte ich ganz gut im Griff. Auch AWL von den SPS'en war nicht so das Problem. Aber das hier raubt mir echt den Nerv. Wobei es bei keinem Programm so schwer war wie bei diesem.
Hm. Vom imperativen Stil sehe ich aber viele Gemeinsamkeiten mit Basic.
|
PaterSigmund
(Themenstarter)
Anmeldungsdatum: 24. Dezember 2007
Beiträge: 161
|
deprecated schrieb: Nein. Du sortiest ja immer nur den Teil von l bis r. Wenn du vom Anfang bis zum Ende des Arrays b nach a kopierst, dann überschreibst du beim ersten Mal, die ganzen Daten in a mit nicht initialisierten Werten.
| while(l <= r)
{
a[l] = b[l];
l++;
}
|
Ok danke ich denk ich habs (hoffentlich verstanden) user unknown schrieb: PaterSigmund schrieb: Soweit ich weiß prüft der Compiler nicht, ob das Array wirklich 10 Elemente hat. Zudem wurde aus dem alten Codefragment nicht klar, daß N an der Stelle 10 ist, weil es der Präprozessor ersetzt hat.
Ich hab mal die N's weggemacht. Aber dann bekomm ich eine ganze Menge Fehlermeldungen.
So? Welche denn?
Und die eckigen Klammern kann ich ja nicht wegmachen, da ich ja anonsten nur noch einen int hab.
Das hat auch niemand vorgeschlagen.
void mergesort (double a[], int l, int r)
Ok nehm fast alles zurück. Hatte ein paar N's vergessen zu löschen. Daher die Fehlermeldungen. Kann es aber sein, dass das nur bei Eindimensionalen Arrays funkioniert? Denn hab noch ein anderes Programm das ich mal "bereinigen" wollt. Und da bekomm ich dann einen ganzen Batzen an Fehlermeldungen bezüglich des 2 Dimensionalen Arrays
würde ich vorschlagen, als ein 'Double-a-Array', oder besser noch
void mergesort (double[] a, int l, int r)
Ein Double-Array a. Beides ist möglich, aber letzteres verbreiteter.
Ok hab ich ja noch nie gesehen... aber davon gibts noch ne Menge. Und initialisier ich das ganze normal? Nur das dann a von Typ "double[]" ist? Und warum ist es besser das so zu machen?
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17604
Wohnort: Berlin
|
Vom Kompilat wird es das gleiche werden, aber die Bezeichnung läßt sich dann symetrisch übernehmen:
int a; /* int(eger) ah */
String s; /* String es */
Window w; /* Window weh */
int [] i; /* int-Array i */
i ist vom Typ int-Array. Dagegen wie drückt man dies sprachlich aus:
int i[]; /* int-i Array ?*/
Ein Int-i-Array? Das sind ja nicht viele is, sondern ints. Ich habe es aber auch jahrelang eher wie Typ 2 geschrieben, und bin nicht unglücklich damit geworden.
Kann es aber sein, dass das nur bei Eindimensionalen Arrays funkioniert? Denn hab noch ein anderes Programm das ich mal "bereinigen" wollt. Und da bekomm ich dann einen ganzen Batzen an Fehlermeldungen bezüglich des 2 Dimensionalen Arrays
Nö.
double get (double[][] feld, int x, int y) {
return feld[x][y];
}
Allerdings beim Indizieren kommen Klammern dann doch hinter den Bezeichner (Feld-x-y, Feld-7-4) und nicht davor.
|
PaterSigmund
(Themenstarter)
Anmeldungsdatum: 24. Dezember 2007
Beiträge: 161
|
user unknown schrieb: Kann es aber sein, dass das nur bei Eindimensionalen Arrays funkioniert? Denn hab noch ein anderes Programm das ich mal "bereinigen" wollt. Und da bekomm ich dann einen ganzen Batzen an Fehlermeldungen bezüglich des 2 Dimensionalen Arrays
Nö.
double get (double[][] feld, int x, int y) {
return feld[x][y];
}
Allerdings beim Indizieren kommen Klammern dann doch hinter den Bezeichner (Feld-x-y, Feld-7-4) und nicht davor.
Bekomm das aber irgendwo nicht hin. Entweder überseh ich irgendwas, oder Eclipse zickt rum. Wobei ich dann eher auf ersteres tipp.
Hier das Prog ohne "bereinigung"
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135 | #include <stdio.h>
#define N 50
#define M 256
int lese(int a[N][N], int *gx, int *gy);
int prueffe(int a[N][N], int gx, int gy);
void ausgabe(int a[N][N], int gx, int gy);
int weg(int a[N][N], int gx, int gy, int x, int y);
void formatieren(int a[N][N], int gx, int gy);
int main()
{
int a[N][N], gx, gy;
if(lese(a, &gx, &gy)==2)
return 0;
else
{
if(prueffe(a, gx, gy)==0)
return 0;
else
{
weg(a, gx, gy, 0, 0);
formatieren(a, gx, gy);
ausgabe(a, gx, gy);
}
}
return 0;
}
int lese(int a[N][N], int *gx, int *gy)
{
FILE* in;
int res=1, tmp=0;
do{
char pfad[M];
printf("\nBitte geben Sie den Pfad der Datei an: ");
scanf("%s",pfad);
in=fopen(pfad,"r");
if(in==NULL)
{
printf("\nPfad oder Dateiname ungültig. Bitte neu eingeben.\n");
tmp++;
}
else
res=0;
if(tmp==3)
{
printf("\nDritte falsche Eingabe. Programm wird beendet\n\n");
res=2;
}
}while(tmp<=3 && res==1);
if(in!=NULL)
{
fscanf(in, "%d %d", gx, gy);
int i,j;
for(i=0; i<*gx; i++)
for(j=0; j<*gy; j++)
fscanf(in, "%d", &a[i][j]);
fclose(in);
}
return res;
}
int prueffe(int a[N][N], int gx, int gy)
{
int fehler;
if(a[gx-1][gy-1]==0 || a[0][0]==0)
return fehler=1;
else
{
printf("\nLabyrinth hat keinen Anfang und/oder kein Ende\n");
return fehler=0;
}
}
void ausgabe(int a[N][N], int gx, int gy)
{
printf("\n");
int i, j;
for(i=0; i<gx; i++)
{
for(j=0; j<gy; j++)
printf("%2d", a[i][j]);
printf("\n");
}
printf("\n");
}
int weg(int a[N][N], int gx, int gy, int x, int y)
{
int res;
a[x][y]=8;
if(x==gx-1 && y==gy-1)
res=0;
else
res=1;
if(a[x+1][y]==0 && x+1<gx && res==1)
res=weg(a, gx, gy, x+1, y);
if(a[x-1][y]==0 && x-1>=0 && res==1)
res=weg(a, gx, gy, x-1, y);
if(a[x][y+1]==0 && y+1<gy && res==1)
res=weg(a, gx, gy, x, y+1);
if(a[y][y-1]==0 && y-1>=0 && res==1)
res=weg(a, gx, gy, x, y-1);
if(res==1)
a[x][y]=3;
return res;
}
void formatieren(int a[N][N], int gx, int gy)
{
int i, j;
for(i=0; i<=gx; i++)
for(j=0; j<=gy; j++)
if(a[i][j]==3)
a[i][j]=0;
}
|
Hier mit bereinigung:
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135 | #include <stdio.h>
#define N 50
#define M 256
int lese(int a[][], int *gx, int *gy);
int prueffe(int a[][], int gx, int gy);
void ausgabe(int a[][], int gx, int gy);
int weg(int a[][], int gx, int gy, int x, int y);
void formatieren(int a[][], int gx, int gy);
int main()
{
int a[N][N], gx, gy;
if(lese(a, &gx, &gy)==2)
return 0;
else
{
if(prueffe(a, gx, gy)==0)
return 0;
else
{
weg(a, gx, gy, 0, 0);
formatieren(a, gx, gy);
ausgabe(a, gx, gy);
}
}
return 0;
}
int lese(int a[][], int *gx, int *gy)
{
FILE* in;
int res=1, tmp=0;
do{
char pfad[M];
printf("\nBitte geben Sie den Pfad der Datei an: ");
scanf("%s",pfad);
in=fopen(pfad,"r");
if(in==NULL)
{
printf("\nPfad oder Dateiname ungültig. Bitte neu eingeben.\n");
tmp++;
}
else
res=0;
if(tmp==3)
{
printf("\nDritte falsche Eingabe. Programm wird beendet\n\n");
res=2;
}
}while(tmp<=3 && res==1);
if(in!=NULL)
{
fscanf(in, "%d %d", gx, gy);
int i,j;
for(i=0; i<*gx; i++)
for(j=0; j<*gy; j++)
fscanf(in, "%d", &a[i][j]);
fclose(in);
}
return res;
}
int prueffe(int a[][], int gx, int gy)
{
int fehler;
if(a[gx-1][gy-1]==0 || a[0][0]==0)
return fehler=1;
else
{
printf("\nLabyrinth hat keinen Anfang und/oder kein Ende\n");
return fehler=0;
}
}
void ausgabe(int a[][], int gx, int gy)
{
printf("\n");
int i, j;
for(i=0; i<gx; i++)
{
for(j=0; j<gy; j++)
printf("%2d", a[i][j]);
printf("\n");
}
printf("\n");
}
int weg(int a[][], int gx, int gy, int x, int y)
{
int res;
a[x][y]=8;
if(x==gx-1 && y==gy-1)
res=0;
else
res=1;
if(a[x+1][y]==0 && x+1<gx && res==1)
res=weg(a, gx, gy, x+1, y);
if(a[x-1][y]==0 && x-1>=0 && res==1)
res=weg(a, gx, gy, x-1, y);
if(a[x][y+1]==0 && y+1<gy && res==1)
res=weg(a, gx, gy, x, y+1);
if(a[y][y-1]==0 && y-1>=0 && res==1)
res=weg(a, gx, gy, x, y-1);
if(res==1)
a[x][y]=3;
return res;
}
void formatieren(int a[][], int gx, int gy)
{
int i, j;
for(i=0; i<=gx; i++)
for(j=0; j<=gy; j++)
if(a[i][j]==3)
a[i][j]=0;
}
|
Und hier die Fehlermeldung dazu:
lab.c:5: error: array type has incomplete element type
lab.c:6: error: array type has incomplete element type
lab.c:7: error: array type has incomplete element type
lab.c:8: error: array type has incomplete element type
lab.c:9: error: array type has incomplete element type
lab.c: In function ‘main’:
lab.c:15: error: type of formal parameter 1 is incomplete
lab.c:19: error: type of formal parameter 1 is incomplete
lab.c:23: error: type of formal parameter 1 is incomplete
lab.c:24: error: type of formal parameter 1 is incomplete
lab.c:25: error: type of formal parameter 1 is incomplete
lab.c: At top level:
lab.c:32: error: array type has incomplete element type
lab.c:73: error: array type has incomplete element type
lab.c:86: error: array type has incomplete element type
lab.c:101: error: array type has incomplete element type
lab.c: In function ‘weg’:
lab.c:113: error: type of formal parameter 1 is incomplete
lab.c:115: error: type of formal parameter 1 is incomplete
lab.c:118: error: type of formal parameter 1 is incomplete
lab.c:120: error: type of formal parameter 1 is incomplete
lab.c: At top level:
lab.c:128: error: array type has incomplete element type Und das sind dann genau die Zeilen die die Array betreffen. Obwohl es eigentlich passen sollte.
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17604
Wohnort: Berlin
|
Du hast absolut Recht - ich muß Abbitte leisten. Ich habe so einen Mischmasch von C und C++ gelernt, um jetzt seit vielen Jahren eigentlich nur noch Java zu machen, eine Sprache die syntaktisch sehr viele Ähnlichkeiten mit C und C++ hat, aber bei Arrays offenbar weniger als ich dachte. Ich bin ganz baff.
Weder dürfen die eckigen Klammern vor dem Bezeichner stehen, und nur die erste Dimension darf weggelassen werden. Pardon - ich hoffe Dir nicht zu viel Arbeit gemacht zu haben.
|
PaterSigmund
(Themenstarter)
Anmeldungsdatum: 24. Dezember 2007
Beiträge: 161
|
user unknown schrieb: Du hast absolut Recht - ich muß Abbitte leisten. Ich habe so einen Mischmasch von C und C++ gelernt, um jetzt seit vielen Jahren eigentlich nur noch Java zu machen, eine Sprache die syntaktisch sehr viele Ähnlichkeiten mit C und C++ hat, aber bei Arrays offenbar weniger als ich dachte. Ich bin ganz baff.
Weder dürfen die eckigen Klammern vor dem Bezeichner stehen, und nur die erste Dimension darf weggelassen werden. Pardon - ich hoffe Dir nicht zu viel Arbeit gemacht zu haben.
Ne ne keine Panik. Kann dadurch auch nur lernen. Und nochmals herzlichen Dank für eure Hilfe.
|