Alapismeretek Programozás I.
Hatwágner F. Miklós Széchenyi István Egyetem, Gy®r
2013. szeptember 29.
Forrásfájltól a programfuttatásig
1
Forrásszöveg megszerkesztése (.c kiterjesztés, ASCII szövegfájl)
elso.c
/* elso.c */ #include <stdio.h> void main(void) { printf("Ez egy C program!\n"); } Kimenet
Ez egy C program! _
Hatwágner F. Miklós
Alapismeretek
Forrásfájltól a programfuttatásig
2
Fordítás (→ compiler)
elso.c
fordító
elso.obj
Üzenetek típusai:
hibaüzenetek (error) gyelmeztet® üzenetek (warning) Megjegyzések: elso.c, 1. sor:
/* elso.c */ /* nyitja és */ zárja több soron át tarthat nem ágyazhatók egymásba
Hatwágner F. Miklós
Alapismeretek
Forrásfájltól a programfuttatásig
El®feldolgozó (preprocessor): egybeépítve a fordítóval közvetlenül a fordítás el®tt lép m¶ködésbe elhagyja a megjegyzéseket végrehajtja, majd elhagyja a direktívákat
előfeldolgozó elso.c
elso.obj fordító
elso.c, 2. sor
#include <stdio.h>
Hatwágner F. Miklós
Alapismeretek
Forrásfájltól a programfuttatásig
El®feldolgozó direktíva: egy sorban, melynek els® nem fehér karaktere a # Fehér karakter (white space): pl. szóköz, soremelés, lapdobás, tabulátor, de még a megjegyzés is #include: betölti a paraméter szövegfájlt stdio.h
→
fejfájl (header): adattípusok, konstansok deníciói,
függvények jellemz®i standard input/output < és > jelek: csak egy bizonyos helyen keresi a fájlt (include les)
Hatwágner F. Miklós
Alapismeretek
Forrásfájltól a programfuttatásig
Függvénydeníció elso.c, 3. sor
void main(void) {
típus függvénynév(formális-paraméterlista) { függvény-test } visszatérési érték típusa void (→ nincs [másutt: eljárás]) fv. neve main
→
indító program
formális-paraméterlista
mindig ( és ) között, most nincsenek
(void)
függvény-test
helye: mindig { és } között
Hatwágner F. Miklós
Alapismeretek
Forrásfájltól a programfuttatásig
Függvényhívás elso.c, 4. sor
printf("Ez egy C program!\n");
függvénynév(aktuális-paraméterlista) printf megjelenteti paraméterét a szabvány kimeneten karakterlánc konstans: id®z®jelek között escape szekvencia (vagy jelsorozat, escape sequence): vezérl®jelek, nem nyomtatható jelek, programnyelvi jelentéssel bíró jelek megjelenítésére ;
→
utasításvég jelzés
Hatwágner F. Miklós
Alapismeretek
Forrásfájltól a programfuttatásig
Esc. szekv.
Jelentés
\a
gyelmeztet® jelzés (bell, cseng®)
\b
visszalépés (backspace)
\f
lapdobás (form feed)
\n
új sor (new line)
\r
kocsi vissza (carriage return)
\t
vízszintes tabulátor (horizontal tab, HTAB)
\v
függ®leges tabulátor (vertical tab, VTAB)
\\
fordított törtvonal (backslash)
\?
kérd®jel
\'
aposztróf
\"
idéz®jel
\ooo
oktális szám
\xhh
hexadecimális szám
\0
zérus ASCII kódú karakter
Hatwágner F. Miklós
Alapismeretek
Forrásfájltól a programfuttatásig
3
Kapcsoló-szerkesztés (link)
fv.-ek tárgykódja: statikus könyvtárakban (.lib) (run-time libraries, standard libraries) keretrendszerben beállítható ezek és a kimeneti fájlok elérési útja elso.obj indító program (obj) könyvtárak (lib) 4
kapcsolószerkesztő
Futtatás
Hatwágner F. Miklós
Alapismeretek
elso.exe
Fahrenheit - Celsius átváltás
Feladat:
°
Számítsuk ki az összetartozó F között,
°
°
értékeket 0 és 300 F
F értékét rendre 20-asával növelve!
= ( °F − 5 9
32)
Adatstruktúra: az értékeket konstansként adjuk meg Algoritmus: minden értékpárt egyesével meghatározunk, majd értéküket megjelentetjük
Hatwágner F. Miklós
Alapismeretek
Fahrenheit - Celsius átváltás pelda1.c
/* PELDA1.C -- Fahrenheit - Celsius átszámítás */ #include <stdio.h> void main(void){ printf("\nFahrenheit - Celsius átszámítás\n\n"); printf("%f Fahrenheit - %f Celsius\n", 0., (5.0/9.0)*(0.-32.0)); printf("%f Fahrenheit - %f Celsius\n", 20., (5.0/9.0)*(20.-32.0)); printf("%f Fahrenheit - %f Celsius\n", 40., (5.0/9.0)*(40.-32.0)); printf("%f Fahrenheit - %f Celsius\n", 60., (5.0/9.0)*(60.-32.0)); printf("%f Fahrenheit - %f Celsius\n", 80., (5.0/9.0)*(80.-32.0)); printf("%f Fahrenheit - %f Celsius\n", 100., (5.0/9.0)*(100.-32.0)); printf("%f Fahrenheit - %f Celsius\n", 120., (5.0/9.0)*(120.-32.0)); printf("%f Fahrenheit - %f Celsius\n", 140., (5.0/9.0)*(140.-32.0)); printf("%f Fahrenheit - %f Celsius\n", 160., (5.0/9.0)*(160.-32.0)); printf("%f Fahrenheit - %f Celsius\n", 180., (5.0/9.0)*(180.-32.0)); printf("%f Fahrenheit - %f Celsius\n", 200., (5.0/9.0)*(200.-32.0)); printf("%f Fahrenheit - %f Celsius\n", 220., (5.0/9.0)*(220.-32.0)); printf("%f Fahrenheit - %f Celsius\n", 240., (5.0/9.0)*(240.-32.0)); printf("%f Fahrenheit - %f Celsius\n", 260., (5.0/9.0)*(260.-32.0)); printf("%f Fahrenheit - %f Celsius\n", 280., (5.0/9.0)*(280.-32.0)); printf("%f Fahrenheit - %f Celsius\n", 300., (5.0/9.0)*(300.-32.0)); } Hatwágner F. Miklós
Alapismeretek
Fahrenheit - Celsius átváltás pelda1.c, 5. sor
printf("%f Fahrenheit - %f Celsius\n", 0., (5.0/9.0)*(0.-32.0));
printf
els®, karakterlánc paraméterét
karakterek és
formátumspecikációk alkotják. Utóbbi % karakterrel indul, és
típuskarakterrel zárul. printf további akt.
A formátumspecikációk és
paraméterei
összetartoznak (sorrend, mennyiség).
%<szélesség><.pontosság>típuskarakter Típuskarakter
Paraméter típusa
Megjelenítés
d
egész típus
decimális egészként
f
lebeg®pontos
tizedes tört alak
c
egy karakter
karakterként
s
karakterlánc
karakterláncként
Hatwágner F. Miklós
Alapismeretek
Fahrenheit - Celsius átváltás
pelda1.c, kimenet
Fahrenheit - Celsius átszámítás 0.000000 Fahrenheit - -17.777778 Celsius 20.000000 Fahrenheit - -6.666667 Celsius 40.000000 Fahrenheit - 4.444444 Celsius 60.000000 Fahrenheit - 15.555556 Celsius 80.000000 Fahrenheit - 26.666667 Celsius 100.000000 Fahrenheit - 37.777778 Celsius 120.000000 Fahrenheit - 48.888889 Celsius 140.000000 Fahrenheit - 60.000000 Celsius 160.000000 Fahrenheit - 71.111111 Celsius 180.000000 Fahrenheit - 82.222222 Celsius 200.000000 Fahrenheit - 93.333333 Celsius 220.000000 Fahrenheit - 104.444444 Celsius 240.000000 Fahrenheit - 115.555556 Celsius 260.000000 Fahrenheit - 126.666667 Celsius 280.000000 Fahrenheit - 137.777778 Celsius 300.000000 Fahrenheit - 148.888889 Celsius _
Hatwágner F. Miklós
Alapismeretek
Fahrenheit - Celsius átváltás
Problémák: rengeteg feleslegesen ismétl®d® kódrészlet sok hibalehet®ség nehézkes karbantarthatóság, stb.
→
módosítunk!
Adatszerkezet: Funkció
Azonosító
Típus
Jelleg
tartomány alsó határa
also
egész
munka
tartomány fels® határa
felso
egész
munka
lépésköz
lepes
egész
munka
aktuális Fahrenheit érték
fahr
valós
munka, output
aktuális Celsius érték
celsius
valós
munka, output
Hatwágner F. Miklós
Alapismeretek
Fahrenheit - Celsius átváltás Algoritmus: változók deklarálása, kezd®értékadások fejlécsor megjelentetése ciklusmag ismétlése, amíg
fahr <= felso
ciklusmagban: számolás, értékpár kijelzése,
fahr
léptetése
pelda2.c
/* PELDA2.C -- Fahrenheit - Celsius átszámítás */ #include <stdio.h> void main(void) { int also, felso, lepes; float fahr, celsius; printf("\nFahrenheit - Celsius átszámítás\n\n"); printf("Fahrenheit - Celsius\n"); printf("--------------------\n"); also = 0; felso = 300; lepes = 20; fahr =also; while(fahr<=felso) { celsius = (5.0/9.0)*(fahr-32.0); printf("%10.0f%10.1f\n", fahr, celsius); fahr = fahr+lepes; } } Hatwágner F. Miklós
Alapismeretek
Fahrenheit - Celsius átváltás
Blokkszerkezet el®ször deklarációs utasítások, majd végrehajtható utasítások (nem keveredhetnek) minden változót deklarálni kell Deklarációs utasítás
típus azonosítólista; azonosítólista: vessz®vel elválasztott azonosítók Típusok
int el®jeles, xpontos bels® ábrázolású egész float 4 bájtos, lebeg®pontos bels® ábrázolású
valós
(mantissza el®jelével 3 bájt + karakterisztika el®jelével 1 bájt, ábrázolási határok:
±3, 4 · 10−38
±3, 4 · 10+38 ,
jegy pontosság)
Hatwágner F. Miklós
Alapismeretek
6-7 decimális
Fahrenheit - Celsius átváltás
Hozzárendelés pelda2.c, 12. sor
celsius=(5.0/9.0)*(fahr-32.0); objektum = kifejezés
módosítható balérték: értéket felvenni képes objektum jobbérték: meghatározható érték¶ kifejezés esetleges implicit típusmódosítás Elöltesztel® ciklus pelda2.c, 11. sor
while(fahr<=felso) { while(kifejezés) utasítás
aritmetikai: igaz (1) esetén ismétli az a ciklust követ® utasításra lép utasítás több utasításból is állhat → { és } kifejezés-nek változnia kell → végtelen ciklus kifejezés
Hatwágner F. Miklós
utasítást,
Alapismeretek
hamis (0) esetén
Fahrenheit - Celsius átváltás Explicit típusmódosítás
(típus)kifejezés pelda2.c, kimenet
Fahrenheit - Celsius átszámítás Fahrenheit - Celsius -------------------0 -17.8 20 -6.7 40 4.4 60 15.6 80 26.7 100 37.8 120 48.9 140 60.0 160 71.1 180 82.2 200 93.3 ... ... 300 148.9 _ Hatwágner F. Miklós
Alapismeretek
Fahrenheit - Celsius átváltás
Probléma túl sok változó (nem is változik az értékük!)
→
pelda3.c
/* PELDA3.C -- Fahrenheit - Celsius átszámítás */ #include <stdio.h> void main(void) { int fahr; printf("\nFahrenheit - Celsius átszámítás\n\n"); printf("Fahrenheit - Celsius\n"); printf("--------------------\n"); for(fahr=0; fahr<=300; fahr=fahr+20) printf("%10d%10.1f\n", fahr, (5.0/9.0)*(fahr-32)); }
Hatwágner F. Miklós
Alapismeretek
módosítunk!
Fahrenheit - Celsius átváltás
Elöltesztel®, iteratív ciklusutasítás
for(
; ; ) utasítás
végrehajtása, ha megadták végrehajtása, ha kifejezés igaz; lehet összetett léptet®-kifejezés végrehajtása, ha megadták, majd ugrás a 2. pontra
1
init-kifejezés
2
utasítás
3
while átalakítható for ciklusra: ; while(kifejezés) {utasítás; } printf paramétere kifejezés is lehet Probléma: konstansok szétszórva a programban módosítások, rengeteg hibalehet®ség
Hatwágner F. Miklós
→
→
nehézkes, lassú
módosítunk!
Alapismeretek
Fahrenheit - Celsius átváltás Szimbolikus állandók (egyszer¶ makrók) egyszer kell deniálni, majd a megfelel® helyeken használni ®ket könny¶ a változásokat átvezetni
#dene azonosító helyettesít®-szöveg pelda4.c
/* PELDA4.C -- Fahrenheit - Celsius átszámítás */ #define ALSO 0 #define FELSO 300 #define LEPES 20 #include <stdio.h> void main(void) { int fahr; printf("\nFahrenheit - Celsius átszámítás\n\n"); printf("Fahrenheit - Celsius\n"); printf("--------------------\n"); for(fahr=ALSO; fahr<=FELSO; fahr=fahr+LEPES) printf("%10d%10.1f\n", fahr, (5.0/9.0)*(fahr-32)); } Hatwágner F. Miklós
Alapismeretek
Fahrenheit - Celsius átváltás
Szokás a #define direktívákat külön fejfájlba helyezni, majd arra hivatkozni A fájlnév most idéz®jelek között áll! beginend.h /* BEGINEND.H -- saját #define ALSO 0 #define FELSO 300 #define LEPES 20 #define begin { #define end } #define LACI for #include <stdio.h>
fejfájl */ /* Alsó hatar. */ /* Fels® határ. */ /* Lépésköz. */
pelda4m.c /* PELDA4M.C -- Fahrenheit - Celsius átszámítás */ #include "beginend.h" int main(void) begin int fahr; printf("\nFahrenheit - Celsius átszámítás\n\n"); printf("Fahrenheit - Celsius\n"); printf("--------------------\n"); LACI(fahr=ALSO; fahr<=FELSO; fahr=fahr+LEPES) begin printf("%10d%10.1f\n",fahr,(5.0/9.0)*(fahr-32)); end end
Hatwágner F. Miklós
Alapismeretek
Be- és kimenet
Szabványos be- és kimenet legtöbb operációs rendszer támogatja stdin (standard input): alapértelmezetten a billenty¶zet stdout (standard output) alapértelmezetten a képerny® felhasználó átirányíthatja ezeket (pl. nyomtatóra, fájlba, . . . ) Egy karakter olvasása szabvány bemenetr®l int getchar(void); balról nulla érték¶ bitekkel feltölti, int-re alakítva adja vissza hiba esetén, vagy a fájl végén EOF értéket szolgáltat. fájl vége billenty¶zeten? Pl. Ctrl+Z stdio.h részlet #dene EOF (-1)
Függvény prototípusa megadja a visszatérési érték típusát a függvény nevét paramétereinek számát, sorrendjét, típusát azaz teljes formai információval szolgál a függvényr®l Hatwágner F. Miklós
Alapismeretek
Be- és kimenet Egy karakter írása a szabvány kimenetre
int putchar(int k); visszatérési érték sikeres esetben
k,
hiba esetén ett®l eltér®
érték Készítsünk programot, ami a fájl végéig átmásolja a szabvány bemenetr®l érkez® jeleket a kimenetre! pelda5.c
/* PELDA5.C -- Bemenet átmásolása a kimenetre */ #include <stdio.h> void main(void) { int c; printf("\nBemenet másolása a kimenetre:\n\n"); printf("Gépeljen Ctrl+Z -ig sorokat!\n\n"); c=getchar(); while(c!=EOF) { putchar(c); c=getchar(); } } Hatwágner F. Miklós
Alapismeretek
Be- és kimenet
A
getchar
az OS billenty¶zet pueréb®l olvas; ENTER leütéséig
nem fér hozzá a begépelt karakterekhez! Készítsünk programot, ami megszámolja a szabvány bemenetr®l érkez® jeleket!
pelda6.c
/* PELDA6.C -- Karakterszámlálás */ #include <stdio.h> void main(void) { long nc; nc = 0l; printf("A bemenet karaktereinek leszámlálása:\n\n"); printf("Gépeljen Ctrl+Z-ig!\n\n"); while(getchar()!=EOF) ++nc; printf("A bemenet karaktereinek száma %ld volt.\n", nc); }
Hatwágner F. Miklós
Alapismeretek
Be- és kimenet Adattípus deklaráció, pontosítva pelda6.c, 4. sor
long nc;
azonosítólista; el®jel kezelése: signed (aé.) / unsigned hosszmódosítók: short / long még az alaptípus is elhagyható (aé. int), de az alaptípus típusmódosítók egyszerre nem hagyhatók el! short
≤
int
≤
long
pelda6.c, 5. sor
nc = 0l; az l a
long,
az u pedig az
unsigned
Hatwágner F. Miklós
utótag
Alapismeretek
és a
Be- és kimenet Növelés, csökkentés pelda6.c, 8. sor
while(getchar()!=EOF) ++nc; növelés, inkrementálás (increment): ++ csökkentés, dekrementálás (decrement): unáris
→
−−
nagyon magas prioritású
el®tag (prex) / utótag (postx) operátor változatok Az el®tag/utótag operátorok hatása az eredményre int a, b; b = 6; a = ++b; /* a==7 és b==7 */ a = b++; /* a==7 és b==8 */
pelda6.c, 9. sor
printf("A bemenet karaktereinek száma %ld volt.\n", nc); Hosszmódosítók: h
→
short, l
Hatwágner F. Miklós
→
long
Alapismeretek
Be- és kimenet Feladat: sorok összeszámolása a bemeneten pelda7.c
/* PELDA7.C -- Sorszámlálás */ #include <stdio.h> void main(void) { int c, nl; nl = 0; printf("A bemenet sorainak leszámlálása:\n\n"); printf("Gépeljen Ctrl+Z -ig!\n\n"); while((c=getchar()) != EOF) if(c == '\n') ++nl; printf("\nA bemeneten %d sor volt.\n", nl); } Vö. pelda5.c
↔
pelda7.c megoldását!
c = getchar(); while(c != EOF) { if(c == '\n') ++nl; c = getchar(); } Hatwágner F. Miklós
Alapismeretek
Be- és kimenet Ciklusszervezés összetett kifejezés felhasználásával gyelni kell a m¶veletek prioritására! mi történne zárójelezés nélkül? Operátor
Asszociativitás
() [] -> . ! ~ ++
−−
balról jobbra + - * & (típus) sizeof
jobbról balra
* / %
balról jobbra
+ -
balról jobbra
<< >>
balról jobbra
< <= > >=
balról jobbra
== !=
balról jobbra
&
balról jobbra
^
balról jobbra
|
balról jobbra
&&
balról jobbra
||
balról jobbra
?:
jobbról balra
= += -= *= /= %= &= ^= |= <<= >>=
jobbról balra
,
balról jobbra
Hatwágner F. Miklós
Alapismeretek
Be- és kimenet
Kétirányú szelekció pelda7.c, 9. sor
if(c == '\n') ++nl;
if(kifejezés) utasítás1 <else utasítás2> az utasítások lehetnek összetettek, vagy akár újabb szelekciós utasítások
Hatwágner F. Miklós
→
többágú szelekció
Alapismeretek
Be- és kimenet Feladat: bemenetr®l érkez® karakterek, szavak és sorok összeszámolása Adatszerkezet vegyünk fel egészeket a karakterek (nc), szavak (nw) és sorok (nl) számlálásához szükség lesz egy egészre a következ® jel olvasásához (c) és egy állapotjelz®re (szó belsejében járunk-e, inword) Algoritmus számlálókat nullázzuk le, szón kívül állunk tájékoztató üzenetek megjelenítése karakterek olvasása ciklussal EOF-ig, közben
nc növelése, nl növelése, ha az utolsó karakter újsor volt, szóhatár észlelése fehér karakterek gyelésével; szó belsejébe lépve nw növelése végül az eredmények kijelzése
Hatwágner F. Miklós
Alapismeretek
Be- és kimenet pelda8.c
/* PELDA8.C -- A bemenet sorainak,szavainak,karaktereinek számlálása */ #include <stdio.h> #define YES 1 #define NO 0 void main(void) { int c, nl, nw, nc, inword; inword = NO; printf("A bemenet karaktereinek,\n"); printf(" sorainak és\n"); printf(" szavainak leszámlálása:\n"); printf("A bemenet vége: Ctrl+Z vagy EOF.\n\n"); nl = nc = nw = 0; while((c=getchar()) != EOF) { ++nc; if(c == '\n') ++nl; if(c==' ' || c=='\n' || c=='\t') inword=NO; else if(inword == NO) { inword=YES; ++nw; }} printf("sor=%d szo=%d karakter=%d\n", nl, nw, nc); } Hatwágner F. Miklós
Alapismeretek
Be- és kimenet
Többszörös hozzárendelés pelda8.c, 12. sor
nl = nc = nw = 0; fontos, hogy nl, nc és nw mind balértékek asszociativitás gyorsabb m¶ködés, tömörebb forrásszöveg
Hatwágner F. Miklós
Alapismeretek
Tömbök
Feladat: készítsünk programot, mely a szabvány bemenetr®l olvas karaktereket EOF-ig, s közben megszámolja, hogy az egyes számjegy karakterekb®l, fehér karakterekb®l és minden más karakterb®l hány darab érkezett! Algoritmus Deklaráljuk az egyszer¶ változókat és a tömböt! A számlálók (beleértve a tömböt is) nullázandók! Jelenítsünk meg tájékoztató üzenetet! M¶ködtessünk ciklust, amíg EOF nem érkezik a bemenetr®l! Ciklusmagban:
Háromágú szelekcióval ki kell választani a megfelel® kategóriát, majd a neki megfelel® számlálót meg kell növelni! Megjelenítend®k a számlálók értékei!
Hatwágner F. Miklós
Alapismeretek
Tömbök pelda9.c
/* PELDA9.C -- Számjegyek, üres és egyéb karakterek leszámlálása */ #include <stdio.h> void main(void) { int c; /* bemeneti karakter */ int i; /* számláló */ int nwhite; /* üres karakterek */ int nother; /* egyéb karakterek */ int ndigit[10]; /* szám karakterek */ printf("Számjegyek, üres- és egyeb karakterek leszámlálása\n"); printf("a bemeneten EOF-ig vagy Ctrl+Z-ig.\n\n"); nwhite = nother = 0; for(i=0; i<10; ++i) ndigit[i] = 0; while((c=getchar()) != EOF) if(c>='0' && c<='9') ++ndigit[c-'0']; else if(c==' ' || c=='\n' || c=='\t') ++nwhite; else ++nother; printf("Számjegyek\n\n"); for(i=0; i<10; ++i) printf("%d = %d\n", i, ndigit[i]); printf("\n\nÜres karakterek = %d\nEgyéb karakterek= %d\n", nwhite, nother); } Hatwágner F. Miklós
Alapismeretek
Tömbök Tömb deníció pelda9.c, 8. sor
int ndigit[10]; /* szám karakterek */
típus tömbazonosító[méret]; méret pozitív, egész érték¶ állandó kifejezés állandó kifejezés értéke fordítási id®ben kiszámítható Tömb helyfoglalása
sizeof(tömbazonosító) ≡ méret*sizeof(típus) sizeof megadja a típus vagy objektum bájtokban Tömbelemek (indexes változó) elérése
tömbazonosító[index] 0 ≤ index ≤ meret − 1 Hatwágner F. Miklós
Alapismeretek
mért méretét
Tömbök
pelda9.c, 12. sor
for(i=0; i<10; ++i) ndigit[i] = 0; Az i számjegyek számát ndigit[i] tárolja! (Azaz pl. 0-ból ndigit[0], 1-b®l ndigit[1], sít. érkezett.) pelda9.c, 14. sor
if(c>='0' && c<='9') ++ndigit[c-'0']; A számjegy karakterek kódjai folytonosan követik egymást a kódtáblában c-'0' a két kód különbségét
Hatwágner F. Miklós
→
a megfelel® indexet adja!
Alapismeretek
Függvények El®re megírtak könyvtárakban (.lib) vagy tárgymodulokban (.obj), pl. printf, getchar,. . . Mi készítjük el! Feladat: jelezzük ki 2 els® 10 hatványát! pelda10.c
/* PELDA10.C -- Hatványozó függvény tesztelése */ #include <stdio.h> #define MEDDIG 10 int power(int x, int n); void main(void) { int i; printf("Kett® hatványai:\n\n"); for(i=0; i<MEDDIG; ++i) printf("2**%d = %d\n", i, power(2, i)); } int power(int x, int n) { /* x n-edik hatványa, ha n>0, különben 1 */ int i, p; p = 1; for(i=1; i<=n; ++i) p=p*x; return(p); } Hatwágner F. Miklós
Alapismeretek
Függvények
Denícióból csak egy létezhet, összhangban a deklarációkkal, prototípusokkal Prototípus el®zze meg a hívást! Hogyan konvertáljuk a paraméterek típusát? Paraméterátadás érték szerint A fv. nem
int-et
ad vissza? Legalább deklarálni kell!
Függvény deklaráció / prototípus / deníció elhelyezése Fv. deníciók nem ágyazhatók egymásba Visszatérési érték:
return ;
Vt. érték típusa: tömb és függvény nem lehet, aé. Implicit típuskonverzió, ha szükséges
return
el®fordulásai
Kilépés függvényb®l:
return
Hatwágner F. Miklós
vagy } elérésekor
Alapismeretek
int
Prodzsekt
Forrásfájlok témánkénti, funkciónkénti csoportosítása main egy és pontosan egy forrásban szerepelhet! Prodzsektfájl készítés fuggv.c
/* FUGGV.C - A power függvény. */ int power(int x, int n) { /* x n-edik hatványa, ha n>0, különben 1 */ int i, p; p = 1; for(i=1; i<=n; ++i) p=p*x; return(p); } foprog.c
/* FOPROG.C -- Hatványozó függvény tesztelése */ #include <stdio.h> #define MEDDIG 10 int power(int x, int n); void main(void) { int i; printf("Kett® hatványai:\n\n"); for(i=0; i<MEDDIG; ++i) printf("2**%d = %d\n", i, power(2,i)); } Hatwágner F. Miklós
Alapismeretek
Prodzsekt foprog.c fuggv.c foprog.obj fuggv.obj indító program (obj) könyvtárak (lib)
foprog.obj fuggv.obj
fordítás
kapcsolószerkesztés
Fájlok közötti implicit függ®ség
→
prodzsekt.exe
újrafordítás szükség esetén
Kezelése: automatikusan vagy explicit megadással
stdio.h
foprog.c fuggv.c
foprog.obj fuggv.obj indító prg. könyvtárak
Hatwágner F. Miklós
Alapismeretek
prodzsekt.exe
Karakterláncok
char tömbazonosító[méret]; Mérete: méret*sizeof(char) ≡ méret Indexelés: [0; méret-1] Karakter konstans bels® ábrázolása: int Van értelme? nev1 == nev2, nev1
...
nev 'G'
'i'
'z'
'i'
'k'
'e' '\0'
0
1
2
3
4
5
6
Feladat:
Készítsen programot, amely neveket olvas a szabvány bemenetr®l EOF-ig vagy üres sorig! Megállapítandó és kijelezend® a leghosszabb név! Probléma:
Szöveg beolvasása Szöveg tárolása
Hatwágner F. Miklós
Alapismeretek
Karakterláncok
getline()
int getline(char s[], int lim) { /* Max. lim méret¶ karakterlánc beolvasása s-be. A függvény a karakterlánc hosszát adja vissza. s tömbnek lim+1 méret¶nek kell lennie. */ int c, i; for(i=0; i
karakterek (EOF is!) csak Enter leütés után olvasható ki mi történik, ha lim-nél több karaktert gépeltek be?
Hatwágner F. Miklós
Alapismeretek
Karakterláncok
getline()
int getline(char s[], int lim) { /* Max. lim méret¶ karakterlánc beolvasása s-be. A függvény a karakterlánc hosszát adja vissza. s tömbnek lim+1 méret¶nek kell lennie. */ int c, i; for(i=0; i
karakterek (EOF is!) csak Enter leütés után olvasható ki mi történik, ha lim-nél több karaktert gépeltek be? getline() puer ürítés
while(c!=EOF && c!='\n') c=getchar(); Hatwágner F. Miklós
Alapismeretek
Karakterláncok
copy()
void copy(char s1[], char s2[]) { /* s1 masolása s2-be. s2-t elég nagynak tételezi fel. */ int i; i = 0; while((s2[i]=s1[i]) != '\0') ++i; } string.h strcpy() stdio.h getline()
POSIX.1-2008
Hatwágner F. Miklós
Alapismeretek
Karakterláncok pelda11.c
/* PELDA11.C -- A leghosszabb szövegsor kiválasztása */ #include <stdio.h> #define MAXLINE 1000 int getline(char s[],int lim); void copy(char s1[], char s2[]); void main(void) { int len; /* Az aktuális sor hossza */ int max; /* Az aktuális max. sor hossza */ char line[MAXLINE+1]; /* Az aktuális sor */ char save[MAXLINE+1]; /* Az aktuális max. sor */ printf("A leghosszabb szövegsor kiválasztása\n"); printf("A sorokat zárja le Enter-rel!\n"); printf("Utoljára adjon meg egy üres sort vagy Ctrl+Z-t!\n\n"); max = 0; while((len=getline(line, MAXLINE)) > 0) if (len>max) { max=len; copy(line, save); } printf("A leghosszabb sor:\n"); if(max > 0) printf("\n%s\n", save); } /* Volt sor */ int getline(char s[],int lim) { ... } void copy(char s1[], char s2[]) { ... } Hatwágner F. Miklós
Alapismeretek
Változók tulajdonságai
Alapfogalmak
Hatáskör/érvényességi tartomány Az a programterület, ahol hivatkozható, elérhet®. Élettartam Az az id®szak, amíg memóriát foglal. Változó deníciója Olyan deklaráció, melynek során memóriafoglalás is történik. Tárolási osztály Meghatározza, hogy az objektum
1
hol jön létre a memóriában (regiszter / statikus / dinamikus terület)
2
deniálja az objektum élettartamát
Hatwágner F. Miklós
Alapismeretek
Változók tulajdonságai
Lokális (bels®) változók
Pl.
i
a
copy(), getline()
fv.-ekben
Hatásköre: a blokk, amiben deniálták (és annak blokkjai; lokális hatáskör) Élettartama: amíg saját blokkjában van a vezérlés (lokális élettartam) Memóriaterület: futásid®ben foglalt, rendszerint a veremben Alapértelmezett (implicit) kezd®érték: nincs Alapértelmezett tárolási osztály: auto Függvények formális paraméterei lokális változók.
Hatwágner F. Miklós
Alapismeretek
Változók tulajdonságai
Változó deklarációja, pontosítva
azonosítólista; Tárolási osztályok:
auto register static extern Pl.
auto i; ≡ auto signed int i;
Hatwágner F. Miklós
Alapismeretek
Változók tulajdonságai
További alapfogalmak
Fordítási egység El®feldolgozott forrásmodul. Részei: függvénydeníciók küls® deklarációk Küls® deklaráció Minden fv. testén kívüli deklaráció
Hatwágner F. Miklós
→
Alapismeretek
küls®/globális változó
Változók tulajdonságai Globális (küls®) változók Hatásköre: fordítási egységben a deklarációtól a modul végéig (fájl/globális hatáskör) Élettartam: teljes futásid® (statikus élettartam) Memóriaterület: fordítási id®ben, els®dleges adatterületen Alapértelmezett kezd®érték: minden bit zérus Alapértelmezett tárolási osztály: extern extern explicit használata
→
nincs memóriafoglalás!
Azonos nev¶ lokális változó elfedi modul1.c
modul2.c
extern int i;
int i;
extern char s[];
char s[64];
/* ... */
/* ... */
Hatwágner F. Miklós
Alapismeretek
Változók tulajdonságai
pelda12.c, els® rész
/* PELDA12.C -- A leghosszabb szövegsor kiválasztása */ #include <stdio.h> #define MAXLINE 1000 /* A beolvasott sor max. hossza */ char line[MAXLINE+1]; /* Az aktuális sor */ char save[MAXLINE+1]; /* Az aktuális max. sor */ int max; /* Az aktuális max. sor hossza */ int getline(void); void copy(void); void main(void) { int len; /* Az aktuális sor hossza */ printf("A leghosszabb szövegsor kiválasztása\n"); printf("A sorokat zárja le Enter-rel!\n"); printf("Utoljára adjon meg egy üres sort vagy Ctrl+Z-t!\n\n"); max = 0; while((len=getline()) > 0) if (len>max) { max=len; copy(); } printf("A leghosszabb sor:\n"); if(max > 0) printf("\n%s\n",save); } /* Volt sor */ Hatwágner F. Miklós
Alapismeretek
Változók tulajdonságai
pelda12.c, második rész
int getline(void) { /* MAXLINE méret¶ karakterlánc beolvasása line-be. A függvény a karakterlánc hosszát adja vissza. line tömbnek MAXLINE+1 méret¶nek kell lennie. */ int c, i; for(i=0; i<MAXLINE && (c=getchar())!=EOF && c!='\n'; ++i) line[i]=c; line[i] = '\0'; return(i); } void copy(void) { /* line másolása save-be. save-t elég nagynak tételezi fel */ int i; i = 0; while((save[i]=line[i]) != '\0') ++i; } Hatwágner F. Miklós
Alapismeretek
Változók tulajdonságai
Globális változók használata
+
fv. paraméter átadása megtakarítható
−
nehezen újrahasznosítható fv.-ek: küls® változókat is vinni kell
→
lehetséges névegyezések
↔
csak lokális változók és fv.
paraméterek esetén nincs ilyen gond
−
nehezebben áttekinthet®, karbantartható program
Hatwágner F. Miklós
Alapismeretek
Inicializálás Kezd®értékadás deklarációban. Statikus élettartam: program indulásakor, konstans kifejezéssel Lokális élettartam: minden létrejövetelkor, bármilyen legális kifejezéssel
típus azonosító<=inicializátor>; típus tömbazonosító[<méret>]<=inicializátorlista>;, ahol típus ≡ Az inicializátor egy hozzárendelés-kifejezés (→ típusok, konverziók) Tömböknél:
inicializátorlista elemszáma ≤ tömb elemszáma Ha inicializátorlista elemszáma < tömb elemszáma → elemek nullázódnak
<méret>-et nem specikálták, inicializátorlista elemszámából
Ha
Hatwágner F. Miklós
megállapítják
Alapismeretek
további
Inicializálás
Deníció, hozzárendelés char k, j; k = 'b'; int i; i = 42; float ftomb[3]; ftomb[0] = 1.; ftomb[1] = 2.; ftomb[2] = 3.; int itomb[3]; itomb[0] = itomb[1] = itomb[2] = 0; char ctomb[4]; ctomb[0] = 'Z'; ctomb[1] = 's'; ctomb[2] = 'u'; ctomb[3] = '\0';
Hatwágner F. Miklós
Inicializálás char k='b', j;
int i = 42; float ftomb[3] = {1., 2., 3.}; int itomb[3] = {0}; char ctomb[4] = {'Z', 's', 'u', '\0'} char ctomb2[] = "Zsu";
Alapismeretek