Mulla on c ohjelmoinnissa yks peli semmosessa pisteessä että sen pitäis enää kysyy että pelataanko uudelleen k/e? ja sit ku painaa k niin se jakaa alottaa alusta. Millä koodilla saan tän toimimaan?? osaako kukaan selittää että mitä pitää pistää ja mihin kohti??pitääkö käyttää while lausetta vai mitä??
Toistolause?
erkki1111
9477
0Äänestä
Muut lukivat myös
Odottaa vastausta
Näihin keskusteluihin ei ole vielä vastattu. Ole ensimmäinen.
Vastaukset 9
Vanhimmat
voit vaikka sulkea koko pelin while-blokin sisään. esim näin:
bool peli_kaynnissa = true;
while(peli_kaynnissa)
{
/// peli tähän
/// peli päättyy, kysytään halutaanko uusi peli
if(ei haluta)
{
peli_kaynnissa = false;
}
}
/// ohjelma palaa tänne kun uutta peliä ei haluta
Saa siinä käyttää ihan yhtä hyvin for-silmukkaa tai gotoa, mutta while on ihan luonnollinen juttu.
Näin se kävis do-while-silmukalla. Oletan, että peli()-funktiolla pelataan se peli ja se palaa, kun peli loppuu. Lue_vastaus taas lukee sen, mitä pelaaja vastaa.
char tulos;
do {
printf ("Aloitan uuden pelin.\n");
peli();
printf ("Haluatko uuden pelin?\n");
tulos = lue_vastaus();
} while (tulos != 'E' || tulos != 'e');
Noita gotoja ei kuulemma saa käyttää, koska ne ovat pahasta. Mutta jos haluat elää vaarallisesti, niin näin voi myös tehdä:
char vastaus;
pelin_alku:
printf ("aloitan pelin\n");
peli ();
kysymys:
printf ("haluatko uuden pelin?\n");
vastaus = lue_vastaus ();
if (vastaus == 'k' || vastaus == 'K')
goto pelin_alku;
if (vastaus == 'e' || vastaus == 'E')
goto lopetus;
else goto kysymys;
lopetus:
printf ("Peli loppui!\n");
printf ("Harmittaako?\n");
Kuten näkyy, tämä goto-versio voi olla aivan selvä, jos ei mene överiksi hyppyjen kanssa. Vaan onhan se joillekin kauhistus, ko ne on ihan _kirjasta_ lukeneet, että goto on huonoa ohjelmointia. "Ei vaan kannata käyttää, ku joku kerran jossain teki huonoa koodia sen kanssa!"
Niin, että tee se niinku parhaaksi näet ite.
> Vaan onhan se joillekin kauhistus, ko ne on ihan
> _kirjasta_ lukeneet, että goto on huonoa
> ohjelmointia. "Ei vaan kannata käyttää, ku joku
> kerran jossain teki huonoa koodia sen kanssa!"
Suosittelen käyttämään lohkorakennetta. Niin teen aina, jos on olemassa riski, että kysyjä omaksuu vain huonomman vaihtoehdon, eli goton. ("Miksi opetella kahta, kun yhdelläkin pärjää.") Vähänkin monimutkaisemmissa ohjelmissa tällä on tietenkin kamalia seurauksia, ja huonoista tavoista on hankalaa opetella myöhemmin eroon.
Ohjelmointikirjat usein kirjoitetaan opetusmielessä, jolloin kohdeyleisöllä ei yleensä ole riittävästi kokemusta ja näkemystä sen arvioimiseksi, kumpi on parempi käytäntö tehdä esim. silmukoita. Hyvin yksinkertaisten ohjelmointiharjoitusten kauttakaan tuota näkemystä ei synny. On siksi luonnollista, että kirjassa asia esitetään valmiiksi pureskeltuna ja kehotetaan välttämään goton käyttöä.
Vasta sitten, kun ymmärtää useamman kuin yhden syyn goton pahuuteen, on minun mielestäni valmis käyttämään gotoa. :)
goto-lausetta ei kannata käyttää kuin joissakin ääritapauksissa (yksi tällainen voi olla jos esimerkiksi konvertoi jotain vanhaa FORTRAN-ohjelmaa ja ei jaksa (tai osaa) strukturoida ohjelmaa uudestaan.).
goto aiheuttaa seuraavat ongelmat:
- vaikeasti luettava koodi
- vaikeasti dokumentoitava koodi
- tavallisesti tehoton koodi
- vaikeasti debuggattava koodi
- jne.
Koska periaatteessa voit hypätä minne tahansa, menetät hallinnan muuttujien tilasta, seurauksena vaikeasti jäljitettäviä virheitä. Tavanomaisen C:n lohkorakenne on olemassa nimenomaan pienentääkseen tätä vaaraa, oliopohjainen C on viennyt asian vielä pidemmälle.
Ei ole mitään tilannetta mitä et pystyisi ohjelmoimaan (tehokkaammin ja selkeämmin) ilman goto.
Sen sijaan break-lauseen ymmärrys on melko huono (se korvaa osittain goto). Sen avulla voi poistua "loopista" (for, while, switch...) ja ohjelman lohkorakenne säilyy:
VÄÄRIN:
for(int i=1;i
Olen siis aivan amatööri tässä hommassa ja koodini on aika yksinkertainen. Sain tänään while lauseella sen verran aikaan että venttipelin jakaa esim. 13 ja sitten kun otan yhden kortin lisää, minulla menee yli, 24 ja sitten se kysyy että pelataanko uudestaan?(K/E) ja kun painaa k, niin se jatkaa taas peliä sillä tavalla että lisää tuohon 24 yhden kortin eli luvuksi tulee joku 30 tai jotain. miten saan tuon while lauseen toimimaan sillalailla että se aloittaa sen ihan alusta eikä jatka peliä?
while(1)
//pelataan black jack
while(1){
//jaa uusi kortti
//tulos yli 21? break;
}
haluatko jatkaa? vastaus = "ei"; break;
} end while
Vaikka goto on paha, se käytöllä on puolensa muutamassa erikoistilanteessa.
Ansi C:ssä ei ole try catch finally tyylistä ratkaisua (longjump on sinnepäin), ja se on erittäin selkeä toteuttaa goto lauseella.
#define FREE(ptr)
if (ptr != NULL) {ASSERT(free(ptr)); ptr = NULL; }
#define MALLOC(ptr,size)
FREE(ptr)
ptr = calloc(size)
if (ptr == NULL) { result = NOMEM; goto cleanup; }
int functio () {
int result = OK;
char *mem0 = NULL;
char *mem1 = NULL;
char *mem2 = NULL;
char *mem3 = NULL;
MALLOC(mem0,500)
for ( ) {
MALLOC(mem2,3)
for ( ) {
MALLOC(mem3,300);
sisäkäisten for luuppien sisällä tapahtuu jotain... aseta errorkoodi ja goto cleanup
}
}
cleanup:
FREE(mem0);
FREE(mem1);
FREE(mem2);
FREE(mem3);
return result;
}
Saahan tuon toteutaa tähään tyyliin
mem0 = malloc()
if (mem0) {
mem1 = malloc()
if (mem1) {
} else {
free(mem0);
return NOMEM;
}
}
}
ja kylvää ylimääräisiä muuttujia for luupeihin returnia varten.
Ja mitä goton tehokuuteen tulee gccssä goto ja labelit hakaavat tehokuudessa switch case:n.
jos mennään korkeamman tieteen puolelle, goto lauseella on monta käyttötarkoitusta. Esimerkiksi MacIntosh tiedostorakenne on sellainen että et ilman goto-lausetta voi rakentaa draiverin.
TRY-CATCH-ENDTRY-puutteellisuudet cgg:ssä (ne ovat makroja) ei ole mikään syy goto-rakentelmien yllättämiseen.
Jos todella on tarvetta goto-ominaisuuksista, suosittelen inline assembleria (binäärikoodissa suuri osa käskyistä ovat nimenomaan goto-käskyjä). Silloin ainakin osoitat että tiedät mitä olet tekemässä!
Hauskaa että joku tietää edes aavistuksen verran mistä on kysymys, ei päästetä keskustelu saivartelun puolelle!
erityisesti jos käsitellään "nested looppeja" (en tiedä suomennosta) eli
{
for(lauseke1)
for(lauseke2)
...
for(lausekeN)
{
// täällä toteutuu joku ehto jolloin pitäisi hypätä pois kaikista for-silmukoista
goto ulos;
}
ulos:
}
paljon kätevämpi toteuttaa gotolla kuin alkaa säätämään apumuuttujien kanssa.