Prezentace se nahrává, počkejte prosím

Prezentace se nahrává, počkejte prosím

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,

Podobné prezentace


Prezentace na téma: "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,"— Transkript prezentace:

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 #include 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 - 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_IWRITEpovolen zápis S_IREADpovoleno čtení S_IREAD | S_IWRITEpovoleno čtení a zápis Vytvoření souboru Soubory na elementární úrovni

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: ENOENTjméno souboru nenalezeno EMFILEpříliš mnoho souborů EACCESpří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_RDONLYPro čtenílze použít pouze O_WRONLYPro zápis jeden příznak O_RDWRZápis, čtení PříznakVýznam O_NDELAYpro komp. s UNIX O_APPENDPřed každým zápisem se ukazatel souboru nastaví na konec O_CREATPokud soubor existuje, nemá příznak smysl O_TRUNCExistující soubor se zkrátí na nulu O_EXCLpro komp. s UNIX O_BINARYBinární režim O_TEXTTextový 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 handle = creat(“DU.FIL”, S_IREAD | #include S_IWRITE); #include /* pis 10 slabik do souboru */ #include 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 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 blk je 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í. Čtení a zápis do elementárního souboru

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 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 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 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 souborusymb.c.ukazatel na FILE (han1-3)(sou1-3) ++++++++++++++++++++++++++++++++++++++++++++++++++++ tmp1.txt569F9:027E tmp2.txt669F9:0292 tmp3.txt769F9:02A6

13 - č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 Projekty

14 - řešení pomocí vkládaného modulu (přípona.h je nepovinná) dny.h #define PONDELI 1a1.ca2.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 { …. }…. - typedef, použití pojmenovaných datových typů, vzhledem k typové kontrole opět řešíme pomocí #include dny.h #define PONDELI 1struct 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 Datové typy Konstanty a makra

15 #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 } - 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); Funkce

16 #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) { …. } - globální charakter některých dat c1.c c2.c c3.c Proměnné

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 float GLOB = 9.9; #include "dat.h" … GLOB *= 6.2; … extern float GLOB; #include "dat.h" … if(GLOB > 1234.5) { … } … dat.c dat.hb1.c b2.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 DATA #include "hl.h" #undef DATA int promenna_1 = 6; struct uiop str = {"AHOJ", ANO, 3.5}; #include "hl.h" void fce1(void) { … } void fce2(struct uiop *par) { … } #define ANO1 #define NE0 structuiop { 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 main(void) { fce2(&str); fce1(); } x3.c hl.h x1.c x2.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) 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ů. Správa paměti (platí pouze pro šestnáctibitové prostředí)

20 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 long integer, nikoliv jako fyzická adresa, ostatní relační operátory používají pouze offset. Při zvyšování far ukazatele o 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 Správa paměti (platí pouze pro šestnáctibitové prostředí)

21 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. Správa paměti (platí pouze pro šestnáctibitové prostředí)

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

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

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

26 Barevné režimy 16 barev 256 barev High color True color Paleta RGB

27 Historie grafických adaptérů AdaptérTextový režimGrafický režim MDA80 x 25- monochromatický Hercules80 x 25720 x 348monochromatický CGA80 x 25 (16 barev)640 x 200 (monochromatický) 320 x 200 (4 barvy) EGA80 x 25 (16 barev)640 x 350 (16 barev) 80 x 43 (16 barev) VGA80 x 25 (16 barev)640 x 480 (16 barev) 80 x 50 (16 barev)320 x 200 (256 barev) SVGAjako VGA800 x 600 (16 barev) 1024 x 768 (16 barev)


Stáhnout ppt "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,"

Podobné prezentace


Reklamy Google