9. előadás (2005. április 26.) Parancssor argumentum kezelés példák (K&R) Fordítóprogramok A C előfordító 1
Parancssor arg. kezelés példa 1/a. keres minta #include <stdio.h> #include <string.h> #define MAXSOR 200 main (int argc, char *argv[]) { char sor[MAXSOR]; int talalt=0; if (argc != 2) printf ("Minta?\n"); else while (fgets(sor,MAXSOR,stdin)!=NULL) 2
Parancssor kezelés példa 1/b. /*Az fgets fgv. a következő max. MAXSOR-1 karaktert beolvassa a sor-ba az új sor karakterig (azt is, '\0'). Hiba vagy áll.végnél NULL*/ if(strstr(sor,argv[1])!=NULL) /*Az strstr fgv. visszatérési értéke argv[1] sor-beli első előfordulásának kezdetét címző mutató,vagy NULL, ha nincs benne*/ { printf ("%s",sor); talalt++; } return talalt; 3
Parancssor arg. kezelés példa 2/a. keres -x -n minta x: azt a sort írja ki,amiben nem található n: sorszámozás #include <stdio.h> #include <string.h> #define MAXSOR 200 main (int argc, char *argv[]) { char sor[MAXSOR]; long sorszam=0; int c,kiveve=0,szam=0,talalt=0; 4
Parancssor arg. kezelés példa 2/b. while(--argc>0 && (*++argv)[0]=="-") /* **++argv == "-",[] a legszorosabb*/ while(c=*++argv[0]) switch(c) { case 'x': kiveve=1; break; case 'n': szam=1; default: printf("keres:illegal opció%c\n",c); argc=0; talalt=-1; break; } if(argc!=1) printf("keres -x -n minta \n"); 5
Parancssor arg. kezelés példa 2/c. else while (fgets(sor,MAXSOR,stdin)!=NULL){ sorszam++; if((strstr(sor,*argv)!=NULL)!=kiveve){ if (szam) printf("%ld:",sorszam); printf("%s",sor); talalt++; } return talalt; 6
Fordítóprogramok 1. Gépi utasításkészlet: bináris adatsorozat, melyet a CPU belső értelmezése szerint hajt végre. Szimbolikus gépi nyelv, assembly nyelv: utasítások, változók, gépi tárolóegységek szimbolikus névvel láthatók el. Fordítóprogramja: assembler. CPU specifikusak, nem hordozhatóak. 3 generációs programnyelvek: szabványos CPU független nyelvek. Fordítási mechanizmusok: 1. Soronkénti: interpreter -kötetlen változó deklaráció, 7
Fordítóprogramok 2. -egyetlen forrásprogram, -nehézkes belövés. A fordítás lépései: - lexikális analízis: a nyelvi szimbólumok felismerése és osztályozása: konstansok, makrók, változók, függvények -> szimbólumtábla generálás, - elemzés: a nyelv formális szabályainak megfelelő struktúrák felismerése és alkalmazása - kulcsszó felismerés, 8
Fordítóprogramok 3. - kódgenerálás: gépi utasítássorozat generálás az elemzés alapján - object kód. Szerkesztés a feloldatlan szimbólumok kódjának illesztése a programhoz, kétféle object kód: a.) saját önálló modul több forrásállományból álló program esetén b.) könyvtári hivatkozások saját objektum könyvtárak rendszerhívási felületek betöltő modul: osztott memóriakezelés, áthelyezhető programok. 9
A C előfordító 1. Előfordító - preprocesszor A lexikális analízist megelőző fordítási menet. Feladatai: - makrófeldolgozás, - C forrásállományok beolvasása, - feltételes fordítás vezérlése. Előnyei: - könnyebb program fejlesztés, - olvashatóság javul, - módosíthatóság javul, - portabilitás javul. 10
A C előfordító 2. Szintaktika: Kezdőszimbólum: # Pl. #define PI 3.14152 Hosszú sor: folytató karakter: \ Makrohelyettesítés: Minden szimbólumot a definíciójával. Hibalehetőség: #define MERET 100; int a[MERET]; A programok ne tartalmazzanak mágikus számokat! 11
A C előfordító 3. Függvény típusú makró #define NEV(argumentumlista) makrótest Pl. #define csere(A,B) {int S; S=A; A=B; B=S;} Makróhelyettesítéskor nincs típusellenőrzés: float x=3.2, y=6.3; csere(x, y); /*figyelmeztető üzenet*/ Hibalehetőség: #define negyzet(X) X*X negyzet(a+b) /* a+b*a+b */ #define negyzet(X) (X)*(X) 12
A C előfordító 4. Makrók vagy függvények? Előnyök: - a makrók gyorsak (fordítási időben helyettesítődik), - nincs argumentum típus ellenőrzés (többcélú makrók), - javítják a program olvashatóságát. Hátrányok: - az argumentumok annyiszor értékelődnek ki, ahányszor előfordulnak, - többszörösen fordulnak le (helyigényesebb), - nincs argumentum típus ellenőrzés, - a hibafelismerést nehezíti, 13
A C előfordító 5. - mellékhatások ( pl.: i++ , mint argumentum) #define max(A,B) ((A)>(B)?(A):(B)) max(i++, j++) Beépített makrók: __LINE__ forrásfile aktuális sorának száma __FILE__ forrásfile neve __TIME__ fordítás időpontja __DATE__ fordítás dátuma __STDC__ 1, ha a fordító ANSI C Pl. printf("Prog %s:(%d)File nyitási hiba", __FILE__,__LINE__); 14
A C előfordító 6. Makrónév törlése Feltételes fordítás C forrás1 #undef NEV /* a NEV újradefiniálható */ Feltételes fordítás #if feltétel C forrás1 [#elif feltétel C forrás2] [#else C forrás3] #endif 15
A C előfordító 7. A feltétel csak konstans kifejezés lehet: konstans, makrószimbólum. Makrólétezés tesztelése: #ifdef NEV C forrás1 #else C forrás2 #endif vagy #ifndef NEV ... 16
A C előfordító 8. Forrásbeolvasás: beolvasás standard helyről (a Unixban általában \usr\include\), ahol az include állományok vannak: #include <filenév> beolvasás az aktuális directory-ból: #include "filenév" Makró kifejtés megnézése: cc -E prog.c vagy fájlba irányítva: cc -E prog.c > prog.pre 17
A C előfordító 9. Pl. egy összetett, több forrásból álló program: main.c /* main.c */ #include "header.h" #include <stdio.h> char *astring="Üdv Mindenkinek!"; main () { printf("Fut a főprogram\n"); Writestring(SAJ_STR); printf(""Vége \n); } 18
A C előfordító 10. header.h writestring.c /* header.h */ #define SAJ_STR "Üdv Neked!" void Writestring (char *); writestring.c /* writestring.c */ extern char *astring; void Writestring(char *parstring) { printf("%s\n", parstring); printf("Globális változó=%s\n", astring); } 19
A C előfordító 11. Általában a saját header állományokat több forrás olvassa be, ezért gyakran használjuk az extern hivatkozást. Egy globális változó azonban csak egy forrásban definiálható. 20
A C előfordító 12. I. megoldás: main.c seged.c sajat.h int poz_x, poz_y; #include "sajat.h" seged.c sajat.h extern int poz_x, poz_y; 21
A C előfordító 13. II. megoldás, az inicializálás miatt: main.c #define MAIN #include "sajat.h" seged.c sajat.h #ifdef MAIN int poz_x=122, poz_y=543; #else extern int poz_x, poz_y; #endif 22
A C előfordító 14. III. megoldás: main.c seged.c #define MAIN #include "sajat.h" seged.c 23
A C előfordító 15. sajat.h #ifdef MAIN #define EXTERN #else #define EXTERN extern #endif EXTERN int poz_x, poz_y; 24