Weil deine Logik nicht stimmt.
Du hast programmiert, dass immer dann alle Verlierer sind, wenn nicht
Spieler 3 der Gewinner ist.
Das ist aber offensichtlicher Unsinn, denn wenn Spieler 1 gewinnt, dann
gibt es ja einen Gewinner und nicht alle sind die Verlierer.
Ein else gehört immer zum letzten if. Und wenn du 200 if davor hattest,
die interessieren das if nicht. Die Programmlogik ist immer: entweder
wird der abhängige Programmteil von diesem einen if genommen oder es
kommt dessen else zum Zug.
In deinem Fall bezieht sich das else nur auf dieses if hier
1
if(g==s30||g==s31||g==s32){
2
printf("\nDer Sieger ist Spieler 3");
3
}
4
else
5
printf("\nIhr seid alle Verlierer");
Alles was davor passiert und was du davor ausgibst, interessiert an
dieser Stelle nicht.
Vielen Dank für die schnelle Antwort :),
eine Frage hätte ich noch und zwar, wie das Programm funktioniert wenn
man statt dem Datentyp int ein char verwendet.
Vielen Dank für die schnelle Antwort :),
eine Frage hätte ich noch und zwar, wie das Programm funktioniert wenn
man statt dem Datentyp int ein char verwendet.
Karl Heinz schrieb:
> Ein else gehört immer zum letzten if. Und wenn du 200 if davor hattest,
die interessieren das if nicht. Die Programmlogik ist immer: entweder
wird der abhängige Programmteil von diesem einen if genommen oder es
kommt dessen else zum Zug.
Hört sich nicht an, als ob das von einem Datentyp abhängig wäre, oder?
Appel0 A. schrieb:> Vielen Dank für die schnelle Antwort :),> eine Frage hätte ich noch und zwar, wie das Programm funktioniert wenn> man statt dem Datentyp int ein char verwendet.
Genauso, wenn du den Wertebereich und die richtigen Formatkennzeichner
beachtest. ABER: es ist nicht klar definiert ob dein char
vorzeichenbehaftet ist oder nicht. Das musst du vorher prüfen. Aus
diesem Grund nimmt man char ausschließlich für Zeichen (dafür ist es
gedacht).
Wenn du aus Gründen der Platzersparnis einen kleineren Datentyp als int
haben möchtest, dann bieten sich die mit festgelegter Länge an, also:
uint8_t bzw int8_t aus dem Header "stdint.h".
Gruß
Dennis
Stefan K. schrieb:> Hi Appel0,>> mit der switch-Anweisung kannst Du das auch ganz schön schreiben:>> switch (c)> {> case s10:> case s11:> case s12:> printf("\nDer Sieger ist Spieler 1");> break;>> case s20:> case s21:> case s22:> printf("\nDer Sieger ist Spieler 2");> break;>> case s30:> case s31:> case s32:> printf("\nDer Sieger ist Spieler 3");> break;>> default:> printf("\nIhr seid alle Verlierer");> }>
Das ist leider auch falsch,
bei dem ersten break springt er aus dem switch raus. Da kann es auch nur
einen Sieger geben.
Appel0 A. schrieb:> in der Aufgabe wird verlangt, dass jeder Spieler> eine andere Zahl wählt.nicht"Gast" schrieb:> Da kann es auch nur> einen Sieger geben.
Das ist ja auch richtig. Wenn jeder Spieler andere Zahlen wählen muß,
kann es auch nur einen Sieger geben.
Sieger schrieb:> Das ist ja auch richtig. Wenn jeder Spieler andere Zahlen wählen muß,> kann es auch nur einen Sieger geben.
Tja. Wie das eben mit so muss Vereinbarungen ist. Wenn es keiner
überprüft, dann gilt die auch nichts.
Entweder man sorgt programmtechnisch dafür, dass Duplikate nicht
vorkommen (was im jetzigen Code noch fehlt) oder man lässt zu, dass eben
mehrere die Zahl erraten können und daher zu Recht mehrere Sieger
möglich sind. Letzteres ist ja auch programmtechnisch keine grosse
Hexerei. Mitzählen, wieviele die Zahl in ihrem Vorrat hatten und wenn
die Anzahl 0 ist, dann gab es eben keinen Sieger.
(Ich versteh schon, dass es sich da jetzt um eine Aufgabe für Anfänger
handelt. Von daher messe ich dem jetzt nicht allzuviel Bedeutung bei.
Der Focus liegt in dieser Aufgabenstellung höchst wahrscheinlich auf dem
Verhalten von if - else if Ketten, bzw auf der Zugehörikeit von else zum
vorhergehenden if. Man kann eben nicht alles auf einmal lernen, braucht
aber trotzdem Übungsbeispiele. Jeder der sich schon mal im unterrichten
versucht hat, kennt das Dilemma.)
Ergänzend zu dem was KH schon gesagt hat: es hilft oft das Programm
erstmal in "Pseudo-Code" aufzuschreiben, oder ein sogenanntes
Programm-ablauf-plan (PAP) aufzustellen.
Hier könnte das etwa so aussehen:
1
PROGRAMMLotto:
2
FÜRJEDENSpieler:
3
FÜRJEDENWurf:/* Ich sage mal, dass die Spieler würfeln... */
4
WIEDERHOLE
5
FragSpielernachseinemWurf
6
VergleicheWurfmitallenvorherigenWürfen
7
BISWurfnichtschonvorgekommen
8
9
FragnachGewinnzahl
10
11
FÜRJEDENSpieler:
12
FÜRJEDENWurf:
13
FALLSDiesenWurfistdieGewinnzahl
14
DANNGratuliereSpieler
15
16
FALLSNiemandenwurdegratuliert
17
DANNTrauere
18
ENDE.
Dann stellst du fest dass die Aufgabe "Vergleiche Wurf mit allen
vorherigen Würfen" noch ein bisschen ausgearbeitet werden muss:
Robert L. schrieb:> dein "Pseudo code" ist 10 mal schwerer zu lesen als der C Code
Absolut nicht.
Jemand, der sich mit dieser Sprache noch nicht auseinandergesetzt hat,
ist dankbar über einen solchen Pseudo-Quelltext.
MfG Paul
Paul B. schrieb:> Robert L. schrieb:>> dein "Pseudo code" ist 10 mal schwerer zu lesen als der C Code>> Absolut nicht.> Jemand, der sich mit dieser Sprache noch nicht auseinandergesetzt hat,> ist dankbar über einen solchen Pseudo-Quelltext.>> MfG Paul
nein: in deinem Psoudo Code ist das "einrücken" von essentieller
Bedeutung, in C überhaupt nicht..
(gerade dieses Details waren/sind aber das ursprünglich Problem des TO,
..)
ausserdem geht aus dem "Psoudo Code" nicht wirklich hervor wie
"Niemanden wurde gratuliert" zustande kommt..
das Wort "Wurf" wird mehrfach verwendet, mit (min 3) verschiedenen
Bedeutungen usw. usw.
warum dem TO ein solcher Psoudo Code Überhaupt nicht helfen würde ist
recht einfach
er würde den Psoudo Code ja so Schreiben:
Start
Spieler1 wähle 3 Zahlen
Spieler2 wähle 3 Zahlen
Spieler3 wähle 3 Zahlen
Unbeteiligter wähle Siegerzahl
Wenn Zahl1 oder Zahl2 oder Zahl3 von Spieler1 ist Siegerzahl dann
Gratuliere Spieler 1
Wenn Zahl1 oder Zahl2 oder Zahl3 von Spieler2 ist Siegerzahl dann
Gratuliere Spieler 2
Wenn Zahl1 oder Zahl2 oder Zahl3 von Spieler3 ist Siegerzahl dann
Gratuliere Spieler 3
sonst
Es gibt keinen Sieger
ende
er würde also 1:1 den selben Fehler auch im Psoudocode machen..
Robert L. schrieb:> in deinem Psoudo Code ist das "einrücken" von essentieller> Bedeutung, in C überhaupt nicht..
Siehst Du: Das ist schon das erste Problem:
Wenn man nicht vernünftig einrückt, macht man mehr Fehler, die man
länger suchen muß.
Ich habe gelernt: Programmiert wird zunächst auf einem Blatt Papier
mit
Bleistift und Radiergummi in der Hand. In Pseudocode.
Man kann dann das Ganze erst einmal "durchspielen", um Logikfehler zu
entdecken, BEVOR man den Kram in der jeweiligen Sprache am Rechner
umsetzt. Da bleiben dann immer noch mehr als genug Möglichkeiten für
syntaktische Fehler. Gerade bei C heißt das nicht unbedingt, daß ein
sytaktischer Fehler auch als solcher erkannt wird. Das Programm läßt
sich u.U. trotzdem kompilieren, macht aber etwas völlig Anderes, als man
geplant hatte.
Oder es wird etwas wegoptimiert, was ich aber nicht grundlos so haben
wollte. So etwas brauche ich nicht...
MfG Paul
Robert L. schrieb:> ausserdem geht aus dem "Psoudo Code" nicht wirklich hervor wie> "Niemanden wurde gratuliert" zustande kommt..
Das ist aber gerade das essentielle an einem Pseudo Code, dass er einem
aufzeigt, wo man noch Definitionsbedarf hat. Dann kümmert man sich
zuerst um genau diese Problemkreise, ehe man sich dann in das für die
Problemlösung unwichtige Problem der syntaktischen Feinheiten begibt.
Denn gerade Neulinge unterschätzen diesen Teil vollkommen. Ehe man ein
Programm schreiben kann, muss man sich über alle logischen Details und
Abhängigkeiten im klaren sein. Zumindest über die meisten. Das was man
dann noch übersehen hat, das zeigt einem dann schon der Rechner - und
das gnadenlos.
Aber, und das ist das wichtige, man kann sich auf die Logik
konzentrieren. Es ist völlig egal, ob irgendwo ein ; vergessen wurde
oder man einen Fehler in der Gross-Kleinschreibung hat. Das alles hält
nur auf. Dafür kann man sich auf die Fragestellung konzentrieren: Hä? Da
steht "keinem wurde gratuliert" - "Wie mache ich das, woher weiss ich
das?" Wissen durch Hinsehen gilt nicht, ich muss mir dafür schon eine
Kochbuch-Regelung einfallen lassen.
Robert L. schrieb:> Start> Spieler1 wähle 3 Zahlen> Spieler2 wähle 3 Zahlen> Spieler3 wähle 3 Zahlen> Unbeteiligter wähle Siegerzahl> Wenn Zahl1 oder Zahl2 oder Zahl3 von Spieler1 ist Siegerzahl dann> Gratuliere Spieler 1> Wenn Zahl1 oder Zahl2 oder Zahl3 von Spieler2 ist Siegerzahl dann> Gratuliere Spieler 2> Wenn Zahl1 oder Zahl2 oder Zahl3 von Spieler3 ist Siegerzahl dann> Gratuliere Spieler 3> sonst> Es gibt keinen Sieger>> ende>> er würde also 1:1 den selben Fehler auch im Psoudocode machen..
Ja. Und wenn er diesen Pseudocode als menschlicher Computer dann
probeweise mal durchspielt, dann würde er den logischen Fehler auch
bemerken.
Münze an eine Anweisung setzen und dann genau das und nur das im Kopf
'abarbeiten' was dort steht. Nicht was man sich denkt was dort stehen
sollte, nicht was man vor hatte, sondern genau und 100% das was man
hingeschrieben hat. Danach Münze entsprechend weiterrücken und weiter
machen.
>sondern genau und 100% das was man>hingeschrieben hat
damit das funktioniert, müsste der Pseudocode bis ins kleinste Detail
mit Regeln versehen werden, der unterschied zu echtem code (Pascal z.b)
wäre minimal..
ein Anfänger müsste also nicht nur die Syntax von C sondern auch
gleichzeitig die Syntax des Psoudocode lernen
(wenn die Syntax dann auch noch verschieden ist, siehe einrücken usw.
wird ihn das eher verwirren als helfen) ..
nur als Beispiel, müsste man
anstelle von:
Wenn Zahl1 oder Zahl2 oder Zahl3 von Spieler1 ist Siegerzahl dann
sowas schreiben:
Wenn ("Zahl1 von Spieler1" ist Siegerzahl) oder ("Zahl2 von Spieler1"
ist Siegerzahl) oder ("Zahl3 von Spieler1" ist Siegerzahl) dann
damit das überhaupt "klar definiert ist" ...
hätte der TO hingegen den Code aus dem Ausgangsposting nur EINMAL
schritt für schritt im Debugger durchlaufen lassen, hätte er den Fehler
wesentlich schneller als mit Bleistift auf Papier und Pseudocode
gefunden..
ps. ich sag ja nicht, dass man sich nicht das grobe Konzept als
Ablaufplan (aber natürlich auch mit einer Software, nicht am papier)
erstellt.. aber doch nicht 1:1 das ganze Programm als Pseudocode das
dann auch noch "per hand Debugger" durchspielbar sein soll, vielleicht
noch mit Kreide und Tafel, wo man sie dich Variablen und deren aktuelle
werte notiert???
Robert L. schrieb:>>sondern genau und 100% das was man>>hingeschrieben hat>> damit das funktioniert, müsste der Pseudocode bis ins kleinste Detail> mit Regeln versehen werden, der unterschied zu echtem code (Pascal z.b)> wäre minimal..>> ein Anfänger müsste also nicht nur die Syntax von C sondern auch> gleichzeitig die Syntax des Psoudocode lernen
Der Unterschied ist, dass die Syntax von Pseudocode ziemlich unwichtig
ist, solange man sich selbst noch auskennt, wie etwas zu lesen ist.
Pseudocode darf jeder schreiben, wie es ihm gefällt. Deshalb ja auch
'Pseudo'. Der Focus liegt auf der Logik und nicht auf syntaktischen
Spitzfindigkeiten. Der Schritt kommt nachher: Wie wird das was ich mir
beim hinschreiben ausgedacht habe in meiner konkreten Programmiersprache
umgesetzt?
Die Idee dahinter ist es ja nicht, noch eine weitere Programmiersprache
vorzuschreiben, sondern den Neuling dazu anzuregen, sich auf einfache
Weise und losgelöst von syntaktischen Zwängen sich über Abläufe klar zu
werden. Dinge mit einem Federstrich umändern zu können ohne erst mal 2
Stunden lang in einem Fachbuch nach der korrekten Syntax suchen zu
müssen.
Robert L. schrieb:> damit das funktioniert, müsste der Pseudocode bis ins kleinste Detail> mit Regeln versehen werden
Ich finde daher einen PAP besser, um den Überblick zu behalten.
Da sieht man dann genau, wohin mit einer Entscheidung verzweigt wird.
Peter D. schrieb:> Ich finde daher einen PAP besser, um den Überblick zu behalten.> Da sieht man dann genau, wohin mit einer Entscheidung verzweigt wird.
Da stimme ich zum Teil zu. Für Anfänger ist ein PAP ein gutes Werkzeug;
ich schreibe lieber direct (pseudo) C-Code. Nachteil von ein PAP ist das
man sich, vor allem wenn das Problem ein bisschen komplexer wird,
schnell in allen sich überkreuzenden Linien verliert.
Pseudocode soll, wie auch KH schon erklärt hat, dem Benutzer helfen sein
Problem (und Lösung) zu beschreiben, ohne sich zu sehr auf
Programmier-syntax konzentrieren zu müssen. Wie diese Pseudocode
aussieht ist dem Benutzer völlig frei. Was ich da hingepinselt habe war
nur ein Beispiel.
Ich hätte statt
1
FÜRJEDENSpieler:
auch schreiben können:
1
FORPlayer=1TONrOfPlayers:
oder
Letztendlich ist der Dreh- und Angelpunkt, dass man eine Aufgabe in
kleinere, einfacher zu verarbeitenden Schritten "zerlegt" und so sein
Programm Struktur gibt. Etwa so:
1
#define NPLAYERS 3
2
#define NTRIES 3 /* Nr of tries for each player */
3
4
inttries[NPLAYERS][NTRIES];
5
6
/*** insert forward declarations here ***/
7
8
intmain()
9
{
10
print_title();
11
read_all_player_input();
12
read_winning_number();
13
determine_winner();
14
}
15
16
voidprint_title()
17
{
18
printf("!! WELCOME TO LOTTO !!\n\n");
19
}
20
21
voidread_all_player_input()
22
{
23
/* Get all player input */
24
for(intp=0;p<NPLAYERS;p++)
25
{
26
printf("Player %d:\n\n",p);
27
for(intt=0;t<NTRIES;t++)
28
{
29
read_player_try(p,t);
30
}
31
}
32
}
33
34
voidread_player_try(intp,intt)
35
{
36
printf("Player %d:\n",p);
37
do
38
{
39
printf(" Enter your number %d:\n",t);
40
scanf("%i",&(tries[p][t]);
41
42
boolin_use=verify_try(p,t);
43
if(in_use)
44
{
45
printf(
46
" ** Sorry, %d is already in use. Pick another number...\n",