Mivel nov. 20-án csütörtökön 13:00-tól TDK miatt dékáni szünet van, a 8. mini zh-t a csütörtök délutáni csoportok nem tudnák megírni. Ezért a 6. és 7. zh 10 helyett 15 pontos és 30 helyett 45 perces lesz. Az eredetileg tervezett 8. mini zh órája zh nélkül lesz megtartva.
Ismétlő feladatsort nem állítottam össze. A lényeg, hogy egyszerű típusdefiniálást tudni kell létrehozni, tudni kell használni az enum-felsorolás típust, és jól kell ismerni az egyes típusok méretét és előjeles/előjeltelen formájuk alsó és felső korlátait.
Figyeljük meg, hogy az alábbi programban, nem simán változó értékeket adunk át, hanem memória címeket ( & ). Függvényhíváskor pedig ezekre a memória címekre mutató pointereket ( * ) használunk a változók tényleges értékeinek felülírásához.
F: Számítsd ki egy háromszög területét és kerületét a három oldalhossz segítségével. A számolást egyetlen függvény végezze. ============================================================================== #include <stdio.h> #include <math.h> void haromszogTKpar(double a, double b, double c, double *t, double *k){ double s; *k = (a + b + c); s = (*k) / 2.0; *t = sqrt((s-a)*(s-b)*(s-c)*s); } int main() { double a, b, c, t, k; printf("Adja meg az oldalakat!?:\n"); scanf("%lf %lf %lf", &a, &b, &c); haromszogTKpar(a, b, c, &t, &k); printf("T: %lf; K: %lf;\n", t, k); return 0; } ============================================================================== Nézzük meg mi történik, ha nem pointereket használunk.
F: Másodfokú egyenlet megoldása ============================================================================== #include <stdio.h> #include <math.h> int megoldo(double a, double b, double c, /* együtthatók */ double *x1, double *x2) /* gyökök */ { double d; /* a diszkrimináns */ int valos; /* van-e megoldás */ valos = 1; if (a == 0.0) { if (b == 0.0) { /* az egyenlet elfajuló */ valos = 0; } else { /* 1. fokú */ *x1 = -(c / b); *x2 = *x1; } } else { d = b * b - 4.0 * a * c; if (d < 0.0) { /* nincs valós gyöke */ valos = 0; } else { *x1 = (-b + sqrt(d)) / (2.0 * a); *x2 = (-b - sqrt(d)) / (2.0 * a); } } return valos; } int main() { double a, b, c, x1, x2; printf("Adja meg az egyutthatokat!\n?:"); scanf("%lf", &a); scanf("%lf", &b); scanf("%lf", &c); if(megoldo(a, b, c, &x1, &x2)) printf("Az egyenlet megoldasai: %lf, %lf\n", x1, x2); else printf("Az egyenletnek nincs valos megoldasa.\n"); return 0; }
Rekurzió: Rekurziónak nevezzük, amikor egy függvény önmagát hívja, egy bizonyos feltétel teljesüléséig. Sokkal elegánsabb megoldást kapunk és csökkenti a redundanciát a kódunkban. Használata akkor ajánlott, ha egy bizonyos függvény hívását egymás után többször végre kell hajtani. Azonban a számítási idő és a memóriaigény jelentős növekedése miatt az esetek többségében mégis az iteratív megoldás ajánlott.
F: Fibonacci-sorozat n. elemének kiszámítása rekurzív módszerrel ============================================================================= #include <stdio.h> int fib(int n) { if(n==1 || n==2) { return 1; } else { return fib(n-1) + fib(n-2); } } int main() { int n; printf("n erteke?: "); scanf("%d",&n); printf("A fibonacci sorozat %d. eleme: %d\n",n,fib(n)); return 0; } ============================================================================= Kérdés: Hányszor hívódik a függvény?
F: n faktoriális kiszámítása rekurzív módszerrel ============================================================================= #include <stdio.h> long factorial(int); int main() { int n; long f; printf("Enter an integer to find factorial\n"); scanf("%d", &n); if (n < 0) printf("Negative integers are not allowed.\n"); else { f = factorial(n); printf("%d! = %ld\n", n, f); } return 0; } long factorial(int n) { if (n == 0) return 1; else return(n * factorial(n-1)); }
Fontos, hogy mekkora méretű típusban mekkora/milyen értéket szeretnénk letárolni. Erre beolvasáskor és kiíratáskor is jelentős figyelmet kell fordítani.
sizeof operátor - típusok méretének meghatározása byte-okban. Pl.:
int i = sizeof(int); // ilyenkor az i változóba bele kerül az int típus mérete. ez a C esetén 4 byte
C típus méret(bájt) alsó határ felső határ _______________________________________________________ char 1 ? ? signed char 1 -128 127 unsigned char 1 0 255 short int 2 -32768 32767 unsigned short int 2 0 65535 int 4 -2147483648 2147483647 unsigned int 4 0 4294967295 long int 4 -2147483648 2147483647 unsigned long int 4 0 4294967295 long long 8 -263 263-1 float 4 -+3.4028234663852886E+38 double 8 -+1.7976931348623157E+308 long double 8 -+1.7976931348623157E+308
F: Írj egy programot, ami beolvas egy előjeltelen short int értéket, és nyolcas számrendszerbe átváltva írja ki. ============================================================================== #include <stdio.h> int main() { unsigned short int v; scanf("%hu", &v); printf("%ho\n", v); return 0; }
F: Írj egy programot, ami beolvas egy hexadecimális egész számot, majd 15 karakter szélességben kiírja a decimális értékét, mindenképpen előjellel és vezető nullákkal. ============================================================================== #include <stdio.h> int main() { unsigned int v; scanf("%x", &v); printf("%+015u\n", v); return 0; }
F: Olvass be egy double és egy egész értéket, majd a valós értéket írasd ki az egészben megadott pontossággal. ============================================================================== #include <stdio.h> int main() { double ertek; int pontossag; scanf("%lf %d", &ertek, &pontossag); printf("%1.*lf\n", pontossag, ertek); return 0; }
F: Olvass be egy csupa kisbetűből álló, legfeljebb 20 karakteres sztringet, majd írasd ki 10 karakteren jobbra igazítva az első legfeljebb 8 karakterét. A bemeneten a kisbetűket közvetlenül bármi követheti. ============================================================================== #include <stdio.h> int main() { char str[21]; scanf("%20[a-z]", str); printf("%10.8s\n", str); return 0; }
getchar : egy darab karaktert vár a standard bemeneten (egy billentyű lenyomás).
char c = getchar();
putchar : egy darab karaktert ír ki a képernyőre.
putchar(c);
F: Írasd ki a SPACE jelig (32) tartó bemenetet úgy, hogy a számjegyeket törlöd belőle. A végén írd ki, hogy hány számjegyet töröltél. ============================================================================== #include <stdio.h> int main() { int c, d=0; while((c=getchar())!=32) { if('0'<=c && c<='9') { d++; } else { putchar(c); } } printf("\n--\n%d torolve\n", d); return 0; }
A C nyelv szabványos könyvtára tartalmaz függvényeket karaktersorozatok (sztringek) egyetlen hívással történő beolvasására (gets) és kiírására (puts).
gets : A gets függvény egy sort (<Enter> lenyomásáig) olvas a szabványos inputról, majd a karaktereket az argumentumban megadott sptr mutató által kijelölt területre másolja:
char* gets(char *sptr);
puts : A puts függvény az argumentumban megadott sztringet a szabványos kimenetre (a képernyőre) írja. A függvény egy nem negatív szám visszaadásával jelzi a sztring sikeres kiíratását, ellenkező esetben pedig EOF (-1) értékkel tér vissza.
int puts(char *sptr);
F: Olvass be egy sztringet, majd írasd ki a képernyőre a gets és a puts parancsok használatával. ============================================================================== #include <stdio.h> int main() { char str[80]; puts("Sztring beolvasasa:"); gets(str); puts(str); return 0; }
F: Írj egy programot, ami beolvas két egész számot, majd kiírja az összegüket és a szorzatukat. ============================================================================== #include <stdio.h> int main() { int a, b; scanf("%d %d", &a, &b); printf("Osszeg: %d\nSzorzat: %d\n", a + b, a * b); return 0; }
F: Módosítsuk úgy a programot, hogy használja az stdin, stdout, fscanf és fprintf függvényeket. ============================================================================== #include <stdio.h> int main() { int a, b; fscanf(stdin, "%d %d", &a, &b); fprintf(stdout, "Osszeg: %d\nSzorzat: %d\n", a + b, a * b); return 0; } /* látható, hogyha elhagynánk az fscanf és az fprintf elejéről az f betűket, valamint a zárójelekből az stdin és stdout függvényeket, az előző feladattal ekvivalens megvalósítást kapnánk */
A fájlok adatfolyamként történő kezelése során egy FILE * típusú ún. filemutató azonosítja az állományt. (Ezt az állományt az STDIO.H file deklarálja.)
FILE *nev;
Ahhoz, hogy a háttértáron levő file tartalmához hozzáférjünk, a file-t meg kell nyitnunk. A file megnyitását a fopen függvény hívásával végezhetjük el, melynek prototípusa:
FILE * fopen(const char * filename, const char *mode);
avagy meglévő FILE * esetén
FILE * vmi; vmi = fopen(const char * filename, const char *mode);
A filename helyére a beolvasandó file neve kerül, tehát egy sztring. (pl.: "be.txt")
A mode úgyszint egy sztring, amely a file elérését és típusát határozza meg. (pl.: "r")
A lehetséges elérési módok:
"r" - Létező file megnyitása olvasásra. "w" - Új file megnyitása írásra. Ha file már létezik, akkor a tartalma elvész. "a" - File megnyitása hozzáírásra. A nyitás után a file végén lesz az aktuális file-pozíció. Ha a file nem létezik, akkor az fopen létrehozza azt. "r+" - Létező file megnyitása írásra és olvasásra (update). "w+" - Új file megnyitása írásra és olvasásra (update). Ha a file már létezik, akkor a tartalma elvész. "a+" - File megnyitása a file végén végzett írásra és olvasásra (update). Ha a file nem létezik, akkor az fopen létrehozza azt.
Amikor többé nincs szükségünk a megnyitott file(ok)-ra, akkor kell használnunk az fclose hívást, amely lezárja a file-t.
F: Módosítsuk úgy az előző programot, hogy valódi fájlokat használjon. ============================================================================== #include <stdio.h> int main() { int a, b; FILE *infile; //beolvasáshoz FILE *outfile; //kiíratáshoz infile = fopen("be.txt", "r"); //bementi fájl olvas outfile = fopen("ki.txt", "w"); // fscanf(infile, "%d %d", &a, &b); fprintf(outfile, "Osszeg: %d\nSzorzat: %d\n", a + b, a * b); fclose(infile); fclose(outfile); return 0; }
A be.txt-nek léteznie kell, viszont a ki.txt-t a program létrehozza magától, amennyiben nem volt ellőállítva.
Ha a megadott állományt nem sikerült megnyitni, vagy ha a FILE struktúrának nem sikerült helyet foglalni a memóriában, NULL lesz a függvényérték.
F: Hibakóddal lépjen ki a program, ha valamelyik fájl megnyitása nem sikerült. ============================================================================== #include <stdio.h> int main() { int a, b; FILE *infile; FILE *outfile; if(!(infile = fopen("be.txt", "r"))) { return 1; } if(!(outfile = fopen("ki.txt", "w"))) { fclose(infile); return 1; } fscanf(infile, "%d %d", &a, &b); fprintf(outfile, "Osszeg: %d\nSzorzat: %d\n", a + b, a * b); fclose(infile); fclose(outfile); return 0; }
A házi feladatot megoldani nem kötelező és bemutatni sem kell, viszont a következő gyakorlaton visszakérhető (kikérdezés, táblához hívás, stb. formájában)! Ha a hallgató megoldása ötletes, szép kivitelezésű, plusz pont adható. Amennyiben viszont nem tudja megoldani gyakorlaton a házi feladatban szereplő példákat vagy nem tud válaszolni az azzal kapcsolatban feltett kérdésekre, mínusz pont adható. Plusz és mínusz pontból is egyaránt maximum 10 pontot gyűjthet össze egy-egy hallgató.
Házi feladat letöltése .
A gyakorlat témája:
Konzultációs óra. Nem lesz új anyag, sem katalógus. Viszont bátran be lehet jönni kérdezni, gyakorolni.
Vissza a lap tetejére.