Hirdetés

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

  • nevemfel
    senior tag

    A goto használatának kerülése minden strukturális programnyelvben ajánlott, ez kivétel nélkül így van. Az okostojások persze mindig kardoskodnak mellette, de Dijkstra "Go To Statement Considered Harmful" 1968-as írása ugyanúgy érvényes ma is.

    C-nél annyiban más a helyzet, hogy a C nem magas szintű programnyelv. Ami a break-et illeti, annak a használata időnként elkerülhetetlen, pl. a switch case szerkezet esetében, ami tulajdonképpen egy kalkulált goto.

  • nevemfel
    senior tag

    Innen:

    Bármennyire is adott azonban a lehetőség a Goto használatára, ne használjuk. Nincs olyan probléma, amely ne lenne megoldható nélküle is, használatával azonban áttekinthetetlenné válik a programunk, és ezzel a hibalehetőségek száma növekszik.

    Továbbá:

    A Goto parancs sok nyelvben létezik, használatát azonban el kell kerülni. Léteztek olyan ősnyelvek, amelyekben nélkülözhetetlen volt, a mai magasszintű nyelvekbe azonban többnyire hagyománytiszteletből került be, nincs rá szükség. Léteznek olyan nyelvek is, amelyekből hiányzik ez a parancs.

    Ezért hasonlítom össze a C-t meg a Pascalt(meg minden olyan nyelvet, amiben létezik). Mindenesetre a fenti idézetek sem Stroustrup nézőpontját hangoztatják, hanem László Józsefét. Sőt, a második idézet egyértelműen kimondja, hogy léteznek olyan nyelvek is amelyekből hiányzik. Ezek szerint azokban a nyelvekben nem is lehet programozni, igaz?

    A goto használatának kerülése minden strukturális programnyelvben ajánlott, ez kivétel nélkül így van. Az okostojások persze mindig kardoskodnak mellette, de Dijkstra "Go To Statement Considered Harmful" 1968-as írása ugyanúgy érvényes ma is.

  • gregory91
    senior tag

    A continue tiltásán 1 kicsit én is csodálkozom. Ami okot adhat erre, az talán az, hogy a ciklusnak alapvetően 2 lényeges pontja van: az eleje és a vége. A continue ezt rúgja fel. Gyakorlatilag így több (kis)ciklus lesz a (nagy)ciklusban, ami egyébként elkerülhető. Sztem ez lehet valamiféle ok a tiltására. De mondjuk ezt én nem venném fel a "soha" kezdetű listámra.

    Csak bizonyos esetekben a ciklusok képesek feleslegesen lefutni ,felesleges cpu terhelést, növelt futási időt képes adni,a continue bizonyos feltételek közt képes ezt a problémát orvosolni.

    #6188: A break-ről is ugyan ezt gondolom.

  • pmonitor
    aktív tag

    Nem, semmit nem jelent.
    De azt sem tudom mit jelent, hogy simán összehasonlítod a C-t meg a Pascalt és azt sem érted hogy ezen élcelődök...

    Innen:

    Bármennyire is adott azonban a lehetőség a Goto használatára, ne használjuk. Nincs olyan probléma, amely ne lenne megoldható nélküle is, használatával azonban áttekinthetetlenné válik a programunk, és ezzel a hibalehetőségek száma növekszik.

    Továbbá:

    A Goto parancs sok nyelvben létezik, használatát azonban el kell kerülni. Léteztek olyan ősnyelvek, amelyekben nélkülözhetetlen volt, a mai magasszintű nyelvekbe azonban többnyire hagyománytiszteletből került be, nincs rá szükség. Léteznek olyan nyelvek is, amelyekből hiányzik ez a parancs.

    Ezért hasonlítom össze a C-t meg a Pascalt(meg minden olyan nyelvet, amiben létezik). Mindenesetre a fenti idézetek sem Stroustrup nézőpontját hangoztatják, hanem László Józsefét. Sőt, a második idézet egyértelműen kimondja, hogy léteznek olyan nyelvek is amelyekből hiányzik. Ezek szerint azokban a nyelvekben nem is lehet programozni, igaz?

  • buherton
    őstag

    Ez a coding style vagy coding rules az NI LabWindows CVI-ban programozott GUI-s projekthez kell (rémisztően csak C-ben lehet használni ezt a GUI-s frameworköt). Én eddig a neten mindenhol azt olvasom és azt tanították nekem, hogy a globális változó egy nagy programban már szigorúan kerülendő (itt már nem 8 bites microcontroller a cél HW), jelenleg ahova kellene az már egy nagy program, tele káosszal már sajnos. Valamint ELTE IK C/C++ gyakorlaton instant évismétlés járt a go to és continue használatért, és értettem hogy miért, miután egyszer valaha valami tele go to-zott programot kellett debugolnom, és visszafejtenem. Fenntarthatatlan és karbantarthatatlan lesz a program tőle.

    Az Ericsson-os codechekker az Windwos 10-en is életre kelthető? Ez a CVI fordító és IDE csak Windows 10-en megy, ebben megy a napi munka.

    Aki tanított neked az egyetemen kívül nem dolgozott. A papír/publikáció sok mindent elbír.

    Ha bármelyik nyelvi elemet nem úgy használod ahogy kell, akkor is olvashatatlan és debuggolhatatlan lehet a kód.

    Nem hiszem, esetleg WSL-ben mehet, azt próbáltad már?

    Windows-on fejleszteni :Y .

  • sztanozs
    veterán

    Az első mondatom meg szerintem nem értetted meg. Azt a goto-ra írtam.
    Csak azért leírtam, hogy komoly könyv írója is tiltja a goto-t nem véletlenül.
    Meg leírtam, hogy ezzel virtuálisan jól összeugrasztottam Stroustrup-ot és László Józsefet.

    Még a szakik sem értenek mondjuk egyet. De László József nem egy könyvet írt meg goto nélkül. Ez azért valamit csak jelent, nem?

    Nem, semmit nem jelent.
    De azt sem tudom mit jelent, hogy simán összehasonlítod a C-t meg a Pascalt és azt sem érted hogy ezen élcelődök...

  • pmonitor
    aktív tag

    És? Semmi olyat nem szerkesztettél bele, ami bármilyen szempontból releváns lenne :DDD

    Mondjuk azt sem hiszem hogy Stroustrup túl sokat programozott volna pascalban, hogy László Józseffel összeugorjon a magyar nyelvű kommenteken. :U

    Az első mondatom meg szerintem nem értetted meg. Azt a goto-ra írtam.
    Csak azért leírtam, hogy komoly könyv írója is tiltja a goto-t nem véletlenül.
    Meg leírtam, hogy ezzel virtuálisan jól összeugrasztottam Stroustrup-ot és László Józsefet.

    Még a szakik sem értenek mondjuk egyet. De László József nem egy könyvet írt meg goto nélkül. Ez azért valamit csak jelent, nem?

  • sztanozs
    veterán

    Azalatt válaszoltál, mialatt szerkesztettem a hozzászólásom.

    És? Semmi olyat nem szerkesztettél bele, ami bármilyen szempontból releváns lenne :DDD

    Mondjuk azt sem hiszem hogy Stroustrup túl sokat programozott volna pascalban, hogy László Józseffel összeugorjon a magyar nyelvű kommenteken. :U

  • pmonitor
    aktív tag

    Már hogyne lenne goto, nézd meg mit csinál belőle a compiler.
    Mert break-kel ki tudsz lépni if-ből, vagy előrefelé ugrani?

    Azalatt válaszoltál, mialatt szerkesztettem a hozzászólásom.

  • sztanozs
    veterán

    A break nem goto. Nem lehet vele visszafelé ugrani, meg if-es szerkezetekből sem tudsz kilépni vele.

    Ebben a könyvben László József a következőket írja(többek között):
    >A Pascal programokban betartunk még néhány hasznosnak vélt egyéb konvenciót is:
    1: Angol elnevezést adunk az eljárásoknak, függvényeknek, típusoknak, változóknak, stb.,
    .
    3: A megjegyzéseket magyarul írjuk, lehetőleg minél tömörebben,
    .
    5: A goto utasítást a Pascal-ban nem használjuk, mert ugye programozók vagyunk.

    Na, most virtuálisan jól összeugrasztottam Stroustrup-ot és László Józsefet. :)

    Már hogyne lenne goto, nézd meg mit csinál belőle a compiler.
    Mert break-kel ki tudsz lépni if-ből, vagy előrefelé ugrani?

  • pmonitor
    aktív tag

    Én a break-et is tiltanám, biztos-ami-biztos alapon. Végül is az is csak egy goto (coated in synthetic sugar)...

    A break nem goto. Nem lehet vele visszafelé ugrani, meg if-es szerkezetekből sem tudsz kilépni vele.

    Ebben a könyvben László József a következőket írja(többek között):
    >A Pascal programokban betartunk még néhány hasznosnak vélt egyéb konvenciót is:
    1: Angol elnevezést adunk az eljárásoknak, függvényeknek, típusoknak, változóknak, stb.,
    .
    3: A megjegyzéseket magyarul írjuk, lehetőleg minél tömörebben,
    .
    5: A goto utasítást a Pascal-ban nem használjuk, mert ugye programozók vagyunk.

    Na, most virtuálisan jól összeugrasztottam Stroustrup-ot és László Józsefet. :)

  • #90088192
    törölt tag

    Én a break-et is tiltanám, biztos-ami-biztos alapon. Végül is az is csak egy goto (coated in synthetic sugar)...

    Még milyen dolog a return, tessék rekurziv logikát használni ;]

  • sztanozs
    veterán

    "Valamint ELTE IK C/C++ gyakorlaton instant évismétlés járt a go to és continue használatért,"

    A continue tiltásásért én adnék egy évismétlést..... :C

    Én a break-et is tiltanám, biztos-ami-biztos alapon. Végül is az is csak egy goto (coated in synthetic sugar)...

  • pmonitor
    aktív tag

    "Valamint ELTE IK C/C++ gyakorlaton instant évismétlés járt a go to és continue használatért,"

    A continue tiltásásért én adnék egy évismétlést..... :C

    A continue tiltásán 1 kicsit én is csodálkozom. Ami okot adhat erre, az talán az, hogy a ciklusnak alapvetően 2 lényeges pontja van: az eleje és a vége. A continue ezt rúgja fel. Gyakorlatilag így több (kis)ciklus lesz a (nagy)ciklusban, ami egyébként elkerülhető. Sztem ez lehet valamiféle ok a tiltására. De mondjuk ezt én nem venném fel a "soha" kezdetű listámra.

  • dabadab
    titán

    "Valamint ELTE IK C/C++ gyakorlaton instant évismétlés járt a go to és continue használatért,"

    A continue tiltásásért én adnék egy évismétlést..... :C

    Szerintem a "C/C++" is megérne egy évismétlést :D

  • gregory91
    senior tag

    Ez a coding style vagy coding rules az NI LabWindows CVI-ban programozott GUI-s projekthez kell (rémisztően csak C-ben lehet használni ezt a GUI-s frameworköt). Én eddig a neten mindenhol azt olvasom és azt tanították nekem, hogy a globális változó egy nagy programban már szigorúan kerülendő (itt már nem 8 bites microcontroller a cél HW), jelenleg ahova kellene az már egy nagy program, tele káosszal már sajnos. Valamint ELTE IK C/C++ gyakorlaton instant évismétlés járt a go to és continue használatért, és értettem hogy miért, miután egyszer valaha valami tele go to-zott programot kellett debugolnom, és visszafejtenem. Fenntarthatatlan és karbantarthatatlan lesz a program tőle.

    Az Ericsson-os codechekker az Windwos 10-en is életre kelthető? Ez a CVI fordító és IDE csak Windows 10-en megy, ebben megy a napi munka.

    "Valamint ELTE IK C/C++ gyakorlaton instant évismétlés járt a go to és continue használatért,"

    A continue tiltásásért én adnék egy évismétlést..... :C

  • pmonitor
    aktív tag

    Valamint ELTE IK C/C++ gyakorlaton instant évismétlés járt a go to és continue használatért, és értettem hogy miért, miután egyszer valaha valami tele go to-zott programot kellett debugolnom, és visszafejtenem. Fenntarthatatlan és karbantarthatatlan lesz a program tőle.

    A hülyén használt gototól. Ez pont olyan, mint amikor idióta magyartanárok előveszik a "macska fel van mászva a fára" mondatot, hogy ezzel szemléltessék, hogy magyarban miért nem szabad szenvedő szerkezetet használni - csak hát valójában a magyarban a szenvedő szerkezet teljesen rendben van, a macskás példával az a gond, hogy pont azt semmilyen nyelven sem mondják szenvedőben, mert az úgy hülyeség (angolul se mondaná senki, hogy "the cat is on the tree climbed").

    A jól használt goto a C-ben az a jól olvasható kódhoz sok esetben gyakorlatilag elkerülhetetlen. Tipikus példája az, amikor egy függvény több helyen érhet véget, de mindenképpen fel kell szabadítani resource-oket. Ezt mondjuk C++-ban tök faszán lehet csinálni RAII-vel meg finallyvel C#-ban, de azok tök más nyelvek. C-ben nincs ilyen, ott vagy minden helyre külön odakopipészteled a felszabadítást, vagy mindenhonnan a végére gotozol. Egyértelmű, hogy az utóbbi megoldás az, ami olvashatóbb és ami kevesebb hibalehetőséggel jár.

    A C az gyakorlatilag hordozható assembler, ennek megfelelően kell hozzáállni, aki ott azt mondaná, hogy a JMP használatát el kell kerülni, azt kiröhögnék.

    Stroustrup írta:
    >A "soha ne tegyük ezt" alakú szabályokat haszontalannak tekintem.

    Ez általában igaz, viszont teljesen nem értek vele egyet. Hozzátenném, hogy azért nem ilyen sok van. 2 fő ökölszabály viszont biztos létezik a programozásban:
    1.: SOHA ne használjunk gotot. A Szekvencia - Szelekció - Iterácó hármassal mindent meg lehet oldani. Nincs szükség goto-ra.
    2.: Ha van egy típus, és létezik hozzá olyan függvény/metódus, hogy a konvertál(string s) az adott típusra alakítja a stringet, akkor ezt a konvertál() függvényt/metódust MINDIG használni kell, mielőtt műveletet végzünk vele.

  • pmonitor
    aktív tag

    Ez egészen rettentes, szerintem.

    Az eredetinek van egy teljesen normális logikája, hogy sorban megy végig a lépéseken és ha bármelyik nem sikerül, akkor game over. Ez meg gondos átolvasást igényel, hogy az ember rájöjjön, hogy mi is történik itt - mert maga a struktúra azt sugallja, hogy háromféle, nagyjából egyenértékű dologgal próbálkozunk, amiből az egyiknek kellene sikerülnie.

    Ilyen alapon az én első kódomon is világosan látszik, hogy sorban megy végig a lépéseken és ha bármelyik nem sikerül, akkor game over., hogy téged idézzelek. Olvashatóságra az sem rossz. De nevemfel-é mégis jobb. De az sem sokkal rosszabbul olvasható.

  • dabadab
    titán

    Ez se okés így? :

    static int kvm_vcpu_check_block(struct kvm_vcpu *vcpu)
    {
    int ret = 0;
    int idx = srcu_read_lock(&vcpu->kvm->srcu);

    if (kvm_arch_vcpu_runnable(vcpu)) {
    kvm_make_request(KVM_REQ_UNHALT, vcpu);
    ret = -EINTR;
    } else if (kvm_cpu_has_pending_timer(vcpu)) {
    ret = -EINTR;
    } else if (signal_pending(current)) {
    ret = -EINTR;
    }

    srcu_read_unlock(&vcpu->kvm->srcu, idx);
    return ret;
    }

    Ez egészen rettentes, szerintem.

    Az eredetinek van egy teljesen normális logikája, hogy sorban megy végig a lépéseken és ha bármelyik nem sikerül, akkor game over. Ez meg gondos átolvasást igényel, hogy az ember rájöjjön, hogy mi is történik itt - mert maga a struktúra azt sugallja, hogy háromféle, nagyjából egyenértékű dologgal próbálkozunk, amiből az egyiknek kellene sikerülnie.

  • pmonitor
    aktív tag

    Ez se okés így? :

    static int kvm_vcpu_check_block(struct kvm_vcpu *vcpu)
    {
    int ret = 0;
    int idx = srcu_read_lock(&vcpu->kvm->srcu);

    if (kvm_arch_vcpu_runnable(vcpu)) {
    kvm_make_request(KVM_REQ_UNHALT, vcpu);
    ret = -EINTR;
    } else if (kvm_cpu_has_pending_timer(vcpu)) {
    ret = -EINTR;
    } else if (signal_pending(current)) {
    ret = -EINTR;
    }

    srcu_read_unlock(&vcpu->kvm->srcu, idx);
    return ret;
    }

    A konkrét példára sztem. a tiéd a legjobb. De az mindenképpen látszik, hogy a logikai háló megtervezésével mellőzhető a goto.

  • pmonitor
    aktív tag

    Ez se okés így? :

    static int kvm_vcpu_check_block(struct kvm_vcpu *vcpu)
    {
    int ret = 0;
    int idx = srcu_read_lock(&vcpu->kvm->srcu);

    if (kvm_arch_vcpu_runnable(vcpu)) {
    kvm_make_request(KVM_REQ_UNHALT, vcpu);
    ret = -EINTR;
    } else if (kvm_cpu_has_pending_timer(vcpu)) {
    ret = -EINTR;
    } else if (signal_pending(current)) {
    ret = -EINTR;
    }

    srcu_read_unlock(&vcpu->kvm->srcu, idx);
    return ret;
    }

    Én is gondoltam erre. Csak az a baj vele sztem. hogy feltételezi, hogy ha az előző feltételbe belemegy, akkor annak mindenképpen kilépés lesz a vége. Bár a konkrét példában ez a helyzet. De még azon belül is lehetnek if-ek.

  • nevemfel
    senior tag

    Igazából meg lehet csinálni egymásba ágyazott ifekkel, de az meg a struktúrát bonyolítja el.

    Ez se okés így? :

    static int kvm_vcpu_check_block(struct kvm_vcpu *vcpu)
    {
    int ret = 0;
    int idx = srcu_read_lock(&vcpu->kvm->srcu);

    if (kvm_arch_vcpu_runnable(vcpu)) {
    kvm_make_request(KVM_REQ_UNHALT, vcpu);
    ret = -EINTR;
    } else if (kvm_cpu_has_pending_timer(vcpu)) {
    ret = -EINTR;
    } else if (signal_pending(current)) {
    ret = -EINTR;
    }

    srcu_read_unlock(&vcpu->kvm->srcu, idx);
    return ret;
    }

  • dabadab
    titán

    De ez orvosolható azzal, ha else-t is használunk a megfelelő helyen.

    Igazából meg lehet csinálni egymásba ágyazott ifekkel, de az meg a struktúrát bonyolítja el.

  • pmonitor
    aktív tag

    Ezzel (meg nevemfel megoldásával) elég nyilvánvalóan az a gond, hogy olyan függvényeket is meghívsz, amiket nem kellene (szabadna) és a kód azt mondja, hogy az, hogy h a vcpu nem runnable, az még tök oké, mert attól még csinálhatunk itt dolgokat, noha ennek pont az ellenkezője a helyzet.

    Így?

    static int kvm_vcpu_check_block(struct kvm_vcpu* vcpu)
    {
    int ret = 0;
    int idx = srcu_read_lock(&vcpu->kvm->srcu);
    int ex = 0;
    if (kvm_arch_vcpu_runnable(vcpu)) {
    kvm_make_request(KVM_REQ_UNHALT, vcpu);
    ret = -EINTR;
    ex = 1;
    }
    if (!ex && kvm_cpu_has_pending_timer(vcpu))
    {
    ret = -EINTR;
    ex = 1;
    }
    if (!ex && signal_pending(current))
    {
    ret = -EINTR;
    }

    srcu_read_unlock(&vcpu->kvm->srcu, idx);
    return ret;
    }

  • nevemfel
    senior tag

    Ezzel (meg nevemfel megoldásával) elég nyilvánvalóan az a gond, hogy olyan függvényeket is meghívsz, amiket nem kellene (szabadna) és a kód azt mondja, hogy az, hogy h a vcpu nem runnable, az még tök oké, mert attól még csinálhatunk itt dolgokat, noha ennek pont az ellenkezője a helyzet.

    De ez orvosolható azzal, ha else-t is használunk a megfelelő helyen.

  • dabadab
    titán

    Én ilyenkor inkább így szoktam:

    static int kvm_vcpu_check_block(struct kvm_vcpu *vcpu)
    {
    int ret = 0;
    int idx = srcu_read_lock(&vcpu->kvm->srcu);

    if (kvm_arch_vcpu_runnable(vcpu)) {
    kvm_make_request(KVM_REQ_UNHALT, vcpu);
    ret = -EINTR;
    }
    if (kvm_cpu_has_pending_timer(vcpu))
    {
    ret = -EINTR;
    }
    if (signal_pending(current))
    {
    ret = -EINTR;
    }

    srcu_read_unlock(&vcpu->kvm->srcu, idx);
    return ret;
    }

    Persze ekkor az nincs lekezelve, hogy a többi if-et kihagyja a returnbe érés előtt, ez kérdés szabad-e ebben a Linux driverben.

    Ezzel (meg nevemfel megoldásával) elég nyilvánvalóan az a gond, hogy olyan függvényeket is meghívsz, amiket nem kellene (szabadna) és a kód azt mondja, hogy az, hogy h a vcpu nem runnable, az még tök oké, mert attól még csinálhatunk itt dolgokat, noha ennek pont az ellenkezője a helyzet.

  • nevemfel
    senior tag

    Én ilyenkor inkább így szoktam:

    static int kvm_vcpu_check_block(struct kvm_vcpu *vcpu)
    {
    int ret = 0;
    int idx = srcu_read_lock(&vcpu->kvm->srcu);

    if (kvm_arch_vcpu_runnable(vcpu)) {
    kvm_make_request(KVM_REQ_UNHALT, vcpu);
    ret = -EINTR;
    }
    if (kvm_cpu_has_pending_timer(vcpu))
    {
    ret = -EINTR;
    }
    if (signal_pending(current))
    {
    ret = -EINTR;
    }

    srcu_read_unlock(&vcpu->kvm->srcu, idx);
    return ret;
    }

    Persze ekkor az nincs lekezelve, hogy a többi if-et kihagyja a returnbe érés előtt, ez kérdés szabad-e ebben a Linux driverben.

    Én is így okoskodtam:

    static int kvm_vcpu_check_block(struct kvm_vcpu *vcpu)
    {
        int ret = 0;
        int idx = srcu_read_lock(&vcpu->kvm->srcu);
        if (kvm_arch_vcpu_runnable(vcpu)) {
            kvm_make_request(KVM_REQ_UNHALT, vcpu);
            ret = -EINTR;
        }
        if (kvm_cpu_has_pending_timer(vcpu) || signal_pending(current)) {
            ret = -EINTR;
        }
        srcu_read_unlock(&vcpu->kvm->srcu, idx);
        return ret;
    }

    (ez a kódformázás, ehh...)

  • pmonitor
    aktív tag

    Ez inkább elrettentő példának jó, hogy miért kell mégis a goto.

    De sztem ki lehet az ilyeneket szervezni az ilyent külön függvénybe, és akkor tovább egyszerűsíthető. Azért a gyakorlatban ilyen nem nagyon fordul elő. A papír(vagy a monitor :) ) mindent elbír.

    Szerk.: ja látom Livius gyorsabb volt. Mondtam, hogy csak szervezés kérdése. Csak nem én szerveztem jól.

  • Livius
    őstag

    Akkor tessék, demonstráld:

    static int kvm_vcpu_check_block(struct kvm_vcpu *vcpu)
    {
    int ret = -EINTR;
    int idx = srcu_read_lock(&vcpu->kvm->srcu);

    if (kvm_arch_vcpu_runnable(vcpu)) {
    kvm_make_request(KVM_REQ_UNHALT, vcpu);
    goto out;
    }
    if (kvm_cpu_has_pending_timer(vcpu))
    goto out;
    if (signal_pending(current))
    goto out;

    ret = 0;
    out:
    srcu_read_unlock(&vcpu->kvm->srcu, idx);
    return ret;
    }

    Én ilyenkor inkább így szoktam:

    static int kvm_vcpu_check_block(struct kvm_vcpu *vcpu)
    {
    int ret = 0;
    int idx = srcu_read_lock(&vcpu->kvm->srcu);

    if (kvm_arch_vcpu_runnable(vcpu)) {
    kvm_make_request(KVM_REQ_UNHALT, vcpu);
    ret = -EINTR;
    }
    if (kvm_cpu_has_pending_timer(vcpu))
    {
    ret = -EINTR;
    }
    if (signal_pending(current))
    {
    ret = -EINTR;
    }

    srcu_read_unlock(&vcpu->kvm->srcu, idx);
    return ret;
    }

    Persze ekkor az nincs lekezelve, hogy a többi if-et kihagyja a returnbe érés előtt, ez kérdés szabad-e ebben a Linux driverben.

  • dabadab
    titán

    Ha minden igaz így hirtelen:

    static int kvm_vcpu_check_block(struct kvm_vcpu *vcpu)
    {
    int ret = -EINTR;
    int idx = srcu_read_lock(&vcpu->kvm->srcu);

    if (kvm_arch_vcpu_runnable(vcpu)) {
    kvm_make_request(KVM_REQ_UNHALT, vcpu);
    srcu_read_unlock(&vcpu->kvm->srcu, idx);
    return ret;
    }
    if (kvm_cpu_has_pending_timer(vcpu) || signal_pending(current)) {
    srcu_read_unlock(&vcpu->kvm->srcu, idx);
    return ret;
    }

    ret = 0;
    srcu_read_unlock(&vcpu->kvm->srcu, idx);
    return ret;
    }

    Ez inkább elrettentő példának jó, hogy miért kell mégis a goto.

  • pmonitor
    aktív tag

    Akkor tessék, demonstráld:

    static int kvm_vcpu_check_block(struct kvm_vcpu *vcpu)
    {
    int ret = -EINTR;
    int idx = srcu_read_lock(&vcpu->kvm->srcu);

    if (kvm_arch_vcpu_runnable(vcpu)) {
    kvm_make_request(KVM_REQ_UNHALT, vcpu);
    goto out;
    }
    if (kvm_cpu_has_pending_timer(vcpu))
    goto out;
    if (signal_pending(current))
    goto out;

    ret = 0;
    out:
    srcu_read_unlock(&vcpu->kvm->srcu, idx);
    return ret;
    }

    Ha minden igaz így hirtelen:

    static int kvm_vcpu_check_block(struct kvm_vcpu *vcpu)
    {
    int ret = -EINTR;
    int idx = srcu_read_lock(&vcpu->kvm->srcu);

    if (kvm_arch_vcpu_runnable(vcpu)) {
    kvm_make_request(KVM_REQ_UNHALT, vcpu);
    srcu_read_unlock(&vcpu->kvm->srcu, idx);
    return ret;
    }
    if (kvm_cpu_has_pending_timer(vcpu) || signal_pending(current)) {
    srcu_read_unlock(&vcpu->kvm->srcu, idx);
    return ret;
    }

    ret = 0;
    srcu_read_unlock(&vcpu->kvm->srcu, idx);
    return ret;
    }

  • dabadab
    titán

    > vagy minden helyre külön odakopipészteled a felszabadítást, vagy mindenhonnan a végére gotozol.

    Mindenképpen mindenhová kell kopipésztelned vagy a gotot, vagy a felszabadítást. De sztem. ha ilyenre sor kerül a gyakorlatban, ott nem jól tervezték meg a logikai hálózatot. Biztos vagyok benne, hogy a megfelelő if-ek megválasztásával ha nem is teljesen, de nagyon nagy mértékben megszüntethető a sok helyről történő kilépés a függvényből. Max. 2 helyre nyugodtan lehet kopizni a felszabadítást is. De az is lehet, hogy megfelelő szervezéssel még a 2 helyet is le lehet redukálni egyre(de erre a fejemet nem teszem).

    Akkor tessék, demonstráld:

    static int kvm_vcpu_check_block(struct kvm_vcpu *vcpu)
    {
    int ret = -EINTR;
    int idx = srcu_read_lock(&vcpu->kvm->srcu);

    if (kvm_arch_vcpu_runnable(vcpu)) {
    kvm_make_request(KVM_REQ_UNHALT, vcpu);
    goto out;
    }
    if (kvm_cpu_has_pending_timer(vcpu))
    goto out;
    if (signal_pending(current))
    goto out;

    ret = 0;
    out:
    srcu_read_unlock(&vcpu->kvm->srcu, idx);
    return ret;
    }

  • pmonitor
    aktív tag

    Valamint ELTE IK C/C++ gyakorlaton instant évismétlés járt a go to és continue használatért, és értettem hogy miért, miután egyszer valaha valami tele go to-zott programot kellett debugolnom, és visszafejtenem. Fenntarthatatlan és karbantarthatatlan lesz a program tőle.

    A hülyén használt gototól. Ez pont olyan, mint amikor idióta magyartanárok előveszik a "macska fel van mászva a fára" mondatot, hogy ezzel szemléltessék, hogy magyarban miért nem szabad szenvedő szerkezetet használni - csak hát valójában a magyarban a szenvedő szerkezet teljesen rendben van, a macskás példával az a gond, hogy pont azt semmilyen nyelven sem mondják szenvedőben, mert az úgy hülyeség (angolul se mondaná senki, hogy "the cat is on the tree climbed").

    A jól használt goto a C-ben az a jól olvasható kódhoz sok esetben gyakorlatilag elkerülhetetlen. Tipikus példája az, amikor egy függvény több helyen érhet véget, de mindenképpen fel kell szabadítani resource-oket. Ezt mondjuk C++-ban tök faszán lehet csinálni RAII-vel meg finallyvel C#-ban, de azok tök más nyelvek. C-ben nincs ilyen, ott vagy minden helyre külön odakopipészteled a felszabadítást, vagy mindenhonnan a végére gotozol. Egyértelmű, hogy az utóbbi megoldás az, ami olvashatóbb és ami kevesebb hibalehetőséggel jár.

    A C az gyakorlatilag hordozható assembler, ennek megfelelően kell hozzáállni, aki ott azt mondaná, hogy a JMP használatát el kell kerülni, azt kiröhögnék.

    > vagy minden helyre külön odakopipészteled a felszabadítást, vagy mindenhonnan a végére gotozol.

    Mindenképpen mindenhová kell kopipésztelned vagy a gotot, vagy a felszabadítást. De sztem. ha ilyenre sor kerül a gyakorlatban, ott nem jól tervezték meg a logikai hálózatot. Biztos vagyok benne, hogy a megfelelő if-ek megválasztásával ha nem is teljesen, de nagyon nagy mértékben megszüntethető a sok helyről történő kilépés a függvényből. Max. 2 helyre nyugodtan lehet kopizni a felszabadítást is. De az is lehet, hogy megfelelő szervezéssel még a 2 helyet is le lehet redukálni egyre(de erre a fejemet nem teszem).

  • dabadab
    titán

    A mi C-ben írt CVI projektünkben egyelőre még ez a +10 év alatt jól volt kezelve az ilyen, hogy nincs szükség sehol calloc vagy malloc-ra és azok felszabadítására, tehát amit írsz példát nincs szükségünk rá nagyon, de ettől független láttam már benne go to-t olyan helyen, ahol csak a megértést nehezítette, de azt amit írsz előnyt semmit sem adott.

    BÁRMIT lehet hülyén használni, de ez nem az adott konstrukció hibája. Láttam már megértést nehezítő kommenteket is, de ebből szerintem nem következik az, hogy ne írjunk kommentet :)

  • Livius
    őstag

    Valamint ELTE IK C/C++ gyakorlaton instant évismétlés járt a go to és continue használatért, és értettem hogy miért, miután egyszer valaha valami tele go to-zott programot kellett debugolnom, és visszafejtenem. Fenntarthatatlan és karbantarthatatlan lesz a program tőle.

    A hülyén használt gototól. Ez pont olyan, mint amikor idióta magyartanárok előveszik a "macska fel van mászva a fára" mondatot, hogy ezzel szemléltessék, hogy magyarban miért nem szabad szenvedő szerkezetet használni - csak hát valójában a magyarban a szenvedő szerkezet teljesen rendben van, a macskás példával az a gond, hogy pont azt semmilyen nyelven sem mondják szenvedőben, mert az úgy hülyeség (angolul se mondaná senki, hogy "the cat is on the tree climbed").

    A jól használt goto a C-ben az a jól olvasható kódhoz sok esetben gyakorlatilag elkerülhetetlen. Tipikus példája az, amikor egy függvény több helyen érhet véget, de mindenképpen fel kell szabadítani resource-oket. Ezt mondjuk C++-ban tök faszán lehet csinálni RAII-vel meg finallyvel C#-ban, de azok tök más nyelvek. C-ben nincs ilyen, ott vagy minden helyre külön odakopipészteled a felszabadítást, vagy mindenhonnan a végére gotozol. Egyértelmű, hogy az utóbbi megoldás az, ami olvashatóbb és ami kevesebb hibalehetőséggel jár.

    A C az gyakorlatilag hordozható assembler, ennek megfelelően kell hozzáállni, aki ott azt mondaná, hogy a JMP használatát el kell kerülni, azt kiröhögnék.

    A mi C-ben írt CVI projektünkben egyelőre még ez a +10 év alatt jól volt kezelve az ilyen, hogy nincs szükség sehol calloc vagy malloc-ra és azok felszabadítására, tehát amit írsz példát nincs szükségünk rá nagyon, de ettől független láttam már benne go to-t olyan helyen, ahol csak a megértést nehezítette, de azt amit írsz előnyt semmit sem adott.

  • dabadab
    titán

    Ez a coding style vagy coding rules az NI LabWindows CVI-ban programozott GUI-s projekthez kell (rémisztően csak C-ben lehet használni ezt a GUI-s frameworköt). Én eddig a neten mindenhol azt olvasom és azt tanították nekem, hogy a globális változó egy nagy programban már szigorúan kerülendő (itt már nem 8 bites microcontroller a cél HW), jelenleg ahova kellene az már egy nagy program, tele káosszal már sajnos. Valamint ELTE IK C/C++ gyakorlaton instant évismétlés járt a go to és continue használatért, és értettem hogy miért, miután egyszer valaha valami tele go to-zott programot kellett debugolnom, és visszafejtenem. Fenntarthatatlan és karbantarthatatlan lesz a program tőle.

    Az Ericsson-os codechekker az Windwos 10-en is életre kelthető? Ez a CVI fordító és IDE csak Windows 10-en megy, ebben megy a napi munka.

    Valamint ELTE IK C/C++ gyakorlaton instant évismétlés járt a go to és continue használatért, és értettem hogy miért, miután egyszer valaha valami tele go to-zott programot kellett debugolnom, és visszafejtenem. Fenntarthatatlan és karbantarthatatlan lesz a program tőle.

    A hülyén használt gototól. Ez pont olyan, mint amikor idióta magyartanárok előveszik a "macska fel van mászva a fára" mondatot, hogy ezzel szemléltessék, hogy magyarban miért nem szabad szenvedő szerkezetet használni - csak hát valójában a magyarban a szenvedő szerkezet teljesen rendben van, a macskás példával az a gond, hogy pont azt semmilyen nyelven sem mondják szenvedőben, mert az úgy hülyeség (angolul se mondaná senki, hogy "the cat is on the tree climbed").

    A jól használt goto a C-ben az a jól olvasható kódhoz sok esetben gyakorlatilag elkerülhetetlen. Tipikus példája az, amikor egy függvény több helyen érhet véget, de mindenképpen fel kell szabadítani resource-oket. Ezt mondjuk C++-ban tök faszán lehet csinálni RAII-vel meg finallyvel C#-ban, de azok tök más nyelvek. C-ben nincs ilyen, ott vagy minden helyre külön odakopipészteled a felszabadítást, vagy mindenhonnan a végére gotozol. Egyértelmű, hogy az utóbbi megoldás az, ami olvashatóbb és ami kevesebb hibalehetőséggel jár.

    A C az gyakorlatilag hordozható assembler, ennek megfelelően kell hozzáállni, aki ott azt mondaná, hogy a JMP használatát el kell kerülni, azt kiröhögnék.

  • Livius
    őstag

    Bár C++, de nagyon jó: [Google C++ style guide]

    Coding rules: [SEI CERT C]

    Hogy ellenőrizni is tudd a kódot: [CodeChecker]

    A globális változókat és a gotot kategorikusan elutasítani elég buta dolog. Hatékony eszközök bizonyos problémák megoldásához.

    Ez a coding style vagy coding rules az NI LabWindows CVI-ban programozott GUI-s projekthez kell (rémisztően csak C-ben lehet használni ezt a GUI-s frameworköt). Én eddig a neten mindenhol azt olvasom és azt tanították nekem, hogy a globális változó egy nagy programban már szigorúan kerülendő (itt már nem 8 bites microcontroller a cél HW), jelenleg ahova kellene az már egy nagy program, tele káosszal már sajnos. Valamint ELTE IK C/C++ gyakorlaton instant évismétlés járt a go to és continue használatért, és értettem hogy miért, miután egyszer valaha valami tele go to-zott programot kellett debugolnom, és visszafejtenem. Fenntarthatatlan és karbantarthatatlan lesz a program tőle.

    Az Ericsson-os codechekker az Windwos 10-en is életre kelthető? Ez a CVI fordító és IDE csak Windows 10-en megy, ebben megy a napi munka.

  • buherton
    őstag

    Asztali PC-és C programozáshoz tudtok linkelni valami bevált nagy techcégek által is használt coding rules-t vagy coding style-t? A neten tele van minden +20 éves beágyazott rendszerekhez kitalált coding style-okkal, de nagyon nem olyan kéne, hanem ami inkább Windows PC-és környezethez van és C-hez azon belül is C99 vagy újabbhoz.

    Olyan féle is jól jönne, ami nem csak a nevezéktanról ír, hanem általános programozási alapelvekről is, hogy pl kerüljük a globál változókat, meg tiltott legyen a go to használat stb.

    Bár C++, de nagyon jó: [Google C++ style guide]

    Coding rules: [SEI CERT C]

    Hogy ellenőrizni is tudd a kódot: [CodeChecker]

    A globális változókat és a gotot kategorikusan elutasítani elég buta dolog. Hatékony eszközök bizonyos problémák megoldásához.

  • Livius
    őstag

    Asztali PC-és C programozáshoz tudtok linkelni valami bevált nagy techcégek által is használt coding rules-t vagy coding style-t? A neten tele van minden +20 éves beágyazott rendszerekhez kitalált coding style-okkal, de nagyon nem olyan kéne, hanem ami inkább Windows PC-és környezethez van és C-hez azon belül is C99 vagy újabbhoz.

    Olyan féle is jól jönne, ami nem csak a nevezéktanról ír, hanem általános programozási alapelvekről is, hogy pl kerüljük a globál változókat, meg tiltott legyen a go to használat stb.

  • pmonitor
    aktív tag

    Szerintem aki az előző kódodat nem érti meg, az is viheti valamire, csupán nem tud programozni... :DDD

    Nem pejoratív értelemben gondoltam, amit írtam. Csupán azt jelenti, hogy aki ezt írja magáról: "Elkezdtem csak úgy érdeklődés szinten c-t tanulni mert érdekel. Az elején vagyok nagyon"
    Ha ő megérti, akkor nagyon tehetséges. Ezt értettem a "viheti valamire" alatt. Egyébként az sem baj, ha most nem érti meg, és később visszanéz(és akkor gondolkodik el rajt). Viszont az olvasók között is lehet olyan, aki már eljutott odáig, hogy magától nem jutna eszébe, de ha így látja, akkor egyrészt megérti a működését, másrészt hogy mely esetekben célszerű ezt a formát használni. Sztem. az olvasókat kevesen emlegetik(talán senki), pedig többen vannak, mint akik ide írnak. Pl. itt is szóba került, hogy a kérdező kezdő, azért nem kellene kész megoldást adni. Az ilyenre írom, hogy azért olvasók is vannak, akik már megértik a másfajta megoldást is. Nem biztos, hogy mindig csak a kérdezőt kellene nézni. De a kódot "konyhanyelven" pszeudo kóddal is le lehet írni, ha valaki nem akar teljesen kész kódot adni.

  • sztanozs
    veterán

    Mint ahogy mindenki, én is magamból indulok ki. Nekem sokkal jobb, ha 1 feladatra látok több jó megoldást, és ezeknek a működését értem meg. Pl. ha az előző kódomat megérti, akkor még viheti valamire :K .

    Szerintem aki az előző kódodat nem érti meg, az is viheti valamire, csupán nem tud programozni... :DDD

  • pmonitor
    aktív tag

    Azért nem is akartam semmilyen spéci függvényt javasolni, mert a kérdező - elmondása alapján - gyakorolja a C programozást, így többet ér azzal, ha saját maga kódolja le a megoldást, mint ha készen kap egyet.

    Mint ahogy mindenki, én is magamból indulok ki. Nekem sokkal jobb, ha 1 feladatra látok több jó megoldást, és ezeknek a működését értem meg. Pl. ha az előző kódomat megérti, akkor még viheti valamire :K .

  • pmonitor
    aktív tag

    Kicsit másképp ;)
    int main()
    {
    char name[20];
    char chars[5] = { 'a','b','c','d','e' };
    int yes = 0;
    printf("Enter name: ");
    scanf("%s", name);
    int max[2] = { (int)(sizeof(name) / sizeof(char) - 1), (int)(sizeof(chars) / sizeof(char) - 1) };
    int index[2];
    int n = 1, act = -1;
    int ok = 1;
    do
    {
    while (act < n)
    {
    ++act;
    index[act] = 0;
    }

    if (name[index[0]] == chars[index[1]])
    {
    ok = !ok;
    break;
    }

    while (act > -1)
    {
    if (index[act] < max[act])
    {
    ++index[act];
    break;
    }
    else --act;
    }
    } while (act > -1);
    if (ok) printf("Name: %s\n", name);
    else printf("Not a valid name!\n");
    return 0;
    }

    A "name" tömböt azért fel kellene tölteni "\0"-kal, vagy a ciklust csak strlen(name)-ig kellene futtatni, mert különben memóriaszemét lesz a tartalma.

  • pmonitor
    aktív tag

    Csak úgy érdekességként:
    #include <stdio.h>
     
    int main (){
    char name[20];
    char chars[5]={'a','b','c','d','e'};
    int yes=0;
        printf("Enter name: ");
       scanf("%s",name);
        for(int i=0;i<sizeof(name)/sizeof(char);i++){
            for(int j=0;j<sizeof(chars)/sizeof(char);j++){    
                if(name[i]==chars[j]){
                    yes=1;}
                            }
                                }
    printf("%s",yes?"YES\n":"NO\n");
        
        printf("%ld name",sizeof(name)/sizeof(char));
            printf("%ld chars",sizeof(chars)/sizeof(char));
             return 0;}

    Kicsit másképp ;)
    int main()
    {
    char name[20];
    char chars[5] = { 'a','b','c','d','e' };
    int yes = 0;
    printf("Enter name: ");
    scanf("%s", name);
    int max[2] = { (int)(sizeof(name) / sizeof(char) - 1), (int)(sizeof(chars) / sizeof(char) - 1) };
    int index[2];
    int n = 1, act = -1;
    int ok = 1;
    do
    {
    while (act < n)
    {
    ++act;
    index[act] = 0;
    }

    if (name[index[0]] == chars[index[1]])
    {
    ok = !ok;
    break;
    }

    while (act > -1)
    {
    if (index[act] < max[act])
    {
    ++index[act];
    break;
    }
    else --act;
    }
    } while (act > -1);
    if (ok) printf("Name: %s\n", name);
    else printf("Not a valid name!\n");
    return 0;
    }

  • kovisoft
    őstag

    Ok. Kozben nekem is leesett. :D
    Valahogy sosem jutott eszembe ezt hasznalni a str(c)spn(3) helyett...

    Azért nem is akartam semmilyen spéci függvényt javasolni, mert a kérdező - elmondása alapján - gyakorolja a C programozást, így többet ér azzal, ha saját maga kódolja le a megoldást, mint ha készen kap egyet.

  • Domonkos
    addikt

    Visszaadja, ha megtalálta bármely keresett (=nem megengedett) karaktert az eredeti stringben. Ha meg NULL-t ad vissza, akkor nem volt egyetlen keresett karakter sem a stringben.

    Ok. Kozben nekem is leesett. :D
    Valahogy sosem jutott eszembe ezt hasznalni a str(c)spn(3) helyett...

  • kovisoft
    őstag

    Ennek nincs komplementer parja. Az eredeti felvetesben nem az kell? Ezt hogy hasznalnad erre?

    Visszaadja, ha megtalálta bármely keresett (=nem megengedett) karaktert az eredeti stringben. Ha meg NULL-t ad vissza, akkor nem volt egyetlen keresett karakter sem a stringben.

  • Domonkos
    addikt

    Sziasztok, kis segítséget kérnék.
    Elkezdtem csak úgy érdeklődés szinten c-t tanulni mert érdekel. Az elején vagyok nagyon, gyakorlásképpen csináltam egy kis kódot:

    #include <stdio.h>
    #include <string.h>
    int main ()
    {
    const char name[20];
    const char restrictions[5] = "c";
    printf("Enter name: ");
    scanf("%s", name);

    if (strstr(name, restrictions) != NULL)
    {
    printf("Not a valid name!\n");
    } else
    printf("Name: %s\n", name);

    return 0;
    }

    Bekér egy nevet és megadott karakter esetén kiírja, hogy az nem megfelelő.Ezt szeretném tovább bővíteni úgy, hogy több nem megengedett karakter legyen. Úgy gondoltam ezt talán tömbbel lehet szóval a
    const char restrictions[5] = "a" sort átírtam így const char restrictions[5] = {'a', 'b', 'c'}
    na így viszont már nem igazán akar működni. Valaki tud elvi iránymutatást adni, hogy ez miért nem jó? Tömbbel már nem működik igy az strstr? Köszi

    strcspn(3)

  • gregory91
    senior tag

    Sziasztok, kis segítséget kérnék.
    Elkezdtem csak úgy érdeklődés szinten c-t tanulni mert érdekel. Az elején vagyok nagyon, gyakorlásképpen csináltam egy kis kódot:

    #include <stdio.h>
    #include <string.h>
    int main ()
    {
    const char name[20];
    const char restrictions[5] = "c";
    printf("Enter name: ");
    scanf("%s", name);

    if (strstr(name, restrictions) != NULL)
    {
    printf("Not a valid name!\n");
    } else
    printf("Name: %s\n", name);

    return 0;
    }

    Bekér egy nevet és megadott karakter esetén kiírja, hogy az nem megfelelő.Ezt szeretném tovább bővíteni úgy, hogy több nem megengedett karakter legyen. Úgy gondoltam ezt talán tömbbel lehet szóval a
    const char restrictions[5] = "a" sort átírtam így const char restrictions[5] = {'a', 'b', 'c'}
    na így viszont már nem igazán akar működni. Valaki tud elvi iránymutatást adni, hogy ez miért nem jó? Tömbbel már nem működik igy az strstr? Köszi

    Csak úgy érdekességként:
    #include <stdio.h>
     
    int main (){
    char name[20];
    char chars[5]={'a','b','c','d','e'};
    int yes=0;
        printf("Enter name: ");
       scanf("%s",name);
        for(int i=0;i<sizeof(name)/sizeof(char);i++){
            for(int j=0;j<sizeof(chars)/sizeof(char);j++){    
                if(name[i]==chars[j]){
                    yes=1;}
                            }
                                }
    printf("%s",yes?"YES\n":"NO\n");
        
        printf("%ld name",sizeof(name)/sizeof(char));
            printf("%ld chars",sizeof(chars)/sizeof(char));
             return 0;}

  • pmonitor
    aktív tag

    Ahaaa, na talán kapizsgálom amit írtál. Köszi szépen, nekiesek majd és e szerint átírom :) Nem voltál lassú amúgy, elvi iránymutatást kértem azt megadtad, a fenti kódot még nem néztem meg. Majd ha nem sikerül megírnom akkor rálesek arra ;)

    Én csak tanulmányozásra írtam a kódot, hogy az strstr() miért is nem működik karakterekre. Mert a karakter nem kezelhető strstr()-el. Viszont a ciklust nem tudod elkerülni, akár az ststr()-t, akár az strchr()-t használod. Egyébként én is elkövettem 1 hibát. A break-re nincs szükség, mert az elején a feltételben vizsgálom.

  • kovisoft
    őstag

    Ahaaa, na talán kapizsgálom amit írtál. Köszi szépen, nekiesek majd és e szerint átírom :) Nem voltál lassú amúgy, elvi iránymutatást kértem azt megadtad, a fenti kódot még nem néztem meg. Majd ha nem sikerül megírnom akkor rálesek arra ;)

    Ha karaktereket keresel egyesével stringben, akkor javaslom az strchr() használatát strstr() helyett, mert az strstr()-nek keresőstringet kell megadni, ezért nem fog működni const char restrictions[5] = {'a', 'b', 'c'} formával. Ezt láthatod is pmonitor kódjában, ha majd megnézed.

  • Szőrös 
    veterán

    Azért nem működik így, mert az strstr() egy összefüggő rész-stringet keres meg az adott stringben, te pedig azt szeretnéd, hogy a megadott karaktereket külön-külön nézze meg, hogy benne vannak-e valahol a stringben, nem feltétlenül összefüggően és nem feltétlenül ugyanabban a sorrendben. Pl. ha "abc"-t keresel, azt az strstr() megtalálja az "aabcc"-ben, de nem találja meg az "aabbcc"-ben, mert ez utóbbinak az "abc" nem rész-stringje.

    Azt kell csinálnod, hogy egy ciklussal végigmész a restrictions[] karakterein, és mindegyikre megnézed, hogy benne van-e a name-ben az adott karakter.

    Szerk: lassú voltam :)

    Ahaaa, na talán kapizsgálom amit írtál. Köszi szépen, nekiesek majd és e szerint átírom :) Nem voltál lassú amúgy, elvi iránymutatást kértem azt megadtad, a fenti kódot még nem néztem meg. Majd ha nem sikerül megírnom akkor rálesek arra ;)

  • kovisoft
    őstag

    Sziasztok, kis segítséget kérnék.
    Elkezdtem csak úgy érdeklődés szinten c-t tanulni mert érdekel. Az elején vagyok nagyon, gyakorlásképpen csináltam egy kis kódot:

    #include <stdio.h>
    #include <string.h>
    int main ()
    {
    const char name[20];
    const char restrictions[5] = "c";
    printf("Enter name: ");
    scanf("%s", name);

    if (strstr(name, restrictions) != NULL)
    {
    printf("Not a valid name!\n");
    } else
    printf("Name: %s\n", name);

    return 0;
    }

    Bekér egy nevet és megadott karakter esetén kiírja, hogy az nem megfelelő.Ezt szeretném tovább bővíteni úgy, hogy több nem megengedett karakter legyen. Úgy gondoltam ezt talán tömbbel lehet szóval a
    const char restrictions[5] = "a" sort átírtam így const char restrictions[5] = {'a', 'b', 'c'}
    na így viszont már nem igazán akar működni. Valaki tud elvi iránymutatást adni, hogy ez miért nem jó? Tömbbel már nem működik igy az strstr? Köszi

    Azért nem működik így, mert az strstr() egy összefüggő rész-stringet keres meg az adott stringben, te pedig azt szeretnéd, hogy a megadott karaktereket külön-külön nézze meg, hogy benne vannak-e valahol a stringben, nem feltétlenül összefüggően és nem feltétlenül ugyanabban a sorrendben. Pl. ha "abc"-t keresel, azt az strstr() megtalálja az "aabcc"-ben, de nem találja meg az "aabbcc"-ben, mert ez utóbbinak az "abc" nem rész-stringje.

    Azt kell csinálnod, hogy egy ciklussal végigmész a restrictions[] karakterein, és mindegyikre megnézed, hogy benne van-e a name-ben az adott karakter.

    Szerk: lassú voltam :)

  • pmonitor
    aktív tag

    Sziasztok, kis segítséget kérnék.
    Elkezdtem csak úgy érdeklődés szinten c-t tanulni mert érdekel. Az elején vagyok nagyon, gyakorlásképpen csináltam egy kis kódot:

    #include <stdio.h>
    #include <string.h>
    int main ()
    {
    const char name[20];
    const char restrictions[5] = "c";
    printf("Enter name: ");
    scanf("%s", name);

    if (strstr(name, restrictions) != NULL)
    {
    printf("Not a valid name!\n");
    } else
    printf("Name: %s\n", name);

    return 0;
    }

    Bekér egy nevet és megadott karakter esetén kiírja, hogy az nem megfelelő.Ezt szeretném tovább bővíteni úgy, hogy több nem megengedett karakter legyen. Úgy gondoltam ezt talán tömbbel lehet szóval a
    const char restrictions[5] = "a" sort átírtam így const char restrictions[5] = {'a', 'b', 'c'}
    na így viszont már nem igazán akar működni. Valaki tud elvi iránymutatást adni, hogy ez miért nem jó? Tömbbel már nem működik igy az strstr? Köszi

    int main()
    {
    const char name[20];
    const char restrictions[7] = "a\0b\0c\0";
    printf("Enter name: ");
    scanf("%s", name);
    int i, ok = 1;
    for (i = 0; restrictions[i] && ok; i += 2)
    {
    if (strstr(name, &restrictions[i]) != NULL)
    {
    ok = !ok;
    break;
    }
    }
    if (ok) printf("Name: %s\n", name);
    else printf("Not a valid name!\n");
    return 0;
    }

  • Szőrös 
    veterán

    Sziasztok, kis segítséget kérnék.
    Elkezdtem csak úgy érdeklődés szinten c-t tanulni mert érdekel. Az elején vagyok nagyon, gyakorlásképpen csináltam egy kis kódot:

    #include <stdio.h>
    #include <string.h>
    int main ()
    {
    const char name[20];
    const char restrictions[5] = "c";
    printf("Enter name: ");
    scanf("%s", name);

    if (strstr(name, restrictions) != NULL)
    {
    printf("Not a valid name!\n");
    } else
    printf("Name: %s\n", name);

    return 0;
    }

    Bekér egy nevet és megadott karakter esetén kiírja, hogy az nem megfelelő.Ezt szeretném tovább bővíteni úgy, hogy több nem megengedett karakter legyen. Úgy gondoltam ezt talán tömbbel lehet szóval a
    const char restrictions[5] = "a" sort átírtam így const char restrictions[5] = {'a', 'b', 'c'}
    na így viszont már nem igazán akar működni. Valaki tud elvi iránymutatást adni, hogy ez miért nem jó? Tömbbel már nem működik igy az strstr? Köszi

  • DopeBob
    addikt

    Megpróbáltam lefordítani az eredeti kódodat, de nekem (treat warnings as errors beállítással) fordítási hibát dobott a scanf és a printf sorokra. Érthető, mivel az int (*statData)[statDay][OPEN_HOURS] egy kétdimenziós tömbre mutató pointer, nem pedig egy kétdimenziós tömb. A statData[i][j] nem egy int-et, hanem egy pointert jelent. Cast-olással kierőszakoltam, hogy leforduljon, valamint felcseréltem a statData deklarációjában a sorokat és az oszlopokat (int (*statData)[OPEN_HOURS][statDay]), és így már ez a változat is működött.

    Ökölszabályként azt tartsd szem előtt, hogy amikor egy pointert deklarálsz, akkor azt tömbként is tudod használni (meg tudod indexelni [i] stílusban), tehát úgy is felfogható a dolog, hogy egy * ugyanúgy hozzáad egy dimenziót a deklarált tömbödhöz, mint egy [SIZE]. Fordítva is igaz a dolog: egy tömb utolsó dimenzióját lehagyva egy pointert kapsz.

    Vagyis amikor ezt írod le: int (*statData)[OPEN_HOURS][statDay], akkor ez igazából egy 3 dimenziós tömb, aminek az első két dimenziója a fix [OPEN_HOURS] és [statDay], a harmadik dimenziója dinamikus, és ennek mérete a malloc-ban megadott értékből jön, ami jelen esetben [1] (mivel a teljes allokált méret OPEN_HOURS*statDay*1). Éppen ezért az így deklarált tömb elemeire ezen a módon kell hivatkozni: statData[i][j][0]. Kipróbáltam ezt is, és így is működik. Ezzel együtt nem javaslom ennek a formának a használatát, és nem is értem, hogy a Pluralsight miért így tanítja.

    Szia,

    nagyon köszönöm a segítséget, azt hiszem most már értem, legalább ezt a részt :B

  • kovisoft
    őstag

    Ah, megvan, azt nem állítom, hogy pontosan értem de működik:

    Ez nem jó:
    int (*statData)[statDay] = malloc(sizeof(int[statDay][OPEN_HOURS]));

    Ez ok, szépen lehet indexelni, adatok a helyükön.
    int (*statData)[OPEN_HOURS]= malloc(sizeof(int[statDay][OPEN_HOURS]));

    Nagyon köszi a segítséget :R

    Megpróbáltam lefordítani az eredeti kódodat, de nekem (treat warnings as errors beállítással) fordítási hibát dobott a scanf és a printf sorokra. Érthető, mivel az int (*statData)[statDay][OPEN_HOURS] egy kétdimenziós tömbre mutató pointer, nem pedig egy kétdimenziós tömb. A statData[i][j] nem egy int-et, hanem egy pointert jelent. Cast-olással kierőszakoltam, hogy leforduljon, valamint felcseréltem a statData deklarációjában a sorokat és az oszlopokat (int (*statData)[OPEN_HOURS][statDay]), és így már ez a változat is működött.

    Ökölszabályként azt tartsd szem előtt, hogy amikor egy pointert deklarálsz, akkor azt tömbként is tudod használni (meg tudod indexelni [i] stílusban), tehát úgy is felfogható a dolog, hogy egy * ugyanúgy hozzáad egy dimenziót a deklarált tömbödhöz, mint egy [SIZE]. Fordítva is igaz a dolog: egy tömb utolsó dimenzióját lehagyva egy pointert kapsz.

    Vagyis amikor ezt írod le: int (*statData)[OPEN_HOURS][statDay], akkor ez igazából egy 3 dimenziós tömb, aminek az első két dimenziója a fix [OPEN_HOURS] és [statDay], a harmadik dimenziója dinamikus, és ennek mérete a malloc-ban megadott értékből jön, ami jelen esetben [1] (mivel a teljes allokált méret OPEN_HOURS*statDay*1). Éppen ezért az így deklarált tömb elemeire ezen a módon kell hivatkozni: statData[i][j][0]. Kipróbáltam ezt is, és így is működik. Ezzel együtt nem javaslom ennek a formának a használatát, és nem is értem, hogy a Pluralsight miért így tanítja.

  • kovisoft
    őstag

    Ah, megvan, azt nem állítom, hogy pontosan értem de működik:

    Ez nem jó:
    int (*statData)[statDay] = malloc(sizeof(int[statDay][OPEN_HOURS]));

    Ez ok, szépen lehet indexelni, adatok a helyükön.
    int (*statData)[OPEN_HOURS]= malloc(sizeof(int[statDay][OPEN_HOURS]));

    Nagyon köszi a segítséget :R

    Ja igen, sorry. Ez volt még a másik dolog, ami közben eszembe jutott, hogy a sorok és az oszlopok lehetnek felcserélve a deklarációban, és sajnos az enyémben is. Jobban belegondolva akár a te változatod is működhet, ha felcseréled a sorokat és az oszlopokat.

  • DopeBob
    addikt

    Szerintem a malloc sorral van a gond. Ahogy írtad, úgy eggyel több az indirekció a bal oldalon (pointer egy két dimenziós tömbre, ami így egy három dimenziós tömbbel lesz analóg). Helyette ez kellene:

    int (*statData)[statDay] = malloc(sizeof(int[statDay][OPEN_HOURS]));

    Másik lehetőség, hogy egy dimenziós tömböt használsz (szimpla pointert allokálsz) és [i*OPEN_HOURS+j] formában indexeled.

    És a free-nél sem kell a csillag, csak simán free(statData).

    Ah, megvan, azt nem állítom, hogy pontosan értem de működik:

    Ez nem jó:
    int (*statData)[statDay] = malloc(sizeof(int[statDay][OPEN_HOURS]));

    Ez ok, szépen lehet indexelni, adatok a helyükön.
    int (*statData)[OPEN_HOURS]= malloc(sizeof(int[statDay][OPEN_HOURS]));

    Nagyon köszi a segítséget :R

  • kovisoft
    őstag

    Megnézem, de ennél a résznél kezdem elveszteni már a fonalat :D Pluralsight-on csinálom a C képzéseket, pont azt monta az oktató ennél a résznél, hogy ez a legegyszerűbb módja mert egyszerű utána felszabadítani a memóriát, és ugyan úgy lehet hivatkozni egy elemet, ahogy statikus 2D tömbnél. Neten- YT-n mindenhol a for ciklussal feltöltögetős verziót láttam, azért örültem meg ennek, de hát nem megy.

    Amit írtál azt hogy kell elépzelni, nem teljesen értem. Egy sort ki tudok választani egy pointerre és egy elemet egy indexel?

    Amikor egy szimpla 1 dimenziós tömböt allokálsz, akkor azt egy szimpla pointerbe rakod bele:

    int *array = malloc(sizeof(int[ARRAY_SIZE]));

    És utána array[i]-vel hivatkozol az elemeire. Ha ezt ki akarjuk terjeszteni 2 dimenzióra, akkor hozzáteszünk mindkét oldalhoz +1 dimenziót, de miért tennénk +2 dimenziót a bal oldalhoz?

    int (*twod_array)[COLUMNS] = malloc(sizeof(int[ROWS][COLUMNS]));

    Így a twod_array egy olyan pointer, ami "COLUMNS db integerből álló tömb" típusú adatra mutat, ilyenekből allokáltunk ROWS db-ot, és twod_array[i][j]-vel hivatkozunk az elemeire. Legalábbis szerintem így kell, de bevallom, nem próbáltam ki.

    Viszont mint írtam, csinálhatod azt is, hogy te számolod át a 2 dimenziós indexet 1 dimenziósra, ekkor elég egy nagy 1 dimenziós tömböt allokálni:

    int *simulated_twod_array = malloc(sizeof(int)*ROWS*COLUMNS);

    Aztán így hivatkozol az i. sor j. oszlopára: simulated_twod_array[i*COLUMNS+j].

  • DopeBob
    addikt

    Szerintem a malloc sorral van a gond. Ahogy írtad, úgy eggyel több az indirekció a bal oldalon (pointer egy két dimenziós tömbre, ami így egy három dimenziós tömbbel lesz analóg). Helyette ez kellene:

    int (*statData)[statDay] = malloc(sizeof(int[statDay][OPEN_HOURS]));

    Másik lehetőség, hogy egy dimenziós tömböt használsz (szimpla pointert allokálsz) és [i*OPEN_HOURS+j] formában indexeled.

    És a free-nél sem kell a csillag, csak simán free(statData).

    Megnézem, de ennél a résznél kezdem elveszteni már a fonalat :D Pluralsight-on csinálom a C képzéseket, pont azt monta az oktató ennél a résznél, hogy ez a legegyszerűbb módja mert egyszerű utána felszabadítani a memóriát, és ugyan úgy lehet hivatkozni egy elemet, ahogy statikus 2D tömbnél. Neten- YT-n mindenhol a for ciklussal feltöltögetős verziót láttam, azért örültem meg ennek, de hát nem megy.

    Amit írtál azt hogy kell elépzelni, nem teljesen értem. Egy sort ki tudok választani egy pointerre és egy elemet egy indexel?

  • kovisoft
    őstag

    Sziasztok, valaki ránézni, hogy mit rontok el? Nem jövök rá mi a baj. Az is lehet, hogy több sebből vérzik a dolog, egy ismerősnek próbálok segíteni vizsgára készülni, de hát eddig vak vezet világtalant :D Első félében C-vel veszik a kedvüket egy életre a programozástól (gépész ráadásul)

    Egy 2D-s tömböt kéne feltölteni, ez lenne egy feladat eleje. A sorok számát kell bekérni, oszlop szám adott, és utána az értékeket.

    #include <stdio.h>
    #include <stdlib.h>

    #define OPEN_HOURS 5

    int main (void) {
        
        int statDay = 0;
        printf("Hany nap adatait visszuk be? ");
        scanf("%d", &statDay);

        int (*statData)[statDay][OPEN_HOURS]= malloc(sizeof(int[statDay][OPEN_HOURS]));

        for (int i = 0; i<statDay;i++) {
            for (int j = 0; j<OPEN_HOURS;j++) {
                printf("Kerem az %d. nap %d elemet: \n", i,j);
                scanf("%d", &statData[i][j]);
            }
        }

        printf("\nKiiras\n");

        for (int i = 0; i<statDay;i++) {
            printf("%d. nap:\t", i);
            for (int j = 0; j<OPEN_HOURS;j++) {
                printf("(%d;%d) %d\t", i,j, statData[i][j]);
            }
            printf("\n");
        }    

        free(*statData);
        
        return 0;
    }

    Látszólag működik is a dolog, de a tömbben rossz helyre kerülnek az értékek és nem jövök rá miért. Ha pl 0. napra 0, 1, 2... az 1. napra 10, 11, 12-t írok akkor ezt kéne kiírnia:

    0: 0 1 2 3 4
    1: 10 11 12 13 14

    de helyette ez van:

    0. nap: 0       1       2       10      11
    1. nap: 10      11      12      20      21
    2. nap: 20      21      22      23      24

    0. napon 3 és 4 helyett 10 és 11 van, 1. napon 13 és 14 helyett 20 és 21...

    Szerintem a malloc sorral van a gond. Ahogy írtad, úgy eggyel több az indirekció a bal oldalon (pointer egy két dimenziós tömbre, ami így egy három dimenziós tömbbel lesz analóg). Helyette ez kellene:

    int (*statData)[statDay] = malloc(sizeof(int[statDay][OPEN_HOURS]));

    Másik lehetőség, hogy egy dimenziós tömböt használsz (szimpla pointert allokálsz) és [i*OPEN_HOURS+j] formában indexeled.

    És a free-nél sem kell a csillag, csak simán free(statData).

  • DopeBob
    addikt

    Sziasztok, valaki ránézni, hogy mit rontok el? Nem jövök rá mi a baj. Az is lehet, hogy több sebből vérzik a dolog, egy ismerősnek próbálok segíteni vizsgára készülni, de hát eddig vak vezet világtalant :D Első félében C-vel veszik a kedvüket egy életre a programozástól (gépész ráadásul)

    Egy 2D-s tömböt kéne feltölteni, ez lenne egy feladat eleje. A sorok számát kell bekérni, oszlop szám adott, és utána az értékeket.

    #include <stdio.h>
    #include <stdlib.h>

    #define OPEN_HOURS 5

    int main (void) {
        
        int statDay = 0;
        printf("Hany nap adatait visszuk be? ");
        scanf("%d", &statDay);

        int (*statData)[statDay][OPEN_HOURS]= malloc(sizeof(int[statDay][OPEN_HOURS]));

        for (int i = 0; i<statDay;i++) {
            for (int j = 0; j<OPEN_HOURS;j++) {
                printf("Kerem az %d. nap %d elemet: \n", i,j);
                scanf("%d", &statData[i][j]);
            }
        }

        printf("\nKiiras\n");

        for (int i = 0; i<statDay;i++) {
            printf("%d. nap:\t", i);
            for (int j = 0; j<OPEN_HOURS;j++) {
                printf("(%d;%d) %d\t", i,j, statData[i][j]);
            }
            printf("\n");
        }    

        free(*statData);
        
        return 0;
    }

    Látszólag működik is a dolog, de a tömbben rossz helyre kerülnek az értékek és nem jövök rá miért. Ha pl 0. napra 0, 1, 2... az 1. napra 10, 11, 12-t írok akkor ezt kéne kiírnia:

    0: 0 1 2 3 4
    1: 10 11 12 13 14

    de helyette ez van:

    0. nap: 0       1       2       10      11
    1. nap: 10      11      12      20      21
    2. nap: 20      21      22      23      24

    0. napon 3 és 4 helyett 10 és 11 van, 1. napon 13 és 14 helyett 20 és 21...

  • Livius
    őstag

    Sziasztok!
    Lenne egy Linux C/C++ programozási kérdésem, de lehet nem is annyira a C/C++ nyelv a lényeg benne, Linux kernel v4.x-et használok.

    A kérdés az, hogy amikor C/C++-ban a pthread.h-et használva indítok egy plusz threadet FIFO ütemezésben úgy, hogy előre attribútumban beállítom neki a CPU affinitást minden magra, a futás közben ezt a Linux hogy fogja figyelembe venni és kezelni? A thread amit indítok egy végtelen ciklusban figyelget egy thread-safe queue-t, és amikor van valami új elem azt kiveszi, majd csinál vele egy két műveletet, aztán megint blockolva várja a következőt. Ez a szál teljesen jól működik, kb 3-4%-os CPU használatot eredményez, de számomra nagyon gyanús az, hogy mintha a Linux véletlenszerűen indítaná az egyik magon a sok közül ezt a threadet, és utána örökké, csak azon a magon futtatja, vagyis a blockolás feloldása után mintha sose lenne olyan, hogy a másik magra kerülne át a futtatása, pedig a másik magon több szabad CPU idő lenne láthatóan htop-ban. Tud valaki valami infót vagy valami jó linket, hogy valami nagy könyv/biblia szerint a több magot is használható threadeknek hogy kéne managelődni a Linuxban a CPU magok között?

  • gregory91
    senior tag

    Ha jól értem csináljak mondjuk egy config.h-t amibe benne van a #define TEST 0 és ezt a headert kell beincludolni a main.c, első.c, masodik.c -be?

    Ha lehet inkább használd a

    #ifndef
    #endif

    Makrót, mert ha végig include-olod a forrásfájlokat,tulajdonképpen teleszemeteled a fájlodat. :D

    Magyarul így minden forrásfájlba:
    #ifndef config.h
       #include "config.h"
    #endif


    A precompiler, meg mint tudjuk nem buta.

  • kovisoft
    őstag

    Ha jól értem csináljak mondjuk egy config.h-t amibe benne van a #define TEST 0 és ezt a headert kell beincludolni a main.c, első.c, masodik.c -be?

    Így van, ez pl. egy lehetséges megoldás. De a config.h a többi olyan include előtt legyen, ami használja a TEST makrót.

    A lényeg, hogy amelyik .c-ben (vagy .c-be include-olt .h-ban) használni akarod a makrót, oda előtte már valahogy bekerüljön. Amit közvetlenül a main.c-be írsz be, azt nem látja az elso.c vagy a masodik.c. Tehát vagy mindegyik .c-be beírod a definíciót, vagy egy olyan .h-ba, ami include-olva van mindegyik .c-be. Nyilván ez utóbbi a szebb megoldás. A .c-be olyan esetben célszerű beírni, ha ettől a makrótól függ valami működés, és különböző .c-kben eltérő definícióra van szükség (pl. egyik .c-ben a TEST értéke 0, egy másikban 1).

  • Sültbanán
    újonc

    Ha azt akarod, hogy mindkét .c file-ban lásd a makrót, akkor egy olyan headerben kell definiálni, ami mindkét .c-be include-olva van.

    Ha jól értem csináljak mondjuk egy config.h-t amibe benne van a #define TEST 0 és ezt a headert kell beincludolni a main.c, első.c, masodik.c -be?

  • kovisoft
    őstag

    Sziasztok,

    Egy kis segítség kellene, sehogy sem tudom megoldani, hogy amint a main.c fájlban definiáltam makrót az elérhető legyen egy include-ban lévő include-ban.

    pl.:

    main.c:
    #include "elso.h"
    #define TEST 0

    void main(void)
    }
     bla-bla
    }

    elso.h:
    #ifndef masodik.h
      #include "masodik.h"
    #endif

    És ha a masodik.c -ben hivatkozok a TEST makróra akkor azt a hibát dobja, hogy nincs definiálva. Szóval elso.c -ben még elérhető a makró de a második.c-ben már nem...

    Valami tanács?

    Ha azt akarod, hogy mindkét .c file-ban lásd a makrót, akkor egy olyan headerben kell definiálni, ami mindkét .c-be include-olva van.

  • Sültbanán
    újonc

    Azért nem látja, mivel az include a define előtt van. A preprocesszor soronként megy végig a file-on, egyszer.
    Egyszerűen cseréld fel a main.c első két sorát és jó lesz.

    Már próbáltam. Nem használ.
    Én is így emlékeztem de mindegy, hogy elé teszem vagy mögé, az első include látja a második nem.

  • dabadab
    titán

    Sziasztok,

    Egy kis segítség kellene, sehogy sem tudom megoldani, hogy amint a main.c fájlban definiáltam makrót az elérhető legyen egy include-ban lévő include-ban.

    pl.:

    main.c:
    #include "elso.h"
    #define TEST 0

    void main(void)
    }
     bla-bla
    }

    elso.h:
    #ifndef masodik.h
      #include "masodik.h"
    #endif

    És ha a masodik.c -ben hivatkozok a TEST makróra akkor azt a hibát dobja, hogy nincs definiálva. Szóval elso.c -ben még elérhető a makró de a második.c-ben már nem...

    Valami tanács?

    Azért nem látja, mivel az include a define előtt van. A preprocesszor soronként megy végig a file-on, egyszer.
    Egyszerűen cseréld fel a main.c első két sorát és jó lesz.

  • Sültbanán
    újonc

    Sziasztok,

    Egy kis segítség kellene, sehogy sem tudom megoldani, hogy amint a main.c fájlban definiáltam makrót az elérhető legyen egy include-ban lévő include-ban.

    pl.:

    main.c:
    #include "elso.h"
    #define TEST 0

    void main(void)
    }
     bla-bla
    }

    elso.h:
    #ifndef masodik.h
      #include "masodik.h"
    #endif

    És ha a masodik.c -ben hivatkozok a TEST makróra akkor azt a hibát dobja, hogy nincs definiálva. Szóval elso.c -ben még elérhető a makró de a második.c-ben már nem...

    Valami tanács?

  • jattila48
    aktív tag

    1/ int sub();
    Ez egy forward declaration, arra szolgál, hogy ha majd csak később lesz ténylegesen definiálva a függvény, amit már előtte használni akarsz, akkor ebből tudja a fordító, hogy milyen argumentumai vannak és milyen típusú értéket ad vissza. Mivel te áthelyezted a sub() függvényt a main() elé, így a te változatodban nincs rá szükség.

    2/ Egy függvény argumentumait deklarálhatod úgy is, hogy rögtön odaírod a nevük elé a típusukat, de úgy is, hogy csak a nevüket írod a zárójelbe, a típusukat ekkor külön meg kell adni a zárójel után és a nyitó kapcsos zárójel előtt. Jelen esetben a fun() függvénynek egy par nevű argumentuma van, aminek a típusa egy int-et visszaadó argumentum nélküli függvénypointer. Ennek lesz majd átadva a sub() itt: fun(sub)

    Ez egy meglehetősen régi példa lehet.
    2/ A példában régi stílusú argumentum deklarálást látsz, ezt már az újabb fordítók meg sem engedik..

  • coco2
    őstag

    Az itt jelenlévők közül futott már valaki köröket a [WolfSSL] libbel ? Főleg linuxon szerver oldali aszinkron stílusban. Dokumentáltabbnak tűnik, mint az openSSL, de a felépítési alapelve szerintem gyengébb (összedrótozták a platformra jellemző socket kezelést a cipherrel ahelyett, hogy csak egy független cipher libet adnának), és kérdéses, hogy tényleg minden részletet kidolgoztak-e.

  • coco2
    őstag

    A jelek szerint csak akkora a kép. Mindössze kíváncsiságból kérdeztem meg utána kotorni, hogy ugyan mi oka lehet valahol a népeknek azt a szintaktikát használni. Ha szétszedik a fejlécet változónként egy sorra, ugyan úgy rugalmasabban szöveg-szerkeszthető eredményt kapnak, és áttekinthetőbben.

  • coco2
    őstag

    Helló, egy tweetben láttam egy ilyet:

    A kód picit csinosítva ez:

    #include <stdio.h>

    int fun(par)
    int (*par)();
    {
    return (*par)();
    }

    int sub()
    {
    return 12;
    }

    int main()
    {
    int sub();
    int var = fun(sub);
    printf("%d", var);
    }

    Dolgok, amiket nem igazán értek:
    1/ int sub();
    Ez gondolom függvénypointer definiálás akar lenni, de akkor nem kellene csillagozni?
    2/ Az elején nem értem azt a konstrukciót:
    int fun(par)
    int (*par)();

    Ez mi az isten? Tehát ha le van zárva pontosvesszővel, akkor utána miből returnölünk?

    Megvan az a szöveg valami normálisabb digitális formában? A teljes blog.

  • 1/ int sub();
    Ez egy forward declaration, arra szolgál, hogy ha majd csak később lesz ténylegesen definiálva a függvény, amit már előtte használni akarsz, akkor ebből tudja a fordító, hogy milyen argumentumai vannak és milyen típusú értéket ad vissza. Mivel te áthelyezted a sub() függvényt a main() elé, így a te változatodban nincs rá szükség.

    2/ Egy függvény argumentumait deklarálhatod úgy is, hogy rögtön odaírod a nevük elé a típusukat, de úgy is, hogy csak a nevüket írod a zárójelbe, a típusukat ekkor külön meg kell adni a zárójel után és a nyitó kapcsos zárójel előtt. Jelen esetben a fun() függvénynek egy par nevű argumentuma van, aminek a típusa egy int-et visszaadó argumentum nélküli függvénypointer. Ennek lesz majd átadva a sub() itt: fun(sub)

    Ahh, köszi. Munkában el vagyok kényeztetve az egyszerű kódokkal.

  • kovisoft
    őstag

    Helló, egy tweetben láttam egy ilyet:

    A kód picit csinosítva ez:

    #include <stdio.h>

    int fun(par)
    int (*par)();
    {
    return (*par)();
    }

    int sub()
    {
    return 12;
    }

    int main()
    {
    int sub();
    int var = fun(sub);
    printf("%d", var);
    }

    Dolgok, amiket nem igazán értek:
    1/ int sub();
    Ez gondolom függvénypointer definiálás akar lenni, de akkor nem kellene csillagozni?
    2/ Az elején nem értem azt a konstrukciót:
    int fun(par)
    int (*par)();

    Ez mi az isten? Tehát ha le van zárva pontosvesszővel, akkor utána miből returnölünk?

    1/ int sub();
    Ez egy forward declaration, arra szolgál, hogy ha majd csak később lesz ténylegesen definiálva a függvény, amit már előtte használni akarsz, akkor ebből tudja a fordító, hogy milyen argumentumai vannak és milyen típusú értéket ad vissza. Mivel te áthelyezted a sub() függvényt a main() elé, így a te változatodban nincs rá szükség.

    2/ Egy függvény argumentumait deklarálhatod úgy is, hogy rögtön odaírod a nevük elé a típusukat, de úgy is, hogy csak a nevüket írod a zárójelbe, a típusukat ekkor külön meg kell adni a zárójel után és a nyitó kapcsos zárójel előtt. Jelen esetben a fun() függvénynek egy par nevű argumentuma van, aminek a típusa egy int-et visszaadó argumentum nélküli függvénypointer. Ennek lesz majd átadva a sub() itt: fun(sub)

  • Helló, egy tweetben láttam egy ilyet:

    A kód picit csinosítva ez:

    #include <stdio.h>

    int fun(par)
    int (*par)();
    {
    return (*par)();
    }

    int sub()
    {
    return 12;
    }

    int main()
    {
    int sub();
    int var = fun(sub);
    printf("%d", var);
    }

    Dolgok, amiket nem igazán értek:
    1/ int sub();
    Ez gondolom függvénypointer definiálás akar lenni, de akkor nem kellene csillagozni?
    2/ Az elején nem értem azt a konstrukciót:
    int fun(par)
    int (*par)();

    Ez mi az isten? Tehát ha le van zárva pontosvesszővel, akkor utána miből returnölünk?

  • coco2
    őstag

    Úgy kell neki állni, mint egy normál programozási feladat. Nézzük meg mit csinált más ;] .

    Mielőtt beleugranál a programozásba érdemes kézzel kipróbálni azt, amit végül csinálni akarsz. Ehhez először olvass el néhány releváns how-to-t. Ezzel ki fogod ismerni magad a kulcsok világában és hogy az openssl-el ez hogyan működik. És megismered a hibaüzneteket, no meg azok formátumát ;] .

    Ha ez megvan akkor érdemes megnézni a példa programokat. Például: Darrenjs [link]

    A githubon találtam még régebben valahol egy nagyon jó example-t, amiben több formátumú kulcsra is voltak különféle példák.

    Az openssl-nek van a neten dokumentációja, de szerintem rossz az elnevezés, mert az inkább egy referencia.

    Köszönöm a példa linket.

    Van esetleg olyan szerver / kliens példa is valahol, ahol a server ténylegesen működik végtelenített echo funkcióval, és minden lépésnél kiírja, ami kliens oldalról éppen érkezett? A linkelt példa csak külső héj, tényleges adatkezelés nincs benne, csak a berkeley socket alapjai, amit megtalálok bárhol.

    Az sha-nak a stream kódoláshoz folyamatosan változó kódolási állapota van. Az ember azt hinné, hogy a socketnak van egy kontextus állapota, amit tudni kell menteni / visszatölteni abban az esetben, ha egy thread-en nem csak egy socket-ot kezelek, hanem sokat. Vajon olyan példa is akadhat valahol?

  • buherton
    őstag

    @kovisoft @buherton:

    Most kotortam végig openssl doksikat amazonon, és nincs egy deka jelenkori könyv sem az sdk-ról :(((

    Kellene egy tapasztalt tanács. Ha amúgy nem vagyok agyhalott programozáshoz, meg dokumentációk megértéséhez, mennyi időt fogok vélhetően rászánni, mire átlátom, hogy mit tud a lib és mit nem?

    Úgy kell neki állni, mint egy normál programozási feladat. Nézzük meg mit csinált más ;] .

    Mielőtt beleugranál a programozásba érdemes kézzel kipróbálni azt, amit végül csinálni akarsz. Ehhez először olvass el néhány releváns how-to-t. Ezzel ki fogod ismerni magad a kulcsok világában és hogy az openssl-el ez hogyan működik. És megismered a hibaüzneteket, no meg azok formátumát ;] .

    Ha ez megvan akkor érdemes megnézni a példa programokat. Például: Darrenjs [link]

    A githubon találtam még régebben valahol egy nagyon jó example-t, amiben több formátumú kulcsra is voltak különféle példák.

    Az openssl-nek van a neten dokumentációja, de szerintem rossz az elnevezés, mert az inkább egy referencia.

  • coco2
    őstag

    @kovisoft @buherton:

    Most kotortam végig openssl doksikat amazonon, és nincs egy deka jelenkori könyv sem az sdk-ról :(((

    Kellene egy tapasztalt tanács. Ha amúgy nem vagyok agyhalott programozáshoz, meg dokumentációk megértéséhez, mennyi időt fogok vélhetően rászánni, mire átlátom, hogy mit tud a lib és mit nem?

  • buherton
    őstag

    Sziasztok!

    TLS libekkel van valakinek közelebbi ismeretsége?

    Egy közepes teljesítményű tcp szervert raknék össze (jellemzően linux), és ha lehet, C libeket használnék. Amit neten találni tudtam viszonylag friss nevet, az az openssl, de a c sdk-ja környékén (pld wiki page-en [link] ) olyan hírek vannak, hogy nem thread-safe a design, és az csúnya hátrány. Kellene nekem tcp stream codernek legalább 6-8 szál folyamatosan. Nem ártana egy normális összefoglaló leírás is, mert szálazni c-ben találomra - szóval az azért nem egészen úgy megy.

    Ha valaki már küzdött meg hasonló problémával, örülnék az utólagos statisztika tapasztalatának. Az alternatíva dotnet core-t használni, de lévén temérdek sok apró csomagot kell majd kezelni, a gc nagyon csúnya hátrány lenne, a dot c-t azért hanyagolnám.

    Halál a CLI interfésze és halál a dokumentációja is. Persze mindent lehet csak idők kérdése. :)

    Érdemes elésben használat előtt szeparált környezetben kitesztelni mindent.

  • kovisoft
    őstag

    Sziasztok!

    TLS libekkel van valakinek közelebbi ismeretsége?

    Egy közepes teljesítményű tcp szervert raknék össze (jellemzően linux), és ha lehet, C libeket használnék. Amit neten találni tudtam viszonylag friss nevet, az az openssl, de a c sdk-ja környékén (pld wiki page-en [link] ) olyan hírek vannak, hogy nem thread-safe a design, és az csúnya hátrány. Kellene nekem tcp stream codernek legalább 6-8 szál folyamatosan. Nem ártana egy normális összefoglaló leírás is, mert szálazni c-ben találomra - szóval az azért nem egészen úgy megy.

    Ha valaki már küzdött meg hasonló problémával, örülnék az utólagos statisztika tapasztalatának. Az alternatíva dotnet core-t használni, de lévén temérdek sok apró csomagot kell majd kezelni, a gc nagyon csúnya hátrány lenne, a dot c-t azért hanyagolnám.

    A linkelt thread safety problémák az 1.0.x openssl verzióra vonatkoznak, de 1.1.0 óta már nem kell locking callbackeket definiálni.

  • coco2
    őstag

    Sziasztok!

    TLS libekkel van valakinek közelebbi ismeretsége?

    Egy közepes teljesítményű tcp szervert raknék össze (jellemzően linux), és ha lehet, C libeket használnék. Amit neten találni tudtam viszonylag friss nevet, az az openssl, de a c sdk-ja környékén (pld wiki page-en [link] ) olyan hírek vannak, hogy nem thread-safe a design, és az csúnya hátrány. Kellene nekem tcp stream codernek legalább 6-8 szál folyamatosan. Nem ártana egy normális összefoglaló leírás is, mert szálazni c-ben találomra - szóval az azért nem egészen úgy megy.

    Ha valaki már küzdött meg hasonló problémával, örülnék az utólagos statisztika tapasztalatának. Az alternatíva dotnet core-t használni, de lévén temérdek sok apró csomagot kell majd kezelni, a gc nagyon csúnya hátrány lenne, a dot c-t azért hanyagolnám.

  • #90088192
    törölt tag

    Most már értem, a karakter kiírásban, az y_offset a koordinatat határozza meg, a string kiiaratasban, meg ugye léptetését kell csinálni, hogy ne egymásra írja a karaktereket. Vagyis SZVSZ nem tudok vele semmit csinálni, hiszen van ahol csak 1db karaktert akarok kiiratni, akkor pedig nem működne ha jól sejtem :R

    Ahogy többet gondolkodom, egyre jobban értem miért hoztad fel :R

    Akkor kellene még egy paraméter, ami megmondja hányadik karakter a referencia koordinátától. Vagyis ha a szorzata 0 akkor lényegtelen :R

    Tetszik, csak nehezen értettem meg. Elnézést :R

  • #90088192
    törölt tag

    :R

    :DDD

    Az a string kiiratas most már értem.

    Most már értem, a karakter kiírásban, az y_offset a koordinatat határozza meg, a string kiiaratasban, meg ugye léptetését kell csinálni, hogy ne egymásra írja a karaktereket. Vagyis SZVSZ nem tudok vele semmit csinálni, hiszen van ahol csak 1db karaktert akarok kiiratni, akkor pedig nem működne ha jól sejtem :R

  • #90088192
    törölt tag

    Arra gondoltam, hogy egy korábbi hozzászólásodban így hívtad meg a write_char-t:

    for(j=0;j<=i-1;j++) write_char(line,y_offset+j*Font_width,test[j]);

    És ebben a második paraméterben használod a Font_width-et is, ezt lehetne kiiktatni, ha egy struktúrában úgyis átadod a font paramétereket. Ehhez át kellene alakítani egy kicsit a paraméterezést (pl. ahogy javasoltam: kettéválasztani egy y és egy j paraméterre, és a write_char függvényen belül elvégezni az y+j*Font_width számolást).

    :R

    :DDD

    Az a string kiiratas most már értem.

  • kovisoft
    őstag

    Köszönöm :)

    Az y_offset át kell hogy nevezzem mert megtévesztő, ez az x tengelyen való eltolást jelöli, semmi dolga nincs magával a fonttal, vagy nem teljesen értelek :DDD

    Próbáltam utána olvasni a struktúrának, egyenlőre nem vagyok vele meg kibékülve, de dolgozom rajta :R

    A másik dolog amin ügyeskedek, a font magassága se jelentsen problémát, vagyis képes legyek több memória lapra kivetítve is elküldeni az adatokat. Arra mar rá jöttem, a font sima decimálisban van(olyat találtam mind a 16 bit egy számot alkot, ami a magasságát teszi ki a karakternek), akkor egyszer 8 pozíciót jobbra, máskor 8 pozíciót balra kell tolni és maris megvan a 8-8 bit, vagy legalábbis remélem :C

    A memória olvasást megoldottam, így mar tudok 1 db pixelt bárhol kapcsolni, anélkül, hogy befolyásolnám az adott lapon levő többi pixelt :K

    Köszönet a segítségért meg egyszer :R

    Arra gondoltam, hogy egy korábbi hozzászólásodban így hívtad meg a write_char-t:

    for(j=0;j<=i-1;j++) write_char(line,y_offset+j*Font_width,test[j]);

    És ebben a második paraméterben használod a Font_width-et is, ezt lehetne kiiktatni, ha egy struktúrában úgyis átadod a font paramétereket. Ehhez át kellene alakítani egy kicsit a paraméterezést (pl. ahogy javasoltam: kettéválasztani egy y és egy j paraméterre, és a write_char függvényen belül elvégezni az y+j*Font_width számolást).

  • #90088192
    törölt tag

    Persze, teheted a font paramétereket egy struktúrába, és akkor elég átadni erre a struktúrára mutató pointert a font választáshoz (vagy csúnyább esetben mehet az egész egy globális változóba). Pl:

    #include "font1.h"
    #include "font2.h"

    struct font_type
    {
    long int *font;
    int font_width;
    int font_height;
    int font_offset;
    };

    struct font_type myfont[2];

    myfont[0].font = Font1;
    myfont[0].font_width = Font1_width;
    myfont[0].font_height = Font1_height;
    myfont[0].font_offset = Font1_offset;

    myfont[1].font        = Font2;
    myfont[1].font_width  = Font2_width;
    myfont[1].font_height = Font2_height;
    myfont[1].font_offset = Font2_offset;


    int write_char(int page_select, int y_offset, int character_code,struct font_type *use_font)
    {
    ...
    send_data_screen(use_font->font);
    ...
    }

    write_char(line,y_offset+j*myfont[0]->font_width,test[j],&myfont[0]);

    write_char(line,y_offset+j*myfont[1]->font_width,test[j],&myfont[1]);

    De lehet, hogy jobb lenne az y_offset paramétert szétszedni egy y és egy j paraméterre, és a font_width-tel való szorzást beletenni a függvénybe, hogy ne kelljen azt is font-tól függően átadni:

    int write_char(int page_select, int y, int j, int character_code,struct font_type *use_font)
    {
    int y_offset = y+j*use_font->font_width;
        ...
        send_data_screen(use_font->font);
        ...
    }

    Köszönöm :)

    Az y_offset át kell hogy nevezzem mert megtévesztő, ez az x tengelyen való eltolást jelöli, semmi dolga nincs magával a fonttal, vagy nem teljesen értelek :DDD

    Próbáltam utána olvasni a struktúrának, egyenlőre nem vagyok vele meg kibékülve, de dolgozom rajta :R

    A másik dolog amin ügyeskedek, a font magassága se jelentsen problémát, vagyis képes legyek több memória lapra kivetítve is elküldeni az adatokat. Arra mar rá jöttem, a font sima decimálisban van(olyat találtam mind a 16 bit egy számot alkot, ami a magasságát teszi ki a karakternek), akkor egyszer 8 pozíciót jobbra, máskor 8 pozíciót balra kell tolni és maris megvan a 8-8 bit, vagy legalábbis remélem :C

    A memória olvasást megoldottam, így mar tudok 1 db pixelt bárhol kapcsolni, anélkül, hogy befolyásolnám az adott lapon levő többi pixelt :K

    Köszönet a segítségért meg egyszer :R

  • kovisoft
    őstag

    Köszönöm :R

    Valahol láttam, de nem tálalom, egy olyan megoldást ahol külön h ban tároltak minden fontot, és talán struct megoldással átvették mindig az aktuális tömböt, és a hozzá tartozó magasság és egyébb paramétereket.

    Erre lenne ötlet? :R

    Előre is köszönöm :R

    Persze, teheted a font paramétereket egy struktúrába, és akkor elég átadni erre a struktúrára mutató pointert a font választáshoz (vagy csúnyább esetben mehet az egész egy globális változóba). Pl:

    #include "font1.h"
    #include "font2.h"

    struct font_type
    {
    long int *font;
    int font_width;
    int font_height;
    int font_offset;
    };

    struct font_type myfont[2];

    myfont[0].font = Font1;
    myfont[0].font_width = Font1_width;
    myfont[0].font_height = Font1_height;
    myfont[0].font_offset = Font1_offset;

    myfont[1].font        = Font2;
    myfont[1].font_width  = Font2_width;
    myfont[1].font_height = Font2_height;
    myfont[1].font_offset = Font2_offset;


    int write_char(int page_select, int y_offset, int character_code,struct font_type *use_font)
    {
    ...
    send_data_screen(use_font->font);
    ...
    }

    write_char(line,y_offset+j*myfont[0]->font_width,test[j],&myfont[0]);

    write_char(line,y_offset+j*myfont[1]->font_width,test[j],&myfont[1]);

    De lehet, hogy jobb lenne az y_offset paramétert szétszedni egy y és egy j paraméterre, és a font_width-tel való szorzást beletenni a függvénybe, hogy ne kelljen azt is font-tól függően átadni:

    int write_char(int page_select, int y, int j, int character_code,struct font_type *use_font)
    {
    int y_offset = y+j*use_font->font_width;
        ...
        send_data_screen(use_font->font);
        ...
    }

  • #90088192
    törölt tag

    Ha jól értem, paraméterben szeretnéd átadni a write_char() függvényednek azt, hogy milyen betűkészletet használjon. Ehhez össze kell szedned, mi definiálja a betűkészletet. Egyrészt a Font[] tömb, másrészt a Font_width, Font_height, Font_offset (ha nem hagytam ki valamit). Ezeket fel kell venned még plusz paraméterként és átadnod a write_char()-nak, pl:

    int write_char(int page_select, int y_offset, int character_code,
    long int *font, int font_width, int font_height, int font_offset)

    És így tudod pl. meghívni:

    write_char(line,y_offset+j*Font_width,test[j],Font,Font_width,Font_height,Font_offset);

    Mivel az y_offset számolásában is használod a Font_width-et, így szebb lenne ezt a függvényen belül végezni.

    Ha pedig mindegyik betűkészlet ugyanolyan méretű, akkor elég csak a font tömböt átadni, nem kellenek a betűméretek.

    Köszönöm :R

    Valahol láttam, de nem tálalom, egy olyan megoldást ahol külön h ban tároltak minden fontot, és talán struct megoldással átvették mindig az aktuális tömböt, és a hozzá tartozó magasság és egyébb paramétereket.

    Erre lenne ötlet? :R

    Előre is köszönöm :R

  • Hello,

    Sry, hogy ide, de itt legalább van élet. (Dobjátok át másikba, ha nem fér el itt :D )
    Valakinek van ötlete, hogy hogyan lehetne Androidon, Camera2 API -ból a preview tulajdonságait lekérni? Konkrétan az AWB_STATE_LOCKED, és az AE_STATE LOCKED kéne, amit mindenhol csak Capturerequest-ből látok lekérdezni, csahogy az én programomban nincs Capturerequest mert nem ment képet, csak a preview-ből jövő képeket dolgozza fel :D

    Köszi bármilyen ötletet :)

  • kovisoft
    őstag

    Hello :)

    Elmétek kiapadhatatlan tudás forrását, szeretném ismételten megcsapolni :R

    Lenne egy olyan problémám, hogy a tömb nevét szeretném változtatni attól függően milyen betűtípust akarok használni. Font neven fut, és ha változóval próbáltam helyettesíteni nem ment.
    Gondolom van rá megoldás, csak nekem új :R

    Előre is köszönöm

    Ez lenne a példa részlet:
    int write_char(int page_select, int y_offset, int charcater_code)

    { int x;
    if(y_offset>=( Display_width/2) && y_offset <= Display_width - Font_width && charcater_code>=32 && charcater_code<=128) //Check which side of the screen need to be activated
    {
    goto_xy( page_select, y_offset);

    for(x=( charcater_code - Font_offset ) * Font_width; x<(( charcater_code - Font_offset)* Font_width)+ Font_width; x++) //Decodes the character code and make sure the data is sent by 8 bits
    {
    send_data_screen( Font[x]); //Sends out the relevant section of the Array
    }
    } else if( y_offset<( Display_width/2) && y_offset>=0 && charcater_code>=32 && charcater_code<=128)
    {
    goto_xy( page_select, y_offset); //Selects pages of writing
    for(x=( charcater_code - Font_offset)* Font_width; x<(( charcater_code - Font_offset) * Font_width)+ Font_width; x++) //Decodes the character code and make sure the data is sent by 8 bits
    { if( y_offset + (x-( charcater_code - Font_offset) * Font_width)!=( Display_width/2)) //Checks if the character has reached the border of the 2 sides of the screen
    {
    send_data_screen( Font[x]);
    }
    else
    { //If the Character is belong to the right side
    goto_xy( page_select,( Display_width/2)); //Selects pages of writing
    send_data_screen( Font[x]); //Sends out the relevant section of the Array


    }
    }
    }
    else
    {
    MEMBRANE_MUTE=1;

    }

    }

    Ha jól értem, paraméterben szeretnéd átadni a write_char() függvényednek azt, hogy milyen betűkészletet használjon. Ehhez össze kell szedned, mi definiálja a betűkészletet. Egyrészt a Font[] tömb, másrészt a Font_width, Font_height, Font_offset (ha nem hagytam ki valamit). Ezeket fel kell venned még plusz paraméterként és átadnod a write_char()-nak, pl:

    int write_char(int page_select, int y_offset, int character_code,
    long int *font, int font_width, int font_height, int font_offset)

    És így tudod pl. meghívni:

    write_char(line,y_offset+j*Font_width,test[j],Font,Font_width,Font_height,Font_offset);

    Mivel az y_offset számolásában is használod a Font_width-et, így szebb lenne ezt a függvényen belül végezni.

    Ha pedig mindegyik betűkészlet ugyanolyan méretű, akkor elég csak a font tömböt átadni, nem kellenek a betűméretek.

  • #90088192
    törölt tag

    Hello :)

    Elmétek kiapadhatatlan tudás forrását, szeretném ismételten megcsapolni :R

    Lenne egy olyan problémám, hogy a tömb nevét szeretném változtatni attól függően milyen betűtípust akarok használni. Font neven fut, és ha változóval próbáltam helyettesíteni nem ment.
    Gondolom van rá megoldás, csak nekem új :R

    Előre is köszönöm

    Ez lenne a példa részlet:
    int write_char(int page_select, int y_offset, int charcater_code)

    { int x;
    if(y_offset>=( Display_width/2) && y_offset <= Display_width - Font_width && charcater_code>=32 && charcater_code<=128) //Check which side of the screen need to be activated
    {
    goto_xy( page_select, y_offset);

    for(x=( charcater_code - Font_offset ) * Font_width; x<(( charcater_code - Font_offset)* Font_width)+ Font_width; x++) //Decodes the character code and make sure the data is sent by 8 bits
    {
    send_data_screen( Font[x]); //Sends out the relevant section of the Array
    }
    } else if( y_offset<( Display_width/2) && y_offset>=0 && charcater_code>=32 && charcater_code<=128)
    {
    goto_xy( page_select, y_offset); //Selects pages of writing
    for(x=( charcater_code - Font_offset)* Font_width; x<(( charcater_code - Font_offset) * Font_width)+ Font_width; x++) //Decodes the character code and make sure the data is sent by 8 bits
    { if( y_offset + (x-( charcater_code - Font_offset) * Font_width)!=( Display_width/2)) //Checks if the character has reached the border of the 2 sides of the screen
    {
    send_data_screen( Font[x]);
    }
    else
    { //If the Character is belong to the right side
    goto_xy( page_select,( Display_width/2)); //Selects pages of writing
    send_data_screen( Font[x]); //Sends out the relevant section of the Array


    }
    }
    }
    else
    {
    MEMBRANE_MUTE=1;

    }

    }

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

Hirdetés