27
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/

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

Embed Size (px)

DESCRIPTION

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/. - PowerPoint PPT Presentation

Citation preview

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

10. přednáška10. 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/

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

#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);

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

- 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ápisS_IREAD povoleno čteníS_IREAD | S_IWRITE povoleno čtení a zápis

Vytvoření souboru

Soubory na elementární úrovni

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

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 nenalezenoEMFILE 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

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

Příznak VýznamO_RDONLY Pro čtení lze použít pouze O_WRONLY Pro zápis jeden příznakO_RDWR Zápis, čtení

Příznak VýznamO_NDELAY pro komp. s UNIXO_APPEND Před každým zápisem se ukazatel souboru

nastaví na konecO_CREAT Pokud soubor existuje, nemá příznak

smyslO_TRUNC Existující soubor se zkrátí na nuluO_EXCL pro komp. s UNIXO_BINARY Binární režimO_TEXT Textový režim

U těchto příznaků lze použít libovolnou kombinaci

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

Při úspěšném otevření se vrací nezáporné celé číslo, ukazatelsouboru 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

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

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četslabik, 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 souborusdruž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 seodstraňuje znak CR, při znaku CTRL-Z čtení končí. ZnakyCTRL-Z a CR se nepočítají.

Čtení a zápis do elementárního souboru

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

Maximální počet slabik, které lze přečíst je 65534, neboť 65535je 0xFFFF (hodnota -1 - chyba). Při zjištění konce souboru jená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)

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

{ 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); }

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

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 typproudu 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

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

/* 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); }}

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

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:027Etmp2.txt 6 69F9:0292tmp3.txt 7 69F9:02A6

Page 13: 10. přednáška 10. 4. 2008 -soubory  (soubory na elementární úrovni) -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

Projekty

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

- ř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 { …. } ….

- 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

Datové typy

Konstanty a makra

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

#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

}

- 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

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

#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){ …. }

- globální charakter některých dat

c1.c

c2.c

c3.c

Proměnné

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

- 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.

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

float GLOB = 9.9; #include "dat.h"…GLOB *= 6.2;…extern float GLOB;

#include "dat.h"…if(GLOB > 1234.5){ … }…

dat.c

dat.h b1.cb2.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 DATAint promenna_1 = 6;struct uiop str = {"AHOJ", ANO, 3.5};

#include "hl.h"void fce1(void){ … }void fce2(struct uiop *par){ … }

#define ANO 1#define NE 0struct 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 main(void){ fce2(&str); fce1();}

x3.c

hl.h

x1.c

x2.c

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

- ří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í)

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

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 : 00030040 : 0056 -> 0045 : 0006500D : 9407 -> 594D : 0007

Správa paměti (platí pouze pro šestnáctibitové prostředí)

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

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í)

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

CS, DS, SS

SP

kód

zásobník

data

volná paměť

heap

do 64 KB

TINY

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

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

sfile sfile A

sfile B

sfile Z

heap

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

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ů

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

0. řádek1. řádek

24. řádek

79.1.0.

159.

adresace řádků displeje: 0000H řádek 000A0H řádek 20140H řádek 401E0H řádek 6

offset = (((řádek x šířka_řádku) + sloupec) x 2)

160 = 10100000B = A0H320 = 101000000B = 140H

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

Barevné režimy

16 barev

256 barev

High color

True color

Paleta

R G B

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

Historie grafických adaptérů

Adaptér Textový režim Grafický režim

MDA 80 x 25 -monochromatický

Hercules 80 x 25 720 x 348monochromatický 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)