1 Dolgozat pontszáma
0…23 → 1 24…32 → 2 33…41 → 3 42…50 → 4 51…60 → 5
Írj programot, amely megkérdezi, hány pontot kapott valaki egy dolgozatra. Utána pedig kiírja az érdemjegyet (elégtelen, elégséges, közepes, jó, jeles) szavakkal a képernyőre! A pontozási táblázat oldalt látható.
Vigyázz: C-ben nem használhatsz 0≤x≤23
formájú
kifejezést a tartomány vizsgálatához!
Megoldás
Sokféle megoldás lehet, hiszen az egyes feltételek megfogalmazhatóak úgy is, hogy egymást kizárják. Az egyik lehetséges változat, amely képes az érvénytelen pontszámot is jelezni:
#include <stdio.h> int main() { int pont; printf("Hany pontos a dolgozat? "); scanf("%d", &pont); if (pont>=0 && pont<=23) printf("Elegtelen"); else if (pont>=24 && pont<=32) printf("Elegseges"); else if (pont>=33 && pont<=41) printf("Kozepes"); else if (pont>=42 && pont<=50) printf("Jo"); else if (pont>=51 && pont<=60) printf("Jeles"); else printf("Ervenytelen pontszam"); return 0; }
2 Beírt számok szorzata
Írj programot, amely valós számokat kér a felhasználótól egész addig, amíg 0-t nem kap! Írd ki a felhasználó által megadott számok szorzatát!
A feladatot meg lehet oldani úgy – és ez a szép megoldás –, hogy a beolvasott szám nulla, avagy nem nulla voltát csak egyetlen egy helyen kell ellenőrizni. Ha nem ilyen lett a programod, akkor próbáld meg átalakítani ilyenné. Másképp fogalmazva: csak egy ciklus kell,
if()
elágazás nem.
Megoldás
#include <stdio.h> int main() { double szam, szorzat; szorzat = 1; /* első */ printf("Szam vagy 0? "); scanf("%lf", &szam); while (szam!=0) { szorzat = szorzat*szam; /* többi */ printf("Szam vagy 0? "); scanf("%lf", &szam); } printf("Szorzatuk: %f\n", szorzat); return 0; }
3 Teve tuvudsz ívígy beveszévélnivi?
Olvass be karakterenként egy szöveget! Írd ki úgy, hogy minden magánhangzó után a program mondjon egy v-t is, és ismételje meg a magánhangzót. Pl. te→teve, ma→mava, labor→lavabovor. Elég csak az ékezet nélküli kisbetűkkel foglalkozni: a, e, i, o, u.
Az operációs rendszer csak akkor fogja odaadni a programodnak a begépelt karaktereket, amikor megnyomtad az Enter-t. Ezért a beírt szöveget nem kell eltárolnod, hanem mindig csak egyetlen karakterrel kell foglalkoznod! Tömb nem kell: a soronkénti, „kérdezz-felelek” működést biztosítja majd az operációs rendszer.
A bemenet végét a programnak az első laboron tanult módon tudod jelezni: az F6-tal vagy a Ctrl-Z billentyűkombinációval. A
scanf()
pedig képes érzékelni ezt. Ez visszaad egy számot, amely azt mutatja, hány dolgot sikerült beolvasnia. Jelen esetben egyetlen karakter beolvasására kérjük, ezért a visszaadott szám, ha sikerült beolvasni a karaktert, 1 lesz:if (scanf("%c", &betu)==1) printf("Sikerült beolvasni a karaktert: %c.\n", betu); else printf("Nem sikerült a beolvasás, a betu változó tartalma nem változott.\n");Ebből megépíthető az a ciklus. Egy végjeles sorozatról van szó, mint az előző feladatban. A karaktersorozat végét az jelzi, hogy a
scanf()
nem 1-et adott.
Megoldás
#include <stdio.h> int main() { char c; /* Karakter tárolásához */ while (scanf("%c", &c)==1) { printf("%c", c); /* Ha magánhangzó */ if (c=='a'||c=='e'||c=='i'||c=='o'||c=='u') printf("v%c", c); /* Írunk egy v-t és újból a karaktert */ } return 0; }
4 Négyzet (téglalap) rajzolása
****** ****** ****** * * ****** * * ****** * * ****** * * ****** ******
****** ** * * * * * * * * ** ******
Írj programot, amely bekér a felhasználótól egy pozitív egész számot, és kirajzol egy ekkora, * karakterekből álló, teljesen kitöltött négyzetet a képernyőre! A C nyelvű kód megírása előtt rajzolj struktogramot!
Keret. Oldd meg a feladatot úgy is, hogy csak a négyzet kerete álljon csillagokból, a belseje legyen üres! Erre két logikus megoldás is van: külön programrészben is megrajzolhatod a keretet, de csinálhatod azt is, hogy az n×n-es ciklus belsejében figyeled egy feltétellel, a négyzet belsejében vagy-e, vagy a kereten.
Átló. Alakítsd át a programot úgy, hogy a négyzet átlóját is behúzza! Az előző két átalakítási lehetőség közül ehhez melyiket érdemes választani? Hogyan lehetne ezt a programot megírni úgy, hogy ne használjon elágazásokat, csak ciklust? És hogyan úgy, hogy lényegében két egymásba ágyazott ciklust tartalmaz (y és benne x), amelyeken belül pedig tetszőleges kód lehet?
Tipp: több sor kijelölése után a TAB billentyűt megnyomva mindegyik sort beljebb (jobbra) viszi a szerkesztő egy szinttel. Ez hasznos, ha egy meglévő kódrészletet szeretnél ciklusba tenni. A Shift+TAB hatására ennek ellenkezője történik.
Megoldás
#include <stdio.h> int main() { int i,j; /* Ciklusváltozók */ int n; /* Négyzet nagysága */ printf("Mekkora legyen a negyzet? "); scanf("%d",&n); /* Beolvasás */ /* Teli négyzet */ for (i=0; i<n; i=i+1) { for (j=0; j<n; j=j+1) printf("*"); /* n db csillag */ printf("\n"); /* Új sor */ } printf("\n\n\n"); /* Pár üres sor */ /* Üres négyzet */ for (i=0; i<n; i=i+1) { for (j=0; j<n; j=j+1) { /* Széleken csillag */ if (i==0 || i==n-1 || j==0 || j==n-1) printf("*"); else printf(" "); /* Különben szóköz */ } printf("\n"); /* Új sor */ } printf("\n\n\n"); /* Pár üres sor */ /* Átlós négyzet */ for (i=0; i<n; i=i+1) { for (j=0; j<n; j=j+1) { /* Széleken és átlóban csillag */ if (i==0 || i==n-1 || j==0 || j==n-1 || i==j) printf("*"); else printf(" "); /* Különben szóköz */ } printf("\n"); /* Új sor */ } return 0; }
5 Prímek keresése
Írj programot, amelyik az osztók próbálgatásával (2≤osztó≤szám/2) meghatározza egy számról, hogy prím-e! Ne a számlálás, hanem a lineáris keresés tételét alkalmazd! Amint találsz egy osztót, álljon le a keresés!
Első n
darab prím.
Módosítsd úgy a programot, amely a szabványos kimenetre írja az első n
db prímet! n
értékét a program a felhasználótól kérje! A C kód elkészítése előtt rajzolj struktogramot!
Tipp: ciklus a ciklusban. A külső ciklus
n
-ig fut, a belső pedig ellenőrzi, hogy a vizsgált szám prím-e. Vigyázat: ez nem ugyanaz a feladat, mint az előadáson! Itt nem a2…n
tartományban lévő prímeket kell megkeresni, hanem az elsőn
darabot.
6 További feladatok
Rajzolás
-
+---+ |\ | | \ | | \| +---+
Alakítsd át az óra eleji négyzetrajzolós programot úgy, hogy vonalakból (+, |, -, \) egy ládát rajzoljon! Figyelj a visszaper karakter kirajzolására: azt"\\"
formában kell megadni. Hogyan lehetne ezt megírni a fent említett két egymásba ágyazott ciklussal és sok elágazással, illetve elágazások használata nélkül?Megoldás
#include <stdio.h> int main() { int meret; int x, y; /* Méret beolvasása */ printf("Mekkora legyen? "); scanf("%d", &meret); printf("lada atloval, csak 2 ciklus\n"); for (y=1; y<=meret; y+=1) { for (x=1; x<=meret; x+=1) /* Feltétel a 4 sarokpontra */ if ((x==1 && (y==1 || y==meret)) || (x==meret && (y==1 || y==meret))) printf("+"); else /* Feltétel a vízszintes oldalakra */ if (y==1 || y==meret) printf("-"); else /* Feltétel a függőleges oldalakra */ if (x==1 || x==meret) printf("|"); else /* Feltétel az átlóra */ if (x==y) printf("\\"); /* A backslash spec. jelentése miatt duplán kell írni */ else printf(" "); printf("\n"); } printf("lada atloval, sok ciklus, elagazasok nelkul\n"); /* Felső oldal és sarkok */ printf("+"); for (x=2; x<meret; x+=1) printf("-"); printf("+\n"); /* Függőleges oldalak és a láda belseje */ for (y=2; y<meret; y+=1) { printf("|"); /* Bal oldal */ /* Szóközök, átló, majd ismét szóközök */ for (x=2; x<y; x+=1) printf(" "); printf("\"); for (x=y+1; x<meret; x+=1) printf(" "); printf("|\n"); /* Jobb oldal és újsor */ } /* Alsó oldal és sarkok */ printf("+"); for (x=2; x<meret; x+=1) printf("-"); printf("+\n"); return 0; }
-
X X X X X X X X X X X X X X X X X X X
Rajzold ki programból a szinusz függvényt, 90 fokkal elforgatva és
X
-ekből kirakva! A mintát lásd a jobb oldalon. Ehhez amath.h
függvénye, asin()
használható. Figyelj arra, hogy ez a paraméterét radiánban várja, vagyis 1°=π/180 rad.Tipp: mindegyik sorban ki kell írnunk valahány szóközt, és utána egy
X
-et. Hány sor van összesen? Mitől függ az, hogy hány szóközt kell tenni? Először írj erre képletet! Gondold végig, a feladat megoldásában melyik változó lehet egész, és melyiknek kell valósnak lennie!Megoldás
Szóközök száma: A
sin(fok)
nyilván nem jó, mert a sin radiánban várja a paramétert, ezért át kell váltani:sin(fok*3.1416/180)
. Ez viszont még mindig nem jó, mert asin()
−1 és +1 közötti számot ad vissza, azaz vagy 0 vagy 1 szóközt írnánk ki. Ha ezt megszorozzuk 10-el, akkor az eredmény −10 és +10 közötti lesz. Ha viszont még 10-et hozzáadunk, akkor a szóközök száma 0 és 20 között lesz, ami a várt ábrát adja.#include <stdio.h> #include <math.h> /* Kell a szinusz miatt */ int main() { int fok; int i; int szokoz; /* A fok változó 0-tól 360-ig megy 20-asával lépkedve */ for (fok=0; fok<=360; fok=fok+20) { szokoz = (10+10*sin(fok*3.1416/180)); /* Kiírjuk a szóközöket */ for (i=0; i<szokoz; i=i+1) printf(" "); /* Írok egy x-et */ printf("X\n"); } return 0; }
-
| 1 2 3 4 5 --+------------------- 1| 1 2 3 4 5 2| 2 4 6 8 10 3| 3 6 9 12 15 4| 4 8 12 16 20 5| 5 10 15 20 25
Tervezz programot pszeudokóddal, amely kiírja a képernyőre az N×N-es szorzótáblát, ahol N értékét a felhasználó adhatja meg. Valósítsd meg C nyelven! Ügyelj arra, hogy a számok állandó oszlopszélességgel jelenjenek meg (maximum 16×16-as táblát feltételezve), azaz pl. az oldalt látható módon. (Ez abban nehezebb az előadáson bemutatottnál, hogy a szorzótáblának kerete is kell legyen.)Megoldás
#include <stdio.h> int main() { int x, y; /* Keret felső része */ printf(" |"); for (y=1; y<=16; y=y+1) printf("%3d ",y); printf("\n"); printf("---+"); for (y=1; y<=16; y=y+1) printf("----"); printf("\n"); /* Szorzótábla */ for (y=1; y<=16; y=y+1) { printf("%2d |",y); /* Keret bal oldala */ for (x=1; x<=16; x=x+1) printf("%3d ", x*y); /* Számok */ printf("\n"); } return 0; }
Sakktábla
XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX
- Rajzolj a képernyőre sakktáblát, ahogyan az oldalt látható! Hogyan lehet
ezt a legtöbb ciklussal, a programban szereplő legrövidebb kiírt szövegekkel
megoldani? Vagyis ne szerepeljen a programban ilyesmi:
printf("XX XX XX XX \n"); printf("XX XX XX XX \n");
Megoldás
#include <stdio.h> int main() { int i, j, k; for (i=1; i<=4; i=i+1) { for (j=1; j<=2; j=j+1) { for (k=1; k<=4; k=k+1) printf("XX "); printf("\n"); } for (j=1; j<=2; j=j+1) { for (k=1; k<=4; k=k+1) printf(" XX"); printf("\n"); } } return 0; }
- Használd a sakktáblán a szokásos jelölést;
1…8
a sorok,a…h
az oszlopok jele. Adott két mező, pl.b7
ésd6
; kérd ezeket a felhasználótól! Mondd meg ezután, ez a lépés szabályos-e egy király, vezér, futó, bástya vagy huszár számára! (Tegyük fel, hogy nem áll más figura az útjukban.)Megoldás
#include <stdio.h> #include <stdlib.h> int main() { /* a két mező koordinátája */ char o1, s1, o2, s2; /* megkérdezzük a felhasználót. */ /* a scanf-nél a szóközök elnyelik a whitespace karaktereket. */ printf("Írd be az első mezőt, pl. d6!\n? "); scanf(" %c %c", &o1, &s1); printf("Írd be a második mezőt, pl. f8!\n? "); scanf(" %c %c", &o2, &s2); /* a betűkre karakterként (számként) tekintek. * mivel ábécé sorban vannak, a számjegyek pedig növekvő * sorrendben, ezért kisebb/nagyobb összehasonlítást * végezhetek, és kivonhatom őket egymásból. */ if (o1<'a' || o1>'h' || s1<'0' || s1>'8' || o2<'a' || o2>'h' || s2<'0' || s2>'8') { printf("Hibás sor- vagy oszlopmegadás!\n"); } else { /* kivételes eset mindegyik figuránál, ha nem * lépett sehova (o1==o2 és s1==s2), hiszen az * nem is lépés. itt azért szerepel mindegyik * kifejezésben, hogy önmagukban is egészt * alkossanak. */ /* a király egyet léphet valamelyik irányba. ez * azt jelenti, hogy a sor- és az oszlopugrás * távolságának abszolút értéke maximum egy. */ if (abs(o1-o2)<=1 && abs(s1-s2)<=1 && !(o1==o2 && s1==s2)) { printf("Ez szabályos a király számára.\n"); } /* a bástyánál az oszlop- vagy a sor változatlan. * de mindkettő nem lehet ugyanaz. */ if ((o1==o2 || s1==s2) && !(o1==o2 && s1==s2)) { printf("Egy bástya léphet így.\n"); } /* a futónál mindkét irányba ugyanannyit kell * mozdulni, úgy jön ki az átlós lépés. */ if (abs(o1-o2)==abs(s1-s2) && !(o1==o2 && s1==s2)) { printf("Egy futó számára ez helyes lépés lehet.\n"); } /* a királynő mint a bástya és a futó együtt. */ if (((o1==o2 || s1==s2) || abs(o1-o2)==abs(s1-s2)) && !(o1==o2 && s1==s2)) { printf("A vezér léphet ilyet.\n"); } /* a huszár nehéznek tűnik, de nem az. az L alak * azt jelenti, hogy a vízszintes elmozdulás 1, * a függőleges 2, vagy fordítva. */ if ((abs(o1-o2)==2 && abs(s1-s2)==1) || (abs(o1-o2)==1 && abs(s1-s2)==2)) { printf("Huszár számára szabályos.\n"); } } return 0; }
- A feladat mint az előző, de most csak egy mezőt ad a felhasználó (pl.
d6
). Listázd ki a programból, melyekre tud lépni szabályosan arról egy király, egy vezér stb.
Prímszámok
- Kérj a felhasználótól egy
n
számot. Írd ki az összes olyan(i;j)
párt, amelyre1<i<j≤n
, és igaz az, hogyi+j
prím. Pl.n=6
esetén2+3=5
,3+4=7
stb. -
300│2 150│2 75│3 25│5 5│5 1│
Emlékezz vissza a gyakorlat feladatára, a prímtényezős felbontásra. Egy adott osztóval addig osztunk, amíg csak lehet; utána a következő osztót próbáljuk. Mindezt pedig addig folytatjuk, amíg 1-ig el nem érünk, mert az már nem osztható semmivel.
Tervezz programot két pozitív egész legnagyobb közös osztójának (LNKO) meghatározására! Gondold végig, hogyan lehet a sima prímtényezős felbontásból kiindulni. (Egy tényező akkor szerepel a közös osztó felbontásában, ha mindkettő számnak tényezője.) A tervezéshez pszeudokódot, folyamatábrát vagy struktogramot használj! Valósítsd meg a programot C nyelven!Megoldás
#include <stdio.h> int main() { int szam1, szam2; int lnko, oszto; printf("Egyik szam? "); scanf("%d", &szam1); printf("Masik szam? "); scanf("%d", &szam2); lnko=1; /* ez mindennek osztoja :) */ oszto=2; /* legkisebb szam, amivel osztunk */ while (szam1>1 && szam2>1) { /* amig mindkettonek osztoja */ while (szam1%oszto==0 && szam2%oszto==0) { /* addig ez tenyezo, felszorozzuk */ lnko=lnko*oszto; szam1=szam1/oszto; szam2=szam2/oszto; } /* ha kijottunk a fenti ciklusbol, valamelyiknek nem osztoja mar. mindegy, melyiknek; a masikat osztogassuk le. a ket ciklus kozul az egyik olyan lesz, amibe egyszer sem megy be! */ while (szam1%oszto==0) szam1=szam1/oszto; while (szam2%oszto==0) szam2=szam2/oszto; oszto=oszto+1; } printf("LNKO: %d\n", lnko); return 0; }
Megoldás
#include <stdio.h> int main() { int a, b; int oszto, lkkt; /* a ket szamot kerjuk a felhasznalotol */ printf("a="); scanf("%d", &a); printf("b="); scanf("%d", &b); oszto=2; lkkt=1; /* amig valamelyik meg nem egy */ while (a>1 || b>1) { /* ha mindkettonek osztoja, felszorozzuk */ while (a%oszto==0 && b%oszto==0) { lkkt=lkkt*oszto; a=a/oszto; b=b/oszto; } /* ha valamelyiknek osztoja, akkor is felszorozzuk */ while (a%oszto==0) { lkkt=lkkt*oszto; a=a/oszto; } while (b%oszto==0) { lkkt=lkkt*oszto; b=b/oszto; } oszto=oszto+1; } printf("lkkt=%d\n", lkkt); return 0; }