Toistolause?

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ä??
9477
Äänestä

Muut lukivat myös

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

Äänestä

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.

Äänestä
  • > 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. :)

    Äänestä

  • 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

    Äänestä

  • ei, ei, ei! kirjoitti:

    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ä?

    Äänestä

  • erkki1111 kirjoitti:

    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

    Äänestä

  • ei, ei, ei! kirjoitti:

    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

    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.

    Äänestä

  • idootti koodari kirjoitti:

    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!

    Äänestä

  • paikkansa kirjoitti:

    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.

    Äänestä

Kommentoi aloitusta


erkki1111 kirjoitti:

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ä??

Anonyymi
5000

Ilmoita asiaton sisältö

  • Sisältää materiaalia, joka on loukkaavaa, herjaavaa, rasistista, uhkailevaa tai ahdistelevaa.

  • Materiaali sisältää nimiä, yhteystietoja tai muita henkilökohtaisia tietoja. Julkisuuden henkilöistä, julkisissa viroissa toimivista ihmisistä sekä yritysten vastuuhenkilöistä saa keskustella työhön liittyen. Myös yksityiselämään liittyvistä asioista voi keskustella siltä osin, kuin niistä on julkisesti kerrottu.

  • Sisältää lapsille haitallista tai heiltä kiellettyä materiaalia. Seksuaalinen sisältö on sallittua aiheeseen tarkoitetuilla palstoilla, joiden ikäraja on 18 vuotta.

  • Lainvastaista sisältöä voi olla mm. yksityiselämää loukkaavan tiedon levitys, kiihottaminen kansanryhmää vastaan, laiton uhkaaminen, alaikäisiin liittyvä seksuaalinen sisältö/grooming, petokset, identiteettivarkaudet, kunnianloukkaukset ja tekijänoikeusrikkomukset.

  • Sisältö ei liity palstan tai keskusteluketjun aiheeseen.

  • Viesti ei ole suomea tai ruotsia (pl. International Forums), se sisältää mainontaa, se sisältää tekijänoikeuksin suojattua materiaalia, se on massapostitus tai jokin muu syy.

Jaa keskustelu