| | |
| Stránka: 1 z 1
| [ Príspevkov: 30 ] | |
Autor | Správa |
---|
Registrovaný: 19.06.12 Prihlásený: 11.12.17 Príspevky: 132 Témy: 20 | Napísal expoox: 15.11.2014 14:04 | |
|
zdravim potreboval by som poradit ako pracovat s malloc v cykle, teda chcem kazdym cyklom zvacsit rozsah pola o jedno, mam tam nieco taketo: Kód: int *cisla; int k=1;
cisla=(int*)malloc(k*sizeof(int));
while (1) {
switch (scanf("%d",&cisla[k-1])) { case 1: { k++; cisla=(int*)malloc(k*sizeof(int)); break; } case EOF: goto out; default: { printf("Nespravny vstup.\n"); return 0; } } } out: a na vystupe su same 0 vdaka za pomoc
_________________ Lenovo IdeaPad G580 *Intel Core i3-2310M 2.10GHz * 4GB RAM * Nvidia GeForce 610M 1GB * 500GB HDD SATA * Windows 10 64-bit || Ubuntu 14.04 |
|
Registrovaný: 13.11.07 Prihlásený: 20.08.16 Príspevky: 1702 Témy: 0 | Napísal chrono: 15.11.2014 15:02 | |
|
Dá sa použiť funkcia realloc, každopádne rozumnejšie by bolo urobiť si nejakú štruktúru a pomocné funkcie, ktoré by dané pole zvyšovali v prípade, že v ňom dôjde voľné miesto (a nezväčšovalo by sa len o jednu položku).
PS: Namiesto toho goto tam stačí použiť break;
|
|
Registrovaný: 19.06.12 Prihlásený: 11.12.17 Príspevky: 132 Témy: 20 | Napísal autor témy expoox: 15.11.2014 15:15 | |
|
skusim to s tym realloc, vdaka ... no toho goto som sa chcel aj ja zbavit ale ak tam hodim break tak to vyskoci len zo switchu ale nie z while
_________________ Lenovo IdeaPad G580 *Intel Core i3-2310M 2.10GHz * 4GB RAM * Nvidia GeForce 610M 1GB * 500GB HDD SATA * Windows 10 64-bit || Ubuntu 14.04 |
|
Registrovaný: 17.07.11 Prihlásený: 29.12.20 Príspevky: 1516 Témy: 3 | Napísal BX: 15.11.2014 18:34 | |
|
Toho goto sa zbav a už nikdy viac to do programu nenapíš (ak ti to predom neschvalim). Ber to ako kliatbu a ak to porušíš, odpadne ti nos. Keď chceš vystúpiť z cyklu, tak ho nemám ako while(1), ale trebárs while(run). Potom z neho vieš vyskočiť veľmi jednoducho. No a k pôvodnej otázke: použi realloc. Toť vše
_________________ Na súkromné správy týkajúce sa problémov, ktoré sa riešia vo fóre, neodpovedám! |
|
Registrovaný: 15.01.07 Prihlásený: 23.09.15 Príspevky: 186 Témy: 3 Bydlisko: ZV/BA | Napísal matwej: 16.11.2014 0:34 | |
|
jop, realloc ... ale co sa tyka vyhnutia goto, pouzi takyto styl: Kód: for (;;) { switch() { case 'nieco': // nieco continue; case 'nieco2': // nieco continue; case 'koniec': break; } break; }
nemas nic za switch, takze to bude fungovat
_________________ nb: Lenovo Thinkpad E520 (starsi pan uz), Fedora 20 / Win7 dualboot " 1000.times { puts "I will not spam on the boards" } " |
|
Registrovaný: 17.07.11 Prihlásený: 29.12.20 Príspevky: 1516 Témy: 3 | Napísal BX: 16.11.2014 8:59 | |
|
Matwej toto tiež neodporúčam, je to vysoko neprehľadné a neintuitívne. Keď mám nekonečný cyklus, tak očakávam, že niečo skutočne robím v cykle a iba pri nejakej podmienke ho opustím. Nie že ho pri podmienkach opakujem. Tvoj kód nemá ďaleko od goto, ktorého sa mame zbaviť.
_________________ Na súkromné správy týkajúce sa problémov, ktoré sa riešia vo fóre, neodpovedám! |
|
Registrovaný: 19.06.12 Prihlásený: 11.12.17 Príspevky: 132 Témy: 20 | Napísal autor témy expoox: 16.11.2014 11:14 | |
|
ok realloc vyriesil co som potreboval, este raz vdaka PS: goto som sa zbavil takto : Kód: eofile=1;
while (eofile) { switch (scanf("%d",&cisla[pocet-1])) { case 1: { ..... break; } case EOF: { eofile=0; .... break; } default: { .... } } }
_________________ Lenovo IdeaPad G580 *Intel Core i3-2310M 2.10GHz * 4GB RAM * Nvidia GeForce 610M 1GB * 500GB HDD SATA * Windows 10 64-bit || Ubuntu 14.04 |
|
Registrovaný: 15.01.07 Prihlásený: 23.09.15 Príspevky: 186 Témy: 3 Bydlisko: ZV/BA | Napísal matwej: 16.11.2014 17:12 | |
|
BX píše: Matwej toto tiež neodporúčam, je to vysoko neprehľadné a neintuitívne. Keď mám nekonečný cyklus, tak očakávam, že niečo skutočne robím v cykle a iba pri nejakej podmienke ho opustím. Nie že ho pri podmienkach opakujem. Tvoj kód nemá ďaleko od goto, ktorého sa mame zbaviť. yeah, viem, ale je to sposob ako sa vyhnut goto, celkovo su nekonecne cykly spolu so switchom taka krepost keby si nechcel pouzit flag samozrejme, ze chlapec pouzil flag, aj ked som myslel, ze sa mu chce nejakym sposobom vyhnut ked tam strka goto
_________________ nb: Lenovo Thinkpad E520 (starsi pan uz), Fedora 20 / Win7 dualboot " 1000.times { puts "I will not spam on the boards" } " |
|
Registrovaný: 17.07.11 Prihlásený: 29.12.20 Príspevky: 1516 Témy: 3 | Napísal BX: 16.11.2014 18:15 | |
|
No nie je, ale zároveň tam to goto je. Tomu sa nesnažíme vyhnúť preto, že sa nám ten príkaz nepáči. Snažíme sa mu vyhnúť preto, že vedie na neprehľadný kód. Takže elimináciu goto sa snažíme vyhnúť neprehľadnému kódu. To sa ale nepodarí, keď neprehľadný kód s goto nahradíš iným neprehľadným kódom bez neho. A to si ty urobil
_________________ Na súkromné správy týkajúce sa problémov, ktoré sa riešia vo fóre, neodpovedám! |
|
Registrovaný: 25.11.09 Prihlásený: 21.04.24 Príspevky: 267 Témy: 32 Bydlisko: LV / Brno | Napísal Spixy: 16.11.2014 18:19 | |
|
matwej ono ten switch sa v konecnom dosledku skompiluje na goto, to už používanie goto je prehladnejšie
goto prikazu by som sa az tak zas nebál (hlavne v C-čku), ale ak si zaciatocnik tak sa mu pre vlastné dobro radšej vyhni
_________________ R5 6600X | GTX 1080 Ti | 32GB Xperia XZ2 Compact |
|
Registrovaný: 17.07.11 Prihlásený: 29.12.20 Príspevky: 1516 Témy: 3 | Napísal BX: 16.11.2014 18:24 | |
|
Spixy, C je tu ale na to, aby nás odtienil od strojových inštrukcií a "hnusného" assembleru. Navrhuješ snáď robiť všetko pomocou najnižších možných príkazov a zabudnúť na cykly, podmienky a funkcie? Kód v C už by nemal obsahovať skoky na navestia. Na to ten vyšší jazyk je.
_________________ Na súkromné správy týkajúce sa problémov, ktoré sa riešia vo fóre, neodpovedám! |
|
Registrovaný: 14.03.11 Prihlásený: 02.08.23 Príspevky: 814 Témy: 23 Bydlisko: Bratislava |
Keď už raz kompilátor príkaz goto pozná, dá sa nájsť príklad keď jeho použitie bude najjednoduchšie a najprehľadnejšie riešenie. Netreba veriť dogmám.
|
|
Registrovaný: 30.12.09 Prihlásený: 01.11.23 Príspevky: 265 Témy: 45 Bydlisko: Praha_4/Presov | Napísal vital: 24.11.2014 19:03 | |
|
expoox píše: ok realloc vyriesil co som potreboval, este raz vdaka
PS: goto som sa zbavil takto : ...
namiesto "manualnej" kontroly konca suboru odporucam pouzit radsej funkciu feof (), v tvojom pripade feof (stdin)... v tom pripade by tvoj kod vyzeral: Kód: eofile=1;
while (!feof (stdin)) { switch (scanf("%d",&cisla[pocet-1])) { case 1: { ..... break; } default: { .... } } } ad goto, neviem si predstavit ako postavit anpr. lexikalny analyzator (alebo iny konecny automat) rozumne, bez pouzitia goto. a len tak na okraj, ani jeden z cyklov v C GCC nepreklada do Genericu ako uzol loop_expr. vsetko su to skoky...
_________________ PC: mobo: Asus PRIME Z490-P cpu: i7 10700F ram: CL16 HyperX 2x8GB DDR4 3200MHz CL16 FURY gpu: MSI R7 250 1GD5 OC ssd: Samsung EVO 850 120GB + EVO 860 250GB psu: EVGA 500B chassis: Fractal CORE 3500W lcd: Samsung U28E590D <3: mobo: DFI LanParty UT P45 t2rs; cpu: Core2Extreme QX6850; ram:OCZ 4x1GB 1150Mhz PC9200 CL5; gpu: asus 9800gx2 hdd: Samsung F3 500GB; psu: TTTP-1,5kW; chassis: Fractal Define r2 lcd: Samsung SyncMaster 2343NW @2048x1152 tire slayer: RS6 4G |
|
Registrovaný: 13.11.07 Prihlásený: 20.08.16 Príspevky: 1702 Témy: 0 | Napísal chrono: 24.11.2014 22:48 | |
|
S tým feof tam stačí if (a netreba goto).
|
|
Registrovaný: 17.07.11 Prihlásený: 29.12.20 Príspevky: 1516 Témy: 3 | Napísal BX: 25.11.2014 7:23 | |
|
vital píše: ad goto, neviem si predstavit ako postavit anpr. lexikalny analyzator (alebo iny konecny automat) rozumne, bez pouzitia goto. a len tak na okraj, ani jeden z cyklov v C GCC nepreklada do Genericu ako uzol loop_expr. vsetko su to skoky... Konečný automat implementuješ kľudne pomocou tabulky (tj. jedno dvojrozmerné pole), alebo switchov. Ale áno, prekladač je jedna z výnimiek, kde sa goto používa. To je ale nízkoúrovňová vec, v programovaní na vyššej úrovni goto nemá veľmi čo hľadať. A Generic tu nemiešaj, to už vôbec nie je vyšší jazyk
_________________ Na súkromné správy týkajúce sa problémov, ktoré sa riešia vo fóre, neodpovedám! |
|
Registrovaný: 25.11.09 Prihlásený: 21.04.24 Príspevky: 267 Témy: 32 Bydlisko: LV / Brno | Napísal Spixy: 25.11.2014 14:41 | |
|
ono čisté C je celkom nízkoúrovňová vec ale sme trochu OT, aj tak sa goto dá vždy nahradiť niečím iným, takže jeho používanie nemá zmysel
_________________ R5 6600X | GTX 1080 Ti | 32GB Xperia XZ2 Compact |
|
Registrovaný: 17.07.11 Prihlásený: 29.12.20 Príspevky: 1516 Témy: 3 | Napísal BX: 25.11.2014 15:17 | |
|
C ale vzniklo práve kvôli abstrakcii od inštrukcií procesora. V tom je jeho "vyššia úroveň". Keby sme to nepotrebovali, tak stále píšeme v assembleri pomocou skokov. Ale už dávno sa ľudia zhodli na tom, že to proste nie je pekné A no a čo, že sme OT, otázka bola zodpovedaná
_________________ Na súkromné správy týkajúce sa problémov, ktoré sa riešia vo fóre, neodpovedám! |
|
Registrovaný: 30.12.09 Prihlásený: 01.11.23 Príspevky: 265 Témy: 45 Bydlisko: Praha_4/Presov | Napísal vital: 25.11.2014 20:47 | |
|
BX píše: Konečný automat implementuješ kľudne pomocou tabulky (tj. jedno dvojrozmerné pole), alebo switchov. Ale áno, prekladač je jedna z výnimiek, kde sa goto používa. To je ale nízkoúrovňová vec, v programovaní na vyššej úrovni goto nemá veľmi čo hľadať. A Generic tu nemiešaj, to už vôbec nie je vyšší jazyk pomocou switchov bez goto? kazdopadne, vobec nechapem o com tocis. C je vysokourovnovy jazyk? proti asm je vsetko vyssi jazyk, a napriek tomu v Ccku piseme prekladace, jadra os, a ine "nizkourovnove" veci. vysvetli mi teda, v com je rozdiel jednotlivych urovni, a preco by som sem nemal miesat Generic, ked su to vsetko Cckove struktury a cele rozhranie ku Generic/Gimple stromom je v C? neviem o akych "jazykoch" je rec, pretoze sa bavime stale o Ccku. btw, skoro mi to pride, ze vnimas C a C++ ako jeden jazyk - C++.
_________________ PC: mobo: Asus PRIME Z490-P cpu: i7 10700F ram: CL16 HyperX 2x8GB DDR4 3200MHz CL16 FURY gpu: MSI R7 250 1GD5 OC ssd: Samsung EVO 850 120GB + EVO 860 250GB psu: EVGA 500B chassis: Fractal CORE 3500W lcd: Samsung U28E590D <3: mobo: DFI LanParty UT P45 t2rs; cpu: Core2Extreme QX6850; ram:OCZ 4x1GB 1150Mhz PC9200 CL5; gpu: asus 9800gx2 hdd: Samsung F3 500GB; psu: TTTP-1,5kW; chassis: Fractal Define r2 lcd: Samsung SyncMaster 2343NW @2048x1152 tire slayer: RS6 4G |
|
Registrovaný: 17.07.11 Prihlásený: 29.12.20 Príspevky: 1516 Témy: 3 | Napísal BX: 25.11.2014 21:35 | |
|
Jemine, stále sme pri tom, že viesť začiatočníkov k používaniu goto je zlé. Bodka.
_________________ Na súkromné správy týkajúce sa problémov, ktoré sa riešia vo fóre, neodpovedám! |
|
Registrovaný: 30.12.09 Prihlásený: 01.11.23 Príspevky: 265 Témy: 45 Bydlisko: Praha_4/Presov | Napísal vital: 25.11.2014 21:52 | |
|
viest zaciatocnikov k pouzivaniu goto je mozno zle, ale rozhodne nie bodka, pretoze horsie je zakryvat zaciatocnikom oci vyjadreniami typu "urcite konstrukcie v C su zle a nemaju sa pouzivat". ak chce niekto vyuzit moznosti C naplno, mal by ich najprv poznat, tym padom by sa aj zaciatocnici mali dozvediet o tom, co to vlastne goto je a naco sa hodi, naco zas menej. dost podobna zalezitost ako dogmaticke znasilnovanie typov, pochadzajuce z C++.
to vsak asi zbytocne pisem niekomu, kto nieje schopny prejavit stipku respektu odpovedou na polozenu otazku, a miesto toho zacina vetu slovom "Jemine" a konci svoj post arogantnym "Bodka."
_________________ PC: mobo: Asus PRIME Z490-P cpu: i7 10700F ram: CL16 HyperX 2x8GB DDR4 3200MHz CL16 FURY gpu: MSI R7 250 1GD5 OC ssd: Samsung EVO 850 120GB + EVO 860 250GB psu: EVGA 500B chassis: Fractal CORE 3500W lcd: Samsung U28E590D <3: mobo: DFI LanParty UT P45 t2rs; cpu: Core2Extreme QX6850; ram:OCZ 4x1GB 1150Mhz PC9200 CL5; gpu: asus 9800gx2 hdd: Samsung F3 500GB; psu: TTTP-1,5kW; chassis: Fractal Define r2 lcd: Samsung SyncMaster 2343NW @2048x1152 tire slayer: RS6 4G |
|
Registrovaný: 17.07.11 Prihlásený: 29.12.20 Príspevky: 1516 Témy: 3 | Napísal BX: 25.11.2014 22:47 | |
|
Lebo tu riešiš sprostosti a už ma to dosť nebaví Keď bude človek poznať základné konštrukcie jazyka a nadobudne nejakú programovaciu zručnosť, tak nech si kľudne používa goto, kde chce. Ale zo skúseností viem, že ukázať začiatočníkovi goto je extrémne kontraproduktívne, pretože to začne písať úplne všade. A to je naozaj zle, to nevyvrátiš.
_________________ Na súkromné správy týkajúce sa problémov, ktoré sa riešia vo fóre, neodpovedám! |
|
Registrovaný: 24.08.12 Prihlásený: 09.02.19 Príspevky: 59 Témy: 0 | Napísal faraon: 26.11.2014 21:09 | |
|
Nechtěl jsem se do toho dlouhou dobu míchat, ale prostě nemůžu mlčet. Je třeba říct že GOTO je užitečný příkaz, ale s řadou vedlejších efektů, které nejsou na první pohled zjevné. Abych nepsal romány, tak uvedu ten asi nejhorší: Nevidíš kam skáče!Zatímco break a continue jasně říkají co provedou, a nalézt jejich cílový bod je otázkou vyhledání nejbližší závorky, u goto může být jeho label kdekoliv. Navíc u začátečníka, kterého ve škole učí používat jednopísmenné proměnné a má problém vymyslet smysluplný název pro funkci (a ještě neslyšel ani o CamelCase), nemůžeme očekávat že bude schopný dost návodně pojmenovat label a opatřit ho dostatečně informativním komentářem! To co Dijkstra napsal v osmašedesátém dnes platí tolikrát víc, kolikrát větší a složitější programy se píšou, a ještě bych to umocnil počtem vrstev, které daný program oddělují od reálného hardwaru! Modernější jazyky než dnes už historické C mají konstrukce umožňující vyskočit třeba z několika cyklů současně, je otázka jestli něco jako "break 4" skutečně přináší víc užitku nebo problémů, ale pořád vidím jediné smysluplné použití goto právě a jedině k téhle činnosti. Samozřejmě s podmínkou toho co jsem psal o názvech a komentářích. JENŽE! Díky borcům co před víc než půlstoletím vymysleli strukturované programování je vždycky víc možností jak vnořené cykly ukončit, přímo použitím nějakého flagu v jejich podmínce. Když z nich vyskočím přes goto, tak na samotné podmínce nijak nepoznám že je i jiný způsob jak se může ukončovat, a pokud tam bude nějaký bug, tak se bude velmi dlouho hledat. Dnes se pracuje obvykle v týmech, a pokud by někdo provedl něco takového, zasloužil by od postiženého kolegy fláknout klávesnicí IBM model M přes ksich, s pořádným rozmachem! Námitku že testování další podmínky zpomaluje program neberu, ty dvě instrukce strojového kódu ho určitě nezpomalí tolik, jako desetitisíce jiných instrukcí, nasviněných v důsledku chybného návrhu zbytku programu. Navíc je nutné aby programátor znal i ty jiné způsoby jak víc cyklů, switchů nebo libovolných jiných struktur přerušit současně, a používal je, protože jedině tím se naučí myslet na ně už od samotného začátku kdy začne algoritmus sestavovat. Potom třeba zjistí že to goto skutečně není potřeba vůbec tak často jak to na první pohled vypadá. Mě trvalo pěkných pár let se tohle naučit. Takže na závěr, v podobných případech říkám: "Ano, goto existuje, ale nepoužívej ho dokud nebudeš psát programy které mají aspoň 10000 řádků!"P.S. Samozřejmě je možné nepatrně zrychlit program tím, že se do už fungujícího pár goto doplní, ale stará moudrost říká, že nic tak nezpomalí program jako předčasná optimalizace
_________________ "Existuje pouze jeden člověk, který má méně přátel než Bill Gates, a tím je Saddám Husajn." (Paul Grayson) |
|
Registrovaný: 17.07.11 Prihlásený: 29.12.20 Príspevky: 1516 Témy: 3 | Napísal BX: 27.11.2014 12:01 | |
|
Faraon, veľmi pekný koment
_________________ Na súkromné správy týkajúce sa problémov, ktoré sa riešia vo fóre, neodpovedám! |
|
Registrovaný: 13.11.07 Prihlásený: 20.08.16 Príspevky: 1702 Témy: 0 | Napísal chrono: 27.11.2014 13:29 | |
|
Príkaz goto je nenahraditeľný (napr. keď sa vo fuinkcii alokuje nejaká pamäť, otvára súbor... tak je rozumnejšie mať všetky uvoľňovania pamäte, zatváranie súborov,... na jednom mieste, aby sa na nič nezabodlo ani v prípade, že nastane nejaká chyba). Každopádne v cykle, v ktorom stačí použiť správne podmienky (v tomto konkrétnom prípade feof) a podmienku if namiesto switch je používanie goto na ukončenie cyklu pravdepodobne zbytočné (a ja by som aspoň pridal komentár, že to goto slúži práve na ukončenie cyklu, pretože nie je možné použiť break).
|
|
Registrovaný: 24.08.12 Prihlásený: 09.02.19 Príspevky: 59 Témy: 0 | Napísal faraon: 27.11.2014 18:54 | |
|
Chrono, nechci ti brát tvojí víru, ale goto JE nahraditelné. A to minimálně od roku 1958, kdy vznikl první návrh Algolu! Samozřejmě že bych se bez všech těch serepetiček obešel, když mám IF a GOTO tak udělám úplné i neúplné větvení bez ELSE, udělám libovolný cyklus bez WHILE, FOR nebo DO, udělám si tabulku skoků bez SWITCH, můžu skákat odkudkoli kamkoli se mi zlíbí. Prostě si tam ty skoky namrskám jeden přes druhý jako špagety, a ještě je pořádně zamíchám, aby to vypadalo hodně zašmodrchaně, aspoň se mi v tom nebude nikdo hrabat Určitě znáš termín "špagetový kód", tak toho jsem si v BASICu užil dosytosti. Byly to krásné časy s Didaktikem Gama, kdy jsem menu řešil takhle: Kód: 10 PRINT "Vigenerova sifra" 20 PRINT "1 - Nacist text" 30 PRINT "2 - Nacist heslo" 40 PRINT "3 - Zobrazit text" 50 PRINT "4 - Zasifrovat" 60 PRINT "5 - Rozsifrovat" 70 PRINT "6 - Konec programu" 80 LET a$ = INKEY$: IF a$<"1" OR a$>"6" THEN GOTO 80 90 GOTO VAL(a$)*100 100 INPUT "Zadej text: ",t$ 110 GOTO 10 200 INPUT "Zadej heslo: ",h$ 210 GOTO 10 300 PRINT t$ 310 IF INKEY$="" THEN GOTO 310 320 GOTO 10 400 REM podprogram pro sifrovani 490 GOTO 10 500 REM podprogram pro desifrovani 590 GOTO 10
Jestli jsi nikdy neprogramoval v Sinclair BASICu, tak předpokládám že na řádek 90 budeš čumět jak puk. Ale i bez téhle znalosti poznáš že se obejdu dokonce bez GOSUB a RETURN, takže i ty podprogramy jsou tam vlastně zbytečné, vystačím si s pouhým GOTO. Psal jsem to z hlavy a netestoval, takže po letech neručím za naprostou bezchybnost toho prográmku, můžeš si sám ověřit co to udělá: http://torinak.com/qaopAle i když na ty časy strašně rád vzpomínám, tak právě tyhle způsoby už nikdy používat nechci. Proč? Protože místo goto mám if/else, v cyklech mám continue a break, na vícenásobné větvení switch, který dělá totéž co v M$ Basicu příkaz ON GOTO. Tam byl dokonce i ON GOSUB a pár dalších vychytávek, ale to by bylo na delší povídání. Ohledně toho nenahraditelného goto při otevírání a zavírání souborů, podívej se na tohle: Kód: #include <stdio.h>
char *zprava[]={"\n" "1 - otevření souboru\n" "2 - výpis řádku\n" "3 - převinutí na začátek\n" "4 - uzavření souboru\n" "5 - konec programu\n", " ERROR: Soubor je otevřený!\n", " ERROR: Soubor nelze otevřít!\n", " ERROR: Soubor není otevřený!\n", " KONEC SOUBORU!\n", " ERROR: Jsi na začátku!\n", " Opravdu chceš skončit? [A/N] ", " ERROR: Neplatná volba!\n" };
int main(void) { int konec=0,znak; FILE *soubor=NULL;
while (!konec) { printf(zprava[0]);
while((znak=getchar())<' '); while (getchar()!='\n');
switch (znak) { case '1': if (soubor) printf(zprava[1]); else if (!(soubor=fopen("text.txt","rt"))) printf(zprava[2]); break; case '2': if (!soubor) printf(zprava[3]); else { while ((znak=fgetc(soubor))!='\n' && znak!=EOF) putchar(znak); if (znak<0) printf(zprava[4]); else putchar(znak); } break; case '3': if (soubor) if (!ftell(soubor)) printf(zprava[5]); else rewind(soubor); else printf(zprava[3]); break; case '4': if (soubor) { fclose(soubor); soubor=NULL; } else printf(zprava[3]); break; case '5': if (soubor) printf(zprava[1]); else { printf(zprava[6]); while((znak=getchar())<' '); while (getchar()!='\n'); if ('a'==znak || 'A'==znak) konec=1; } break; default: printf(zprava[7]); } }
return 0; }
Nenajdeš tam ani jediné goto, a také ani jediný komentář Ale můžeš to samé zkusit napsat po svém, s pomocí goto, pak můžeme porovnávat který z těch dvou způsobů je přehlednější. Nebylo by vhodnější tenhle flame oddělit do samostatného vlákna? (Tak jsem si říkal že můj minulý příspěvek byl můj 42. tady, takže je to vlastně nejdůležitější příspěvek ve Vesmíru )
_________________ "Existuje pouze jeden člověk, který má méně přátel než Bill Gates, a tím je Saddám Husajn." (Paul Grayson) |
|
Registrovaný: 13.11.07 Prihlásený: 20.08.16 Príspevky: 1702 Témy: 0 | Napísal chrono: 27.11.2014 21:56 | |
|
Keď potrebuješ vo funkcii napr. načítať súbor do pamäte a niečo s jeho obsahom urobiť, ako riešiš možnosť, že sa napr. nebude dať súbor otvoriť, prípadne že fread a alebo malloc zlyhá? Máš tam kopec podmienok a opakované zatváranie súboru, uvoľňovanie pamäte...?
PS: Ten tvoj príklad už teraz nie je najprehľadnejší a to tam vôbec neriešiš chyby, ktoré môžu nastať.
|
|
Registrovaný: 24.08.12 Prihlásený: 09.02.19 Príspevky: 59 Témy: 0 | Napísal faraon: 29.11.2014 8:13 | |
|
Úplně jednoduše, podle zásad strukturovaného programování kodifikovaných kolem roku 1960, říká se tomu vnořování: Kód: if ((pointer=malloc...)) činnost; else chyba;
Podle toho co tvrdíš bych řekl, že bys měl nutně navštívit tuhle akci: http://www.root.cz/zpravicky/prednaska- ... -spagetam/Pár těch chyb co v tom narychlo spíchnutém ukázkovém programu mám mi vyjmenuj A jestli ti připadá nepřehledný, tak si ho prohlédni z větší dálky nebo si zmenši písmo v prohlížeči, možná tě překvapí co všechno můj mírně upravený Whitesmiths ukazuje, dokonce i po vytištění na papír bez jakéhokoliv zvýraznění. Samozřejmě by neuškodilo přidat pár komentářů a prázdný řádek pod každý break, nebo nějaké ty mezery kolem operátorů, vím. Ale tobě možná přijde přehlednější něco takového: Kód: int p,k,l,i,j,d,q,R,t,r; S1: s=0; p=1; S2: if (s==0) { i=1; j=n; k=n; l=2*n+1; } if (s==1) { i=n+1; j=2*n; k=0; l=n+1; } d=1; q=p; r=p; S3: if (x[i]>K>x[j]->K) goto S8; S4: k=k+d; x[k]=x[i]; c[k]=c[i]; S5: i+=1; q-=1; if (q>0) goto S3; S6: k+=d; if (k==l) goto S13; else x[k]=x[j];c[k]=c[j]; S7: j-=1; r-=1; if (r>0) goto S6; else goto S12; S8: k+=d; x[k]=x[j]; c[k]=c[j]; S9: j-=1; r-=1; if (r>0) goto S3; S10: k+=d; if (k==l) goto S13; else x[k]=x[i];c[k]=c[i]; S11: i+=1; q-=1; if (q>0) goto S10; S12: q=p; r=p; d=-d; t=k; k=l; l=t; if (j-i<p) goto S10; else goto S3; S13: p+=p; if (p<n) { s=1-s; goto S2; } if (s==0) for (t=1; t<=n; t+=1) { x[t]=x[t+n];c[t]=c[t+n] }
Mám tu jednu starší učebnici Pascalu, která je na používání GOTO založená. Na ty ukázkové programy v ní je dost smutný pohled. Ono se totiž říká: "GOTO je něco jako airbag, je dobré ho mít když všechno ostatní selže, ale není dobré ho používat často."A "opakované zatváranie súboru, uvoľňovanie pamäte" snad není problém, neumíš vyNULLovat ukazatel? Také si na to můžeš udělat funkci nebo makro. Samozřejmě předpokládám že ta tvoje funkce má nějakou návratovou hodnotu a ty jí testuješ! Prostě, jak řekl Linus: Kecy jsou k ničemu, ukaž kód!
_________________ "Existuje pouze jeden člověk, který má méně přátel než Bill Gates, a tím je Saddám Husajn." (Paul Grayson) |
|
Registrovaný: 13.11.07 Prihlásený: 20.08.16 Príspevky: 1702 Témy: 0 | Napísal chrono: 29.11.2014 10:58 | |
|
A ako budú vyzerať tie vnorené podmienky, keď tam bude otvorenie súboru, zistenie jeho veľkosti, alokovanie pamäte a načítanie súboru do pamäte? (každá tá činnosť môže zlyhať)
Keď si už citoval Linusa, tak ti je pravdepodobne jasné, že vnorené podmienky podľa neho nie sú správne riešenie a v linuxovom jadre sa príkazy goto používajú napr. na uvoľňovanie zdrojov pri chybe veľmi často.
Naozaj je, podľa teba, niečo ako printf(zprava[1]); prehľadné? Čo presne to vypisuje? (bez toho, aby si sa pozrel do toho poľa) Aký zmysel tam to pole má?
|
|
Registrovaný: 24.08.12 Prihlásený: 09.02.19 Príspevky: 59 Témy: 0 | Napísal faraon: 29.11.2014 15:49 | |
|
Kód: if (fopen) if (malloc) ... else printf("Málo paměti!\n"); else printf("Soubor nelze otevřít!\n");
Ukaž jak bys to udělal ty, s goto a lépe. Samozřejmě stále tvrdím to co jsem psal hned poprvé: "Ano, goto existuje, ale nepoužívej ho dokud nebudeš psát programy které mají aspoň 10000 řádků!"Linus má dobrý důvod pro svoje názory, a nebude to jen tím že zdrojáky linuxového jádra mají přes 10000000 řádků. Kromě jiného ho píšou lidé s roky praxe kteří goto prostě "umí" používat, ale pro začátečníka je goto jed. Tady máš důvod proč v jádře používají goto: Kód: #include <stdio.h>
int main(int argc,char **argv) { int f,i,j,k,n,o;
if (argc>1) { if (sscanf(argv[1],"%d",&n)) { for (o=0;o<1000000;++o) { f=1; for (i=0;f && i<10;++i) for (j=0;f && j<10;++j) for (k=0;f && k<10;++k) if (n==i && n==j && n==k) f=0; } } else printf("Chybný parametr!\n"); } else printf("Zadej parametr!\n");
return 0; }
gcc -ansi -pedantic -Wall -O0 flag.c && time ./a.out 8 Průměr z deseti pokusů: 5.9882sKód: #include <stdio.h>
int main(int argc,char **argv) { int i,j,k,n,o;
if (argc>1) { if (sscanf(argv[1],"%d",&n)) { for (o=0;o<1000000;++o) { for (i=0;i<10;++i) for (j=0;j<10;++j) for (k=0;k<10;++k) if (n==i && n==j && n==k) goto loop; loop:; } } else printf("Chybný parametr!\n"); } else printf("Zadej parametr!\n");
return 0; }
gcc -ansi -pedantic -Wall -O0 goto.c && time ./a.out 8 Průměr z deseti pokusů: 5.0300sTo printf(zprava[1]); má jednoduchý důvod, některé z těch textů jsou tam až třikrát. Takže ono pole je následek optimalizace, prováděné na už fungujícím programu, tedy narychlo spíchnutém ukázkovém programu, který nemá ani jeden komentář. Měl by je u každé podobné konstrukce, tím si buď jistý. Jen mi není jasné proč zrovna ty goto tak bráníš, když jsi jako první radil použít break. U počítačů se tomu říká multitasking, u lidí schizofrenie
_________________ "Existuje pouze jeden člověk, který má méně přátel než Bill Gates, a tím je Saddám Husajn." (Paul Grayson) |
|
Registrovaný: 13.11.07 Prihlásený: 20.08.16 Príspevky: 1702 Témy: 0 | Napísal chrono: 29.11.2014 16:37 | |
|
S goto by to mohlo vyzerať napr. takto: Kód: { FILE *file = NULL; uint8_t *mem = NULL; long size;
file = fopen("xxx", "rb"); if (file == NULL) goto fail;
if (fseek(file, 0, SEEK_END) == -1) goto error; size = ftell(file); if (size == -1) goto error;
mem = malloc(size); if (mem == NULL) goto error;
if (fread(mem, size, 1, file) != 1) goto error; fclose(file);
return mem;
fail: if (mem) free(mem); if (file) fclose(file); return NULL; }
a s vnorenými podmienkami takto: Kód: { FILE *file; uint8_t *mem; long size;
file = fopen("xxx", "rb"); if (file != NULL) { if (fseek(file, 0, SEEK_END) != -1) { size = ftell(file); if (size != -1) { mem = malloc(size); if (mem != NULL) { if (fread(mem, size, 1, file) == 1) { fclose(file); } else { free(mem); fclose(file); return NULL; } } else { fclose(file); return NULL; } } else { fclose(file); return NULL; } } else { fclose(file); return NULL; } } else { return NULL; }
return mem; } Ak by som tam okrem jednoduchého načítania robil ešte niečo iné (napr. nejako filtroval alebo konvertoval tie načítavané dáta), tak by tam tých úrovní zanorenia bolo ešte viac a rovnako by tam bolo aj viac tých return (a teda aj miestm na ktorých sa musia uvoľnovať použité prostriedky).
|
|
| Stránka: 1 z 1
| [ Príspevkov: 30 ] | |
Podobné témy | Témy | Odpovede | Zobrazenia | Posledný príspevok |
---|
| malloc retazec v Assembler, C, C++, Pascal, Java | 19 | 774 | 30.01.2012 9:55 Fico | | Mám sa učiť C ++/objective C/ C#? v Assembler, C, C++, Pascal, Java | 5 | 732 | 08.07.2014 20:40 XOLOO | | Hledá se programátor C/C++ pro vesmírné projekty (Praha) v Ponuka práce | 0 | 1123 | 10.05.2016 14:59 evolvsys | | rozdiel medzi Borland 3.1 C++ vs Net. C++ v Assembler, C, C++, Pascal, Java | 4 | 576 | 20.07.2010 12:54 walther | | Naučte se C++ za 21 dní + C++Builder 6 v Assembler, C, C++, Pascal, Java | 18 | 2414 | 21.05.2010 21:08 Wpegb | | Hladam hracov na C&C Generals Zero Hour v Počítačové hry | 10 | 1250 | 07.03.2007 19:22 Spirit | | K: PC Literaturu- C++/C#/java/python/ruby/RoR v Kúpim | 0 | 410 | 13.05.2014 18:16 expresado | | Čo mi treba na programovanie v C/C++ v Assembler, C, C++, Pascal, Java | 17 | 1147 | 25.09.2011 18:14 reDo | | aky je rozdiel medzi C++ a Visual C++ ? v Assembler, C, C++, Pascal, Java | 8 | 1964 | 19.02.2011 22:46 vendo2 | | Hladame 3x C/C++ Linux developer- projekt 11/2016-2/2017 v Ponuka práce | 1 | 552 | 24.10.2016 15:28 michalesku | | Darujem knihy o programovaní (HTML, Java, Visual C++, C++ Builder, Android) v Vymením a darujem | 0 | 430 | 01.04.2019 11:20 tomasteicher | | program na projekt (C#, C++, pascal, java) v Assembler, C, C++, Pascal, Java | 2 | 833 | 12.03.2009 12:08 Svjatogor | | C/C++ problém so súbormi a hodnotami v Assembler, C, C++, Pascal, Java | 2 | 311 | 09.12.2012 10:43 nBXXL | | C# alebo C++ , ktore knizky na ucenie? v Assembler, C, C++, Pascal, Java | 20 | 1795 | 12.02.2011 0:12 The | | C&C Generals : Zero Hour - turnaj v Počítačové hry | 0 | 775 | 25.02.2009 20:18 k0t0l | | C# alebo C++ appka/program na výpočty v Assembler, C, C++, Pascal, Java | 1 | 385 | 20.03.2015 22:36 walther |
| Nemôžete zakladať nové témy v tomto fóre Nemôžete odpovedať na témy v tomto fóre Nemôžete upravovať svoje príspevky v tomto fóre Nemôžete mazať svoje príspevky v tomto fóre
|
|