22580
Comment:
|
20341
nicim volnu dostupnost prilis trivializujucich vysvetleni
|
Deletions are marked like this. | Additions are marked like this. |
Line 11: | Line 11: |
|| Slajdy k prednáškam || Iné zdroje || || [[http://109.74.151.214/mathematics/progsem/01_seminar_z_programovania.pdf|1]] || [[MercurialReceptar|Mercurial: Varíme z ortuti - zdravo, rýchlo, lacno]] || || [[http://109.74.151.214/mathematics/progsem/02_seminar_z_programovania.pdf|2]] || [[http://mercurial.selenic.com/quickstart/|Mercurial: Quick Start]] || || [[http://109.74.151.214/mathematics/progsem/03_seminar_z_programovania.pdf|3]] || [[http://hgbook.red-bean.com/read/|Mercurial: The Definitive Guide]] || || [[http://109.74.151.214/mathematics/progsem/04_seminar_z_programovania.pdf|4]] || [[http://mercurial.selenic.com/wiki/CzechMercurial|Mercurial: Návod v českom jazyku]] || || [[http://109.74.151.214/mathematics/progsem/05_seminar_z_programovania.pdf|5]] || || || [[http://109.74.151.214/mathematics/progsem/06_seminar_z_programovania.pdf|6]] || || || [[http://109.74.151.214/mathematics/progsem/07_seminar_z_programovania.pdf|7]] || || ## TOTO treba asi poupratovat ##|| [[http://www.math.sk/sarkoci/MPM1SZP/01_seminar_z_programovania.pdf|Pamať, jej adresovanie a smerníky]] || [[MercurialReceptar|Mercurial: Varíme z ortuti - zdravo, rýchlo, lacno]] || ##|| [[http://www.math.sk/sarkoci/MPM1SZP/02_seminar_z_programovania.pdf|Dynamická allokácia pamäti]] || [[http://mercurial.selenic.com/quickstart/|Mercurial: Quick Start]] || ##|| [[http://www.math.sk/sarkoci/MPM1SZP/03_seminar_z_programovania.pdf|Reprezentácia matíc]] || [[http://hgbook.red-bean.com/read/|Mercurial: The Definitive Guide]] || ##|| [[http://www.math.sk/sarkoci/MPM1SZP/06_seminar_z_programovania.pdf|Nizkoúrovňové I/O]] || [[http://mercurial.selenic.com/wiki/CzechMercurial|Mercurial: Návod v českom jazyku]] || ##|| [[http://www.math.sk/sarkoci/MPM1SZP/05_seminar_z_programovania.pdf|Quicksort]] || || ##|| [[http://www.math.sk/sarkoci/MPM1SZP/04_seminar_z_programovania.pdf|Výpočtová zložitosť I., Rekurzia]] || || |
* [[MercurialReceptar|Mercurial: Varíme z ortuti - zdravo, rýchlo, lacno]] * [[http://mercurial.selenic.com/quickstart/|Mercurial: Quick Start]] * [[http://hgbook.red-bean.com/read/|Mercurial: The Definitive Guide]] * [[http://mercurial.selenic.com/wiki/CzechMercurial|Mercurial: Návod v českom jazyku]] |
Line 171: | Line 159: |
a. Veľké datové typy a komplikované datové štruktúry sa funkciám ''nikdy'' neodovzdávajú ako argumenty. Namieto toho sa ako argumenty odovdávajú iba smerníky na ne. Prečo? Na prednáške sa dozviete, že každé odovzdanie argumentu funkcii pri jej volaní obnáša kopírovanie hodnôt argumentov. Jazyk C toto kopírovanie zakrýva ale to neznamená, že k nemu nedochádza. Ak sú argumentami funkcie nejaké veľké štruktúry, znamená to veľa kopírovania a to je neefektívne. Naproti tomu smerník je iba jedno relatívne malé číslo a to sa kopíruje ľahko. | a. Veľké datové typy a komplikované datové štruktúry sa funkciám ''nikdy'' neodovzdávajú ako argumenty. Tak isto ich funkcie ''nikdy'' neodovzdávajú ako hodnoty svojho návratového typu. Namieto toho sa odovzdávajú iba ich adresy. Prečo? Na prednáške sa dozviete, že každé odovzdanie argumentu funkcii pri jej volaní obnáša kopírovanie hodnôt argumentov. Jazyk C toto kopírovanie zakrýva ale to neznamená, že k nemu nedochádza. Ak sú argumentami funkcie nejaké veľké štruktúry, znamená to veľa kopírovania a to je neefektívne. Naproti tomu smerník je iba jedno relatívne malé číslo a to sa kopíruje ľahko. |
Organizačné informácie
Pre ich citlivú povahu budem uvádzať v systéme anjadu.
Štúdijné materiály
Časté chyby
Každodenná programátorská skúsenosť aj vás naučí, že čitateľnosť a zrozumiteľnosť zdrojáku je nie len nutnou podmienkou jeho trvalej spravovateľnosti ale aj cestou k zachovaniu psychyckého zdravia - ako vašeho tak aj môjho. Na užitočnosť štábnej kultúry prišli už naši predkovia, ktorí stáli pri kolíske programovacích jazykov. Budeme sa toho držať aj my. Toto je zoznam pravidiel, ktorých splnenie bude nutnou podmienkou k tomu, aby som vaše zdrojáky vôbec študoval. Preto vám radím, aby ste sa ich snažili dodržiavať už od prvého zadania.
- Chyby týkajúce sa designu funkcií
Každá jedna funkcia alebo procedúra má vykonávať jednu, čo možno najjednoduchšiu činnosť a túto činnosť má vykonávať dobre. Áno, existujú výnimky z tohoto pravidla, ale na tomto seminári sa s nimi nestretneme.
Rozmeniac na drobné predchádzajúci bod: ak žiadam implementáciu funkcie ktorá vykonáva činnosť Č tak tým myslím, bez toho aby som to explicitne zdôraznoval, že funkcia žiadnu inú činnosť nevykonáva. Napríklad ak chcem, aby funkcia inicializovala pole premenných typu int na zadanú hodnotu tak, bez toho aby som to explicitne písal, očakávam, že funkcia nebude ani nič čítať z klávesnice, ani nič písať na obrazovku a vôbec, nebude robiť nič čo bezprostredne nesúvisí s inicializáciou pola.
Veľké datové typy a komplikované datové štruktúry sa funkciám nikdy neodovzdávajú ako argumenty. Tak isto ich funkcie nikdy neodovzdávajú ako hodnoty svojho návratového typu. Namieto toho sa odovzdávajú iba ich adresy. Prečo? Na prednáške sa dozviete, že každé odovzdanie argumentu funkcii pri jej volaní obnáša kopírovanie hodnôt argumentov. Jazyk C toto kopírovanie zakrýva ale to neznamená, že k nemu nedochádza. Ak sú argumentami funkcie nejaké veľké štruktúry, znamená to veľa kopírovania a to je neefektívne. Naproti tomu smerník je iba jedno relatívne malé číslo a to sa kopíruje ľahko.
- Funkcie vymýšlajte tak, aby referovali všetky možné typy chybových stavov ktoré pri ich vykonávaní môžu nastať. Príznaky týchto chybových stavov referujú primárne cez návratovú hodnotu a ak len ak sa to nedá nejak inak.
Zásada o pred-objektovej disciplíne: Všetky "konštruktory" (čiže funkcie, ktoré sa starajú o allokáciu pamäte pre komplikované datové štruktúry) allokujú celé datové štruktúry a volajúcemu procesu cez navratovu hodnotu odovzdávajú iba ich adresy. Všetky "deštruktory" (čiže funkcie, ktoré sa starajú o uvoľnovanie pamäte po komplikovaných datových štruktúrach) uvoľňujú pamäť po celých datových štruktúrach a ako argument preberajú iba smerník na štruktúru ktorú treba zničiť.
- Všetky "konštruktory" (čiže funkcie, ktoré sa starajú o allokáciu pamäte pre komplikované datové štruktúry) treba implementovať tak, aby v prípade keď sa proces allokacie pamäte nepodarí z nejakého dôvodu úspešne zavŕšiť, uvolnili tie časti pamäte ktoré sa im ešte pred nastaním problému allokovať podarilo. Motivácia pre túto zásadu je úplne jasná: kedykoľvek proces allokácie niekde uviazne, treba volajúcemu procesu namiesto allokovanej štruktúry vrátiť chybový stav - ak sa však konštruktor ešte predtým nepostará o upratanie tých častí pamäte ktoré sa mu allokovať podarilo, budú ich adresy nenávratne zabudnuté a nikomu sa ich už nepodarí po celú dobu behu programu uvoľniť.
- Črty jazyka ktoré nepatria do ANSI C
Ak deklarujete napríklad int pole[n] kde n je nejaká predtým inicializovaná premenná, devcpp, žial, nebude frflať. Lenže niečo podobné je z hladiska čistého ANSI C striktne zakázané. Keďže hodnota n nie je v čase kompilácie známa, to čo takouto deklaráciou hovoríte, je vlastne dynamická allokácia pamate. Ale tá sa správne rieši cez funkciu malloc a jej príbuzné.
- Programátorský štýl
Blok kódu začína vždy na novom riadku. Aj v prípade, že sám nemá viac než jeden riadok. Prečo? Už z letmého pohladu na zdroják je jasné aké panujú medzi časťami kódu logické vzťahy.
- Blok kódu je oproti okolitému kódu odsadený o jeden tabulátor doprava. Prečo? Už z letmého pohladu na zdroják je jasné, kde blok kódu začína a kde končí.
- Mená symbolických konštánt sa píšu vždy veľkými písmenami. Prečo? Táto jednoduchá konvencia ktorá programátora prakticky nič nestojí umožnuje už letmým pohladom odlíšiť symbolické konštanty od premenných, čo je viac než užitočné.
- Návratové chybové stavy funkcií sa realizujú ako symbolické konštanty. Prečo? Pri letmom pohlade na kondicionál
if(sucet(argumenty1, argumentyn) == 1)
by sa mohlo zdať, že testujeme, či sa výsledok nejakého výpočtu (ktorý realizuje funkcia sucet) náhodou nerovná jednej. Ak ale čítame
if(sucet(argumenty1, argumentyn) == PROBLEM_PRETECENIE_ROZSAHU_INT)
- Všetky deklarácie lokálnych premenných sa vybavia na začiatku tela funkcie. Dalej nasleduje už iba kód, žiadne prípadné ďalšie deklarácie.
- Medzi deklarácie premenných na začiatku tela funkcie a jeho zvyšok sa vkladá prázdny riadok. Prečo? Programátor čítajúci zdrojový kód preskakuje deklarácie premenných a vracia sa k nim až neskôr, keď sa chce dozvedieť akého typu tá ktorá premenná je. Prázdny riadok na konci deklarácií výrazne ulahčuje takýto spôsob čítania zdrojáku.
- Medzi definíciami funkcií ako aj medzi inštrukciami preprocesora na začiatku zdrojového kódu a kódom samotným sa nachádzajú voľné riadky. Prečo? Opticky to oddeluje veci ktoré spolu súvisia od vecí ktore spolu nesúvisia čo, opäť, zvyšuje čitateľnosť kódu.
- Pri funkciach sa explicitne uvadza datovy typ a navratovy typ aj vtedy, ak tieto nemaju argumenty alebo ziadnu hodnotu nevracaju. Prečo? Dáva nám to dopredu vedieť, čo možno od tej ktorej funkcie očakávať, čo opäť sprehľadňuje zdroják.
Ukážkový Zdroják
1 #include <stdlib.h>
2 #include <stdio.h>
3
4 void print_num(int a)
5 {
6 printf("%d",a);
7 }
8
9 int main(void)
10 {
11 int i, j, k;
12 char *string;
13 double ratio;
14
15 /* nadomnou je volny riadok oddelujuci deklaracie (zasada 3.e) */
16 if(i == j)
17 printf("Premenne i a j maju, zhodou okolnosti, rovnaku hodnotu.\n");
18 else {
19 printf("Premenne i a j maju, zhodou okolnosti, roznu hodnotu.\n");
20 print_num(i);
21 print_num(j);
22 }
23
24 if(&i == (int*)string) {
25 printf("tento kod sa NIKDY nevykona.");
26 i = j+k;
27 j = i-k;
28 }
29
30 for(i=0;;i++)
31 if(i != k) {
32 printf(".");
33 k -= i;
34 } else {
35 printf("zaverecna");
36 break;
37 }
38
39 if(i < 0)
40 i = -i;
41
42 do{
43 i--;
44 printf(".");
45 }while(i!=1)
46
47 /* aj jednoriadkovy blok je blok */
48 if(i>0)
49 if(j<0)
50 j=i;
51 else
52 if(j>0)
53 i=j;
54
55 /* dovidenia */
56 return(0);
57 }