8. előadás (2005. április 19.) Pozicionálás fájlban (folyt.) I/O mechanizmus váltás Hibakezelő függvények Változók tárolási osztályai Parancssor-argumentumok 1
Pozícionálás fájlban 3. int fgetpos (FILE *stream, fpos_t *ptr); A ptr mutatóval címzett változóba olvassa az aktuális pozíciót, vagy hiba esetén nem nulla értékkel tér vissza. int fsetpos (FILE *stream, const fpos_t *ptr); Az fgetpos függvénnyel meghatározott és a ptr mutatóval címzett helyen tárolt értékre állítja az aktuális pozíciót, vagy hiba esetén nem nulla értékkel tér vissza. 2
I/O mechanizmus váltás 1. int setvbuf (FILE *stream, char *buffer, int mod, size_t meret); Hiba esetén nem nulla értékkel tér vissza. Ha buffer paraméter értéke nem NULL, akkor ez lesz a buffer, különben a rendszer rendel puffert a függvényhez. A meret a puffer mérete. A mod lehetséges értékei: _IOFBF teljes pufferelés _IOLBF text esetén sorpufferelés _IONBF nincs pufferelés 3
I/O mechanizmus váltás 2. void setbuf (FILE *stream, char *buffer); Ha a buffer paraméter NULL, akkor az adatáram pufferelését kikapcsolja, különben megegyezik a: (void) setvbuf(stream, buffer, _IOFBF, BUFSIZ) függvényhívással. 4
Hibakezelő függvények 1. A könyvtári függvények többsége hiba vagy állományvége jelzés esetén beállítja a hibajelzőket. Az headerben deklarált errno egész kifejezés tartalmazhat egy hibaszámot az előfordult hibáról, pl. EDOM tartomány hiba ERANGE értékkészlet hiba HUGE_VAL túlcsordulásnál ezt adja vissza a függvény, alulcsordulásnál pedig 0-át. 5
Hibakezelő függvények 2. void clearerr (FILE *stream); törli az EOF -et és a hiba állapotjelzőt int feof (FILE *stream); Nem nulla értékkel tér vissza, ha az EOF állapotjelző be van állítva. int ferror (FILE *stream); Nem nulla értékkel tér vissza, ha a hiba-állapotjelző be van állítva. 6
Hibakezelő függvények 3. void perror (const char *s); Kiírja az s -t és az errno -hoz tartozó (gépfüggő) hibaüzenetet, egyenértékű az fprintf (stderr,”%s: %s\n”, s, ”hibaüzenet”) függvényhívással. A hibaüzenetet az strerror függvénnyel határozhatjuk meg: char *strerror (n); Visszatérési értéke az n hibaszámhoz tartozó (implementáció függő) hibaüzenet karaktersorozatának mutatója. 7
Változók tárolási osztályai 1. A változók (objektumok) további jellemzője (az azonosítón, típuson, aktuális értéken és a címen túl) a tárolási osztály. Tárolási osztály: élettartam: a változó memória-tárolási életciklusa, érvényességi kör: azt a C forrásbeli területet jelöli ki, ahol az azonosító látható (aktív). A változó deklarációk nem mindegyike jár együtt memória allokálással: definíció: allokálás hivatkozás: utalás egy definícióra 8
Változók tárolási osztályai 2. ANSI C-ben a változó deklarációját az inicializáló kifejezés teszi definícióvá. Inicializálás nélkül -bizonytalan definíció- a forrás maradék részétől függően definíció vagy hivatkozás. Az extern közli a fordítóval, hogy a változót máshol definiálták. 9
Változók tárolási osztályai 3. Élettartam (duration) static (rögzített): a változó értékének megőrzése az érvényességi körbe tartozó programvégrehajtások között garantált és nullára inicializált. auto (automatikus): az érvényességi körből kilépve a változó értéke eltűnik. Az automatikus változó inicializálása során korábban deklarált változókat használhatunk a kifejezésekben, static-nál nem! 10
Változók tárolási osztályai 4. void inc() { int j=1; static int k=1; j++; k++; printf (”\n %d %d”, j, k); } main () { inc();/* 2,2 */ inc();/* 2,3 */ inc();/* 2,4 */ } 11
Változók tárolási osztályai 5. Érvényességi kör (scope) program: a program minden részéből látható, globális változó, fájl: a deklarációs ponttól a fájl végéig, függvény: egy függvényen belül, blokk: egy blokkon belül. Minden alacsonyabb szinten lévő változó átmenetileg felüldefiniálja az azonos nevű változókat. Fájl érvényesség esetén a static arra alkalmas, hogy a fájlon belül található függvények közösen használhas- sanak változókat, melyeket más nem láthat: modul. 12
Változók tárolási osztályai 6. Pl. int i;/* program */ static int j;/* fájl */ fv (k)/* program */ int k;/* blokk */ { int m;/* blokk */ start:/* függvény */.... } 13
Változók tárolási osztályai 7. auto: { int i; Csak blokkérvényességű lehet. Minden utasításblokk elején (nemcsak a függvények kezdetén) lehet változókat deklarálni, amelyekhez rendelt memóriát a fordító a blokk aktívvá válásakor foglalja le, a memóriahely nem rögzített. 14
Változók tárolási osztályai 8. static: { static double x; Függvényen belül: rögzített élettartamú. A program a változó számára az indításkor foglal memóriát. A program futása során a változóhoz rendelt memóriatartalom megőrződik, a változó aktuális értéke a blokk újraaktiválásakor az előző futás utáni állapotban marad. Függvényen kívül: fájl érvényességű. 15
Változók tárolási osztályai 8. extern: Függvényen belül: globális hivatkozás Függvényen kívül: globális definíció A változó számára az adatszegmensen belül fix tárolóhely allokálódik. register: Függvényen belüli automatikus változók esetén az élettartam mellett tájékoztatja a compilert, hogy a változót lehetőleg helyezze regiszterbe. Mivel ez gépfüggő lehet, nem alkalmazható rá az & operátor. 16
Változók tárolási osztályai 8. const: A változó értéke nem változhat (a #define helyett használható). volatile: A gépi megvalósítást az egyébként alkalmazott optimálások elhagyására kényszeríti. Megjegyzés: Minden függvény szimbólum globális, de static int fgv (char *a,...) {... } Ez a függvény a változóhoz hasonlóan csak az adott forrásállományban ismert. 17
Változók tárolási osztályai 9. Változók inicializálása: Explicit inicializálás hiányában a külső és statikus változók kezdeti értéke garantáltan nulla lesz, az automatikus és regiszterváltozók kezdeti értéke határozatlan. Külső és statikus változók inicializálása csak állandó kifejezéssel adható meg, és csak egyszer hajtódik végre. Automatikus és regiszterváltozók kezdeti érték kifejezése bármilyen korábban definált értékű változót vagy függvényhívást tartalmazhat és mindig végrehajtódik, amikor a vezérlés rákerül. 18
Parancssor-argumentumok 1. A main függvény hívásában két argumentum szerepel: argc: az argumentumok száma, argv: karaktersorozatokat tartalmazó tömböt címző mutató. Pl. echo üdv Mindenkinek argc=3 argv[0]="echo", argv[1]="üdv", argv[2]="Mindenkinek" argv[argc]=NULL(ANSI) 19
Parancssor-argumentumok 2. #include main (int argc, char *argv[]) { int i; for (i=1; i<argc; i++) printf ("%s %s", argv[i], (i<argc-1) ? " ": ""); printf ("\n"); return 0; } 20
Parancssor-argumentumok 3. #include main (int argc, char *argv[]) { while (--argc >0) printf ("%s %s", *++argv, (argc>1) ? " ": ""); printf ("\n"); return 0; } Vagy tömörebben: printf ((argc>1) ? "%s " : "%s", *++argv); 21