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.