Hirdetés

Új hozzászólás Aktív témák

  • kpisti1990
    csendes tag

    A "while( 1 )" az végtelen ciklust jelent, mindig fut a kód amíg nem lépsz ki a ciklusból (például egy "break"-kel). A return-t el sem éri.
    Amire gondolni tudok, hogy ez a ciklus a gépeden natívan fut, ergo nagyon gyors - az egyetlen hely ahol várakozik, az a billentyű lenyomása. Tehát amikor lenyomod a billentyűt, azt gyorsan kiértékeli és végig pörög a statemachine-en végül minden kezdődik elölről; de te még mindig ugyanazt a billentyűt nyomod, ezért úgy tűnik, mintha ismételné magát a program, pedig csak többször lefutott. Ez csak egy tipp, sajnos nem ismerem a stdio-t annyira, hogy megtudjam mondani valóban ez történik a te esetedben is.

    Úgyhogy, lehet hogy érdemes lenne valami lassítást rakni az állapotgépedbe:
    - ALAP: ide nem kell, mert itt várakozik egy billentyű lenyomásra
    - FIZETETT: ide valamilyen késleltető függvény, ami érzékelhetően feltartatja a programfutást (~1s kb.), tehát kiírja a szöveget, majd várakozik és utána lép a következő állapotba
    - KESZ: itt ezt írod "-végén (ital elvételekor) álljon vissza alap állapotba", ebből nekem úgy tűnik, hogy valamilyen gombbal kell jelezni, hogy elvetted az italt, tehát az is billentyű beolvasás kell, hogy legyen.

    case FIZETETT:
    {
    printf( "valami szöveg\n" );
    kesleltet_ms( 1000 );
    state = KESZ;
    break;
    }

    A "kesleltet_ms()" pedig egy nagyon hosszú ciklus, ami a megadott milliszekundumnyi ideig várakozik:

    void kesleltet_ms ( int ms )
    {
    while ( ms )
    {
    ms--;
    for ( int c = 0; c < 65535; c++ )
    {
    /* ez itt ures */
    }
    }
    }

    Ez egy nagyon kezdetleges megoldás, a belső "for" ciklust úgy kell tuningolni, hogy nagyjából 1 milliszekundum alatt érjen végig, szóval a c-t addig kell növelni.
    Két nagyon fontos dolog:
    - fordítás mindenféle optimalizáció nélkül (hogy biztosan benne legyen a lefordított kódban a ciklus és végig is menjen rendesen)
    - a típusod olyan legyen, amibe a szám amit vizsgálni akarsz még elfér (tehát ha csak 16bites "int"-ed van, abba értelemszerűen 65535-nél nagyobb szám nem fér bele)

    Itt egy profibb megoldás: [The delay() Function]

    A kilépésre meg azt javasolnám, hogy a while( 1 ) helyett legyen valami ilyesmi:

    int bentmarad = 1;
    while ( bentmarad )
    {
    switch ( state )
    {
    case ALAP:
    {
    printf( "szöveg\n" );
    char c = getchar();
    if ( ( c != 'k' ) || ( c != 't' ) || ( c != 'c' ) || ( c != 'q' ) )
    {
    printf( "rossz billentyű\n" );
    }
    else if ( c == 'k' )
    {
    printf( "jó betű 1.\n" );
    state = FIZETETT;
    }
    else if ( c == 't' )
    {
    printf( "jó betű 2.\n" );
    state = FIZETETT;
    }
    else if ( c == 'q' )
    {
    printf( "viszlát\n" );
    bentmarad = 0;
    }
    ...

    Tehát egy külön billentyűvel megszakítod az egész ciklust - persze, ha a feladatkiírás ezt nem teszi lehetővé, akkor nem kell belerakni a végleges kódba.

    Szia!

    Igen, leírásban IR szenzor ad jelet ha elvették az italt, itt én arra gondoltam, hogy egy számláló leszámol pár secundumot és akkor visszaáll. Másként nem igazán lehet szerintem szimulálni. Köszönöm a részletes választ :) kipróbálom, próba cseresznye ahogy egy ősi kínai mondás tartja :D

Új hozzászólás Aktív témák