1 / 27

10. přednáška 10. 4. 2008 - soubory (soubory na elementární úrovni) - projekty

10. přednáška 10. 4. 2008 - soubory (soubory na elementární úrovni) - projekty - správa paměti (16 bitové prostředí) - výstupy na monitor (práce s barvami, 16 bitové prostředí) Studijní materiály najdete na adrese: http://www.uai.fme.vutbr.cz/~vdumek/.

tanek-buck
Download Presentation

10. přednáška 10. 4. 2008 - soubory (soubory na elementární úrovni) - projekty

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 10. přednáška • 10. 4. 2008 • - soubory (soubory na elementární úrovni) • - projekty • - správa paměti (16 bitové prostředí) • - výstupy na monitor (práce s barvami, 16 bitové prostředí) • Studijní materiály najdete na adrese: • http://www.uai.fme.vutbr.cz/~vdumek/

  2. #include <stdio.h> #include <stdio.h> long filesize(FILE *stream); int main(void) { int main(void) FILE *stream; { /* otevri pro cteni */ FILE *stream; stream = fopen(“DUMMY.FIL”, “r”); stream = fopen(“MY.TXT”,”w+”); /* cti ze souboru */ fprintf(stream, “toto je test”); fgetc(stream); printf(“velikost: %ld”, filesize(stream)); /* kontrola na EOF */ fclose(stream); if(feof(stream)) return(0); printf(“konec souboru\n”); } /* zavri soubor */ fclose (stream); return(0); } long filesize(FILE *stream) { length = ftell(stream); long curpos, length; fseek(stream, curpos, SEEK_SET); return length; curpos = ftell(stream); } fseek(stream, 0L, SEEK_END);

  3. Soubory na elementární úrovni - deklarace funkcí elementárního přístupu jsou v IO.H, nelze spoléhat na přenositelnost int creat(const char *jm_soub, int povolen) - pokud soubor s daným jménem existuje, bude přepsán, parametr povolen má smysl pouze pro nové soubory, pokud soubor již existuje a je nastaven pro čtení, volání neuspěje a soubor zůstane nezmě- něný pokud je parametr pro zápis, bude soubor zkrácen na nulovou délku Možné hodnoty parametru povolen (SYS.H, STAT.H): S_IWRITE povolen zápis S_IREAD povoleno čtení S_IREAD | S_IWRITE povoleno čtení a zápis Vytvoření souboru

  4. Pro téměř všechny OS platí, že pokud je povolen zápis, je povo- leno i čtení. Režim souboru je dán globální proměnnou _fmode (O_TEXT, O_BINARY). Při úspěšném otevření se vrací symbo- lické číslo (>4), jinak se vrací hodnota -1 a je nastavena globální chybová proměnná errno na některou z následujících hodnot: ENOENT jméno souboru nenalezeno EMFILE příliš mnoho souborů EACCES přístup se nepovoluje Prototyp v hlavičce FCNTL.H int open(const char *jm_cest, int pristup) Přístup se konstruuje po bitech jako logický součet příznaků: Otevření souboru

  5. PříznakVýznam O_RDONLY Pro čtení lze použít pouze O_WRONLY Pro zápis jeden příznak O_RDWR Zápis, čtení PříznakVýznam O_NDELAY pro komp. s UNIX O_APPEND Před každým zápisem se ukazatel souboru nastaví na konec O_CREAT Pokud soubor existuje, nemá příznak smysl O_TRUNC Existující soubor se zkrátí na nulu O_EXCL pro komp. s UNIX O_BINARY Binární režim O_TEXT Textový režim U těchto příznaků lze použít libovolnou kombinaci

  6. Při úspěšném otevření se vrací nezáporné celé číslo, ukazatel souboru se nastaví na počátek. Při chybě se vrací -1 a je nasta- vena proměnná errno. int close(int cis_soub) funkce, IO.H, návratová hodnota při úspěš- ném zavření je 0, při neúspěchu -1 při současném nastavení pro- měnné errno (špatné číslo souboru). #include <stdio.h> handle = creat(“DU.FIL”, S_IREAD | #include <string.h> S_IWRITE); #include <fcntl.h> /* pis 10 slabik do souboru */ #include <io.h> write(handle, buf, strlen(buf)); /* zavri soubor */ int main(void) close(handle) { } int handle; char buf[11] = “0123456789”; /* změna default modu textoveho na binarni */ _fmode = O_BINARY; /* vytvor soubor pro cteni a zapis */ Zavření souboru

  7. Čtení a zápis do elementárního souboru int write(int cis_soub, void *blk, int poc_slabik); int read(int cis_soub, void *blk, unsigned poc_slabik); Vyrovnávací paměť, na kterou ukazuje blkje zapsána funkcí write() do souboru se symbolickým číslem cis_soub. Počet slabik, který je zapsán do souboru nebude nikdy větší, než poc_slabik, vyjma zápisu do textových souborů. Pokud je zap- saný počet slabik menší než požadovaný, došlo k chybě (vrací se -1). Automaticky přidané znaky CR se nepočítají. Funkce read() se pokouší číst počet slabik poc_slabik ze souboru sdruženého se symbolickým číslem cis_soub do vyrovnávací paměti blk. Při čtení se vrací přečtený počet bytů, při textovém režimu se odstraňuje znak CR, při znaku CTRL-Z čtení končí. Znaky CTRL-Z a CR se nepočítají.

  8. Maximální počet slabik, které lze přečíst je 65534, neboť 65535 je 0xFFFF (hodnota -1 - chyba). Při zjištění konce souboru je návratová hodnota 0. #include <stdio.h> #include <io.h> int main(void) { void *buf; int handle, bytes; buf = malloc(10); /* hleda soubor a pokousi se cist 10 byte */ if((handle = open(“test.$$$”, O_RDONLY|O_BINARY, S_IWRITE|S_IREAD)) == -1) { printf(“chyba otevreni\n”); exit(1); } if((bytes = read(handle, buf, 10) == -1)

  9. { printf(“spatne cteni\n“); exit(1); } else printf(“cteni: %d slabik precteno\n“, bytes); return(0); } #include <stdio.h> #include <io.h> int main(void) { int handle, length, res; char string[40]; /* vytvori soubor a zapise do nej string, pokud soubor existuje, bude prepsan */ if((handle = open(“test.$$$“, O_WRONLY|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE)) == -1 { printf(“chyba otevreni\n“); exit(1); }

  10. strcpy(string, “nazdar studente\n“); length = strlen(string); if((res = write(handle, string, length)) != length) { printf(“chyba zapisu do souboru\n“); exit(1); } printf(“zapsano %d slabik do souboru\n“, res); close(handle); return(0); } FILE *fdopen(int cis_soub, char *typ) Při sdružení elementárního souboru se streamem musí být typ proudu shodný s režimem souboru s číslem cis_soub. int fileno(FILE *dat_pr) Pokud má stream více symbolických čísel, vrací fileno() to číslo, které bylo proudu přiřazeno při prvním otevření, pro práci se soubory na elementární úrovni není nabídka funkcí a maker tak bohatá, jako pro práci se streamy. Spojení souborů na elementární úrovni s proudy dat

  11. /* demonstrace funkce fdopen */ #include <stdio.h> #include <io.h> int main(void) { int cis_soub, stav; FILE *proud; /* otevri soubor */ cis_soub = open(”muj1.txt”, O_CREAT); /* a predelej ho na proud dat */ proud = fdopen(cis_soub, ”w”); if(proud == NULL) printf(”vsechno spatne\n”); else { /* pisi do nej pomoci funkce pro stream */ fprintf(proud, “ja jsem predelany soubor”); fclose(proud); } }

  12. void main(void) { FILE *sou1, *sou2, *sou3, *a, *b, *c; int han1, han2, han3; sou1 = fopen(“tmp1.txt”, “w+”); han1 = fileno(sou1); sou2 = fopen(“tmp2.txt”, “w+”); han2 = fileno(sou2); sou3 = fopen(“tmp3.txt”, “w+”); han3 = fileno(sou3); fprintf(sou1, “nazev souboru\tsymb.c.\tukazatel na FILE\n”); fprintf(sou1, “\t\t\t(han1-3)\t\t(sou1-3)\n”); fprintf(sou1, “++++++++++++++++++++++++++++++++++”); fprintf(sou1, “tmp1.txt\t\t%d\t\t\t%p\n”, han1, sou1); fprintf(sou1, “tmp2.txt\t\t%d\t\t\t%p\n”, han2, sou3); fprintf(sou1, “tmp3.txt\t\t%d\t\t\t%p\n”, han3, sou3); fcloseall() } nazev souboru symb.c. ukazatel na FILE (han1-3) (sou1-3) ++++++++++++++++++++++++++++++++++++++++++++++++++++ tmp1.txt 5 69F9:027E tmp2.txt 6 69F9:0292 tmp3.txt 7 69F9:02A6

  13. Projekty - členění programu do několika modulů, dekompozice programu, udržení délky modulů na přijatelné úrovni, umožnění spolupráce týmu programátorů, zcela v souladu se zásadami SW inženýrství - jak používat symboly v jiných modulech, než ve kterých jsou definované, jak sestavit výsledný program z jednotlivých modulů - dvě fáze vytváření programu: překlad - týká se pouze zpracovávaného modulu, sestavení - odkazy na symboly definované v jiných modulech - některá symbolická označení se mohou vztahovat pouze pro překlad, některá pro sestavování - je nutné, aby měl překladač k dispozici informaci o objektu

  14. Konstanty a makra - řešení pomocí vkládaného modulu (přípona .h je nepovinná) dny.h #define PONDELI 1 a1.c a2.c #define UTERY 2 #include “dny.h” #include “dny.h” #define STREDA 3 …. …. #define CTVRTEK 4 int den; int d2; #define PATEK 5 …. …. #define SOBOTA 6 if(den==PONDELI) d2 = SOBOTA; #define NEDELE 7 { …. } …. Datové typy - typedef, použití pojmenovaných datových typů, vzhledem k typové kontrole opět řešíme pomocí #include dny.h #define PONDELI 1 struct XXX #define UTERY 2 { #define STREDA 3 int a; #define CTVRTEK 4 float b; #define PATEK 5 char c; #define SOBOTA 6 }; #define NEDELE 7

  15. #include “dny.h” #include “dny.h” …. …. struct XXX str1={UTERY, 8.2, “Ahoj”}; int d2; int den; int je_weekend(struct XXX *par) void main(void) { { if(par->a==SOBOTA || par->==…) if(den == PONDELI) return 1; { …. } else } a1.c return 0; a2.c } Funkce - použité funkce musí mít uvedenu deklaraci svého prototypu, ne- musí být uvedeno v modulu, kde je definice hlavicka.h void funkce_1(int); int funkce_2(char*); float fun_a(void); int *fun_b(int, int);

  16. #include “hlavicka.h” #include “hlavicka.h” void main(void) void funkce_1(int x) { { float f: float z; int a, *b; …. f = fun_a(); z = fun_a(); b = fun_b(1, 2); …. a = funkce_2(“ahoj”); } funkce_1(a); } int funkce_2(char *y) { …. } #include “hlavicka.h” float fun_a(void) { …. } int *fun_b(int a, int b) { …. } c2.c c1.c c3.c Proměnné - globální charakter některých dat

  17. - proměnné třídy extern (globální doba života), možnost viditel- nosti i v jiných modulech, definice bývá v jednom modulu, ve zbývajících deklarace float GLOB = 9.9; /* definice s nepovinnou inicializací */ … GLOB *= 6.2; … extern float GLOB; /* deklarace */ … if(GLOB > 1234.5) { … } … B1.C B2.C - při realizaci projektu se obvykle vytváří jeden hlavičkový soubor (deklarace globálních proměnných, definice maker, konstant, datových typů) - problém nastává v okamžiku, kdy potřebujeme vložit modul s deklaracemi globálních proměnných do modulu, ve kterém jsou tyto definovány. Překladač nepovoluje, aby se při překladu souboru objevila současně deklarace i definice - použití podmíněného překladu.

  18. #include "dat.h" … if(GLOB > 1234.5) { … } … #include "dat.h" … GLOB *= 6.2; … float GLOB = 9.9; dat.c extern float GLOB; b2.c dat.h b1.c - při překladu modulu s definicemi globálních dat je potřeba vyřadit část hlavičkového souboru s deklaracemi globálních proměnných #define ANO 1 #define NE 0 struct uiop { char *a; int dotaz; float q; }; void fce1(void); void fce2(struct uiop*); #if !defined DATA extern int promenna_1; extern struct uiop str; #endif #include "hl.h" void fce1(void) { … } void fce2(struct uiop *par) { … } x2.c #include "hl.h" void main(void) { fce2(&str); fce1(); } hl.h x1.c #define DATA #include "hl.h" #undef DATA int promenna_1 = 6; struct uiop str = {"AHOJ", ANO, 3.5}; x3.c

  19. - řízení při sestavování programu přebírá tzv. projekt, skládá se ze zdrojových souborů (.c), relativních modulů (.obj), knihovních modulů (.lib), textový, binární - knihovny lze vytvářet pomocí programu - knihovník, spojení více modulů .obj do jediného souboru (TLIB) Správa paměti (platí pouze pro šestnáctibitové prostředí) Volbou paměťového modelu určujeme mechanismus adresování. Přesahuje-li velikost kódu hranici segmentu, je použit další segment. Platí to i pro data. Tato činnost je v případě programování v assembleru v rukou programátora, u vyšších jazyků je tato činnost dána automaticky volbou paměťového modelu. Touto volbou je určeno, jaké se používají ukazatele jak pro data, tak pro kód. Typy směrníků: near, far, huge. Near - 16 b., používá k výpočtu adresy jeden registr pro offset a segment se bere podle stavu DS nebo CS. Aritmetika funguje bez problémů.

  20. Správa paměti (platí pouze pro šestnáctibitové prostředí) Far - 32 b., obsahuje segmentovou část, takže data, nebo kód mohou mít více segmentů, velikost může přesáhnout velikost 64 KB. S aritmetikou mohou být problémy, neboť pro =, <> se používá 32 b. jako longinteger, nikoliv jako fyzická adresa, ostatní relační operátory používají pouze offset. Při zvyšování far ukazateleo nějakou hodnotu se mění pouze offset (0531:FFFF + 1 = 0531:0000, 0531:0000 - 1 = 0531:FFFF). Pokud chceme ukazatele porovnávat, musíme používat near, nebo huge. Huge - 32b., na rozdíl od vzdálených jsou v normalizovaném tvaru, takže mají co nejvyšší hodnotu segmentové části. Offset potom může být v rozsahu 0-F. Normalizace se provede tak, že po převodu na fyzickou adresu poslední čtyři bity udávají offset, zbytek je segment. 0000 : 0123 -> 0012 : 0003 0040 : 0056 -> 0045 : 0006 500D : 9407 -> 594D : 0007

  21. Správa paměti (platí pouze pro šestnáctibitové prostředí) Z normalizace vyplývá, že ke každé fyzické adrese existuje pouze jeden normalizovaný ukazatel, takže všechny relační operace dávají stejný výsledek. Po každých 16-ti hodnotách se přetáčí jak segmentová část, tak offset, takže se může manipulovat i s daty, přesahujícími 64KB. Za tuto vlastnost se platí pomalejším zpracováním. Drobný (Tiny) - všechny segmentové registry jsou nastaveny na stejnou adresu. Celý program má k dispozici 64KB. Lze jej převést do tvaru .COM. Malý (Small) - kódový a datový segment se liší a vzájemně se nepřesahují, takže k dispozici je 64KB pro kód a 64KB pro data. Používají se near ukazatele. Střední (Medium) - pro kód se používají far, pro data ne, kód může zabírat 1MB, statická data 64KB. Výhodný pro velké programy, které neudržují mnoho dat v paměti. Kompaktní (Compact) - jde o obrácený střední model. Velký (Large) - pro kód i data se používají far ukazatele. Rozsah dat i kódu je 1MB. Statická data jsou max. 64KB. Rozsáhlý (Huge) - i statická data mohou přesahovat více jak 64KB.

  22. kód CS, DS, SS data TINY heap do 64 KB volná paměť SP zásobník

  23. CS sfile sfile A pro každý zdrojový soubor až 64 KB kód sfile B … sfile Z DS, SS data heap MEDIUM do 64 KB volná paměť zásobník SP far heap volná paměť

  24. Výstupy na monitor - textový režim, grafický režim - v textovém režimu je nejmenší ovladatelný element dán počtem znaků na řádek a počtem řádků (80 x 25, 80 x 43, 132 x 100) - na jedné pozici je možné zobrazit znak daný generátorem (volně programovatelný), množina znaků je omezená (256) - pro každou znakovou pozici je určen znak a atribut (způsob zobrazení) - pro každou znakovou pozici jsou ve videopaměti rezervovány dva byty, první pro kód zobrazovaného znaku, druhý pro atribut - možnost přímého zápisu do videopaměti (rychlost, nekompatibilita), standardní postup je přes funkce - v grafickém režimu větší možnosti, pixel (picture element), počet je závislý na rozlišovací schopnosti adaptéru, monitoru - uložení informace o jednotlivých pixelech se liší podle použitého adaptéru - přímý přístup do videopaměti vyžaduje programování v assembleru, standardní postup je přes grafické funkce - textový režim je rychlejší, ovládání snadnější, omezený počet znaků

  25. 0. řádek 0. 1. 79. 1. řádek 159. offset = (((řádek x šířka_řádku) + sloupec) x 2) 160 = 10100000B = A0H 320 = 101000000B = 140H 24. řádek adresace řádků displeje: 0000H řádek 0 00A0H řádek 2 0140H řádek 4 01E0H řádek 6

  26. Barevné režimy Paleta 16 barev 256 barev High color True color R G B

  27. Adaptér Textový režim Grafický režim MDA 80 x 25 - monochromatický Hercules 80 x 25 720 x 348 monochromatický monochromatický CGA 80 x 25 (16 barev) 640 x 200 (monochromatický) 320 x 200 (4 barvy) EGA 80 x 25 (16 barev) 640 x 350 (16 barev) 80 x 43 (16 barev) VGA 80 x 25 (16 barev) 640 x 480 (16 barev) 80 x 50 (16 barev) 320 x 200 (256 barev) SVGA jako VGA 800 x 600 (16 barev) 1024 x 768 (16 barev) Historie grafických adaptérů

More Related