Labor, 1. hét: egyszerű programok

Pohl László, Czirkos Zoltán · 2023.08.30.

Egyszerű C programok lefordítása, futtatása. Bemenet és kimenet kezelése, egyszerű számítások és vezérlési szerkezetek.

Ezen az első laboron a Code::Blocks fejlesztőkörnyezet használatának alapjait ismerjük meg. Felkészülés a laborra:

1. A Code::Blocks fejlesztőkörnyezet

Az integrált fejlesztőkörnyezetek (integrated development environment, IDE) a programok fejlesztését – készítését, tesztelését, hibakeresését segítő programok. A C nyelv szabványos és elterjedt volta miatt rengeteg ilyen készült hozzá. A Prog1 tárgyban az ajánlott fejlesztőkörnyezet a Code::Blocks nevű, ingyenesen letölthető szoftver, ami megtalálható a HSzK gépein is.

Indítsd el a Code::Blocks programot! Válaszd ki a File menü New/Project… menüpontját! Az alábbi ábrákon látható módon folytasd a projekt létrehozását! Figyelj minden részletre!

  • A projekt típusának válaszd ki a Console application-t. Nyomd meg a Go gombot.
  • A következő oldalon a programozási nyelvet kell megadnod. Ez legyen a C.
  • Ezután arról érdeklődik a Code::Blocks, hogy mi legyen a projekt neve. Írd be, hogy „elso”. Alatta kell beállítanod azt a mappát, ahol a projekt fájlok tárolódnak. Ha ez üresen van hagyva, akkor nyomd meg a ... gombot, és válaszd ki a Dokumentumok mappádat. (Jegyezd meg a mappa elérési útját!) Fontos: a projekt mappa neve, se elérési útja ne tartalmazzon se ékezetes betűket, se szóközt!
  • A negyedik ablakban a fordítóprogramot lehet megadni. Ha nem a „GNU GCC Compiler” van kiválasztva, akkor válaszd azt, továbbá ha a „Create "Debug" configuration” nem lenne beikszelve, akkor azt javítsd ki. De ezek így szoktak lenni.
  • Ezzel létre is jött a projekt. A bal oldalon, a „Management” résznél láthatóak a hozzá tartozó fájlok. A „Sources” mappát kinyitva megtalálod a fő programmodult, a main.c-t. Ebben egy helló világ program van. Fontos: a megadott mappanév ne tartalmazzon ékezetes betűket! Sok program ezeket nem szereti.

2. Helló világ

A Code::Blocks eleve úgy hozta létre a projektet, hogy egy egyszerű helló világ programot tett bele. Ha másik fejlesztőkörnyezetet használsz, akkor másold be ezt a C programot (kettőt kattintva a kódra kijelölheted az egészet):

#include <stdio.h>

int main(void) {
    printf("Hello world!\n");
    return 0;
}

A futtatható program

A fejlesztőkörnyezet által létrehozott saját program ugyanúgy működik, mint a többi parancssori alkalmazás: tartozik hozzá egy .exe. A programodat a „Build and run” (zöld play gomb + sárga fogaskerék) gombra kattintva indíthatod el, vagy a Build/Build and run menüpontot választva. Ilyenkor előbb lefordítja a gép, és aztán el is indítja. Ennek eredménye így kell kinézzen.

Az .exe fájl a project mappa bin/debug alkönyvtárában jön létre.

3. Megoldások feltöltése

Az egész félév során feladat lesz az a laborban, hogy az elkészített megoldásokat a labor végén csomagold össze egy ZIP fájlba (nem 7ZIP, nem RAR!), és töltsd azt fel a portálra. Így neked is meglesz.

Ahogy látni fogod, belépve az adminisztrációs oldalon elérhető a feladatbeadó felület is. A kiírt feladatok közt fogod látni minden héten a laborfeladatoknak való helyet. Itt több fájlt kijelölve is megadhatod a .c programjaidat, vagy csomagolva egyszerre feltöltheted az egészet.

Arra ügyelj, hogy a becsomagolt ZIP-ben az EXE és OBJ fájlok (azaz a projekthez tartozó bin és obj mappa) ne legyenek benne! Ezeket a portál nem fogja engedni feltölteni. Legegyszerűbb ZIP-be csomagolás előtt törölni ezeket.

4. ZIP fájlok létrehozása

ZIP archívumokba több fájl csomagolható és tömöríthető. Utána az archívum egyetlen fájlként kezelhető, pl. küldhető el e-mailben, vagy tölthető fel valahova. ZIP archívumot – vagy tömörített mappát, ahogy a Windows nevezi – legegyszerűbb a Fájlkezelővel létrehozni. Ennek két módja lehetséges, próbáld ki mindkettőt!

Első módszer

  • Keresd meg a tömöríteni kívánt fájlokat vagy mappákat.
  • Jelöld ki az összeset, amelyre szükség van. Ezt megteheted az egérrel kattintva és húzva, téglalapot rajzolva föléjük, vagy a Ctrl gombot nyomva tartva, és egyesével kattintva rájuk.
  • Ha sikerült a kijelölés, kattints a jobb egérgombbal valamelyikükre, és válaszd ki a menüből a Küldés / Tömörített mappát:
  • Ezután megadhatod a fájl nevét, és a ZIP archívum elkészült.

Ugyanez az Asztalon is működik, ha eddig a fájlokat ott hoztad létre.

Második módszer

  • Kattints jobb egérgombbal a semmibe a Fájlkezelőben vagy az asztalon. Válaszd ki az Új / Tömörített mappa menüpontot.
  • Létrejön egy „Új tömörített mappa” nevű ZIP fájl. Kattints erre a jobb gombbal, és nevezd át arra, amire szeretnéd.
  • Ha megvan, utána a tömöríteni kívánt fájlokat egyesével húzd rá az egérrel őket a ZIP fájlra. A többszörös kijelölés itt ugyanúgy működik, kattintás közben a Ctrl billentyűt nyomva tartva.

A létrehozott archívumokra duplán kattintva a Windows Fájlkezelője megmutatja azok tartalmát is. Így ellenőrizni tudod, mi van bennük. Ezekből (és ezekbe) ugyanúgy másolhatók a fájlok, mint egy mappába. De szem előtt kell tartani, hogy valójában ezek nem igazi mappák. Ha bármire szükség van, akkor ki kell bontani az archívumot. A kicsomagolás legegyszerűbben a jobb egérgombbal kattintásra előjövő menüből lehetséges, a „Kibontás” menüpontot kiválasztva.

5. A tartály

Tartály

Írj programot, amely segít kiszámítani a felhasználónak, hogy hány doboz festéket kell vennie a lábakon álló tartály festéséhez! Ehhez használnod kell majd az első előadásokon tanultakat. Indulj ki az előadáson bemutatott kör kerülete és területe programból!

A tartálynak ismerjük a magasságát és az átmérőjét. Mindenhol le kell festeni, az oldalát, a tetejét és az alját is. Tudjuk azt is, hogy egy doboz festék 2 m2 felület lefestéséhez elegendő.

Tartaly festese

Milyen magas? 2
Mennyi az atmeroje? 1.2

4.900885 doboz festek kell.

Figyelj arra, hogy a program kódjában tizedesvessző helyett tizedespontot kell használni (pl. 3.14), ugyanígy a bemenet megadásánál is. Ha nem jön ki a fenti eredmény, gondold át, helyes-e a képlet, amit használsz.

Megoldás
#include <stdio.h>

int main(void) {
    double atmero, magas;
    printf("Tartaly festese\n\n");
    printf("Milyen magas? ");
    scanf("%lf", &magas);
    printf("Mennyi az atmeroje? ");
    scanf("%lf", &atmero);

    double sugar = atmero/2;
    double doboz = (2*sugar*sugar*3.14159265 + magas*2*sugar*3.14159265) / 2;

    printf("\n%f doboz festek kell.\n", doboz);

    return 0;
}

Hasonló feladatok

Ha ez a feladat nehezen ment, megoldhatsz pár hasonló feladatot a példatárból, mielőtt a következő feladatra rátérsz.

Vigyázz, a laborfeladatokat erősen ajánlott az utolsó feladatig megoldani, hogy a jövő hétre felkészült legyél. Ha nem sikerül, fejezd be őket otthon!

6. Másodfokú egyenlet diszkutálása

Írj programot, amely az ax2+bx+c=0 másodfokú egyenlet együtthatóit kérdezi a felhasználótól, és kiírja, hogy az egyenletnek hány (valós) megoldása van! Ehhez használnod kell az elágazásról tanultakat: lásd az előadást! A megoldóképlet:

Próbáld ki az alább látható egyenletekre! Ezekkel ellenőrizni tudod a megoldásod.

egyenletmegoldás
2x2-x-6=0x1=2, x2=-1.5
x2-12x+35=0x1=5, x2=7
egyenletmegoldás
2x2-4x+2=0x=1
x2+2x+10=0 -
Megoldás

A diszkrimináns vizsgálatával tudjuk megnézni, hány valós megoldás lesz.

Az if (diszkr==0) vizsgálat elméletben helyes, gyakorlatban azonban nem előnyös ilyet írni. A kerekítési hibák miatt előfordulhat az, hogy 0-hoz olyan közeli szám adódik, amit már 0-ra kerekít a számítógép. Erről is később lesz szó előadáson.

#include <stdio.h>

int main(void) {
    double a, b, c;
    printf("a=");
    scanf("%lf", &a);
    printf("b=");
    scanf("%lf", &b);
    printf("c=");
    scanf("%lf", &c);

    /* a diszkriminans: b² - 4ac */
    double diszkr;
    diszkr = b * b - 4 * a * c;

    /* ha <0, 2 komplex gyok lenne */
    if (diszkr < 0) {
        printf("Nincs valos gyok!\n");
    }
    /* ha pont 0, akkor 1 megoldas van */
    if (diszkr == 0) {
        printf("Egy valos gyok van.\n");
    }
    /* >0, akkor 2 megoldas */
    if (diszkr > 0) {
        printf("Ket valos gyok van.\n");
    }

    return 0;
}

Hasonló feladatok

Ha ez a feladat nehezen ment, megoldhatsz pár hasonló feladatot a példatárból, mielőtt a következő feladatra rátérsz.

Vigyázz, a laborfeladatokat erősen ajánlott az utolsó feladatig megoldani, hogy a jövő hétre felkészült legyél. Ha nem sikerül, fejezd be őket otthon!

7. Számok kiírása

Az ábrán egy program pszeudokódja látható, amely kiírja a számokat 1-től 20-ig.

Gondolok egy számra, legyen ez 1.
Ismétlés, amíg a szám ≤ 20
    Leírom a számot.
    Új sort kezdek.
    Növelem a számot 1-gyel.
Ismétlés eddig

Írd meg ezt a programot C-ben az előadáson tanult while ciklussal!

Figyeld meg: ahogy gépeled be a while utáni { kapcsos zárójelet, az Enter billentyű hatására a gép egyből néhány szóközzel beljebb kezdi a sorokat. A bezáró } kapcsos után pedig újra kintebb. Használd ezt ki! Így áttekinthetőbb lesz a programod, jobban látszik a ciklus belseje. Ha elrontottad a formázást, a Code::Blocks automatikusan, utólag is képes rendbe tenni a kódot: ehhez kattints jobb gombbal a forráskódra, és válaszd az előugró menüből a „Format use Astyle” menüpontot.

Írd át a while ciklust for ciklusra!

Hasonló feladatok

Ha ez a feladat nehezen ment, megoldhatsz pár hasonló feladatot a példatárból, mielőtt a következő feladatra rátérsz.

8. Adott hosszúságú vonal

Írj egy programot, amely kér a felhasználótól egy számot, és kirajzol egy + és jelekből álló szakaszt. Pl. ha a szám 4, akkor a képernyőn a lenti ábra jelenjen meg, vagyis a belsejében 4 db legyen:

Mekkora legyen a szakasz? 4
+----+

Írd meg a program pszeudokódját, utána pedig gépen a C forráskódot! A pszeudokódot írhatod a fejlesztőkörnyezetbe megjegyzésként is, az egyes sorok alá odaírva a C nyelvű megfelelőjüket.

Tipp: ehhez a programhoz nem kell if elágazás. Ha olyan változatot írtál, amiben van, akkor próbáld meg anélkül is! Gondolj arra, hogy a szakasz elején és végén biztosan van +.

Megoldás
#include <stdio.h>

int main(void){
    int hossz;
    printf("Mekkora legyen a szakasz?\n");
    scanf("%d", &hossz);  /* Hossz beolvasása */

    printf("+");  /* A vonal elejére kell egy + jel */
    for (int i = 0; i < hossz; i = i+1)  /* Ciklus, ami kiír adott - jelet */
        printf("-");
    printf("+");  /* A vonal végére is kell egy + jel */

    return 0;
}

9. Másodfokú egyenlet

Ez a feladat túlmutat az első heti törzsanyagon. Akkor foglalkozz csak vele, ha jut még rá időd, és/vagy érdekel, hogy a te programod is helyesen kiszámolja-e a másodfokú egyenletek megoldását.

Írj programot, amely az ax2+bx+c=0 másodfokú egyenlet együtthatóit kérdezi a felhasználótól, és kiírja az egyenlet x1 és x2 megoldását! A megoldóképlet:

Vedd elő a megoldást diszkutáló programot, és azt fejleszd tovább! Az alábbi egyenletekkel ellenőrizd, hogy helyes-e a megoldásod!

egyenletmegoldás
2x2-x-6=0x1=2, x2=-1.5
x2-12x+35=0x1=5, x2=7
egyenletmegoldás
2x2-4x+2=0x=1
x2+2x+10=0 -

Gyökvonásra az sqrt() könyvtári függvény használható. Ehhez szükséges egy #include "math.h" sor is a kód elején. (Linuxon parancssorból fordítva -lm kapcsoló szükséges.)

Megoldás

Arra kell figyelni, hogy ne vonj negatív számból négyzetgyököt. A gyökvonás csak pozitív diszkrimináns esetén lehetséges, de csak ott van rá szükség.

Itt egy nagyobb C kifejezést kapsz, amiben többféle operátor (összeadás, kivonás, szorzás stb.) szerepel. Ezeknek a műveleteknek C-ben ugyanúgy van precedenciája, mint a matematikában. A szorzás pl. magasabb rendű művelet, mint az összeadás. A C nyelv precedencia szabályai összetettebbek; erről majd előadáson lesz szó.

#include <math.h >
#include <stdio.h>

int main(void) {
    double a, b, c;
    printf("a=");
    scanf("%lf", &a);
    printf("b=");
    scanf("%lf", &b);
    printf("c=");
    scanf("%lf", &c);

    /* a diszkriminans: b² - 4ac */
    double diszkr;
    diszkr = b * b - 4 * a * c;

    /* ha <0, 2 komplex gyok lenne */
    if (diszkr < 0) {
        printf("Nincs valos gyok!\n");
    }
    /* ha pont 0, akkor 1 megoldas van */
    if (diszkr == 0) {
        printf("Egy valos gyok: %f\n", -b / (2 * a));
    }
    /* >0, akkor 2 megoldas */
    if (diszkr > 0) {
        printf("Ket valos gyok: %f, %f\n",
               (-b + sqrt(diszkr)) / (2 * a),
               (-b - sqrt(diszkr)) / (2 * a));
    }

    return 0;
}

10. További feladatok

Ha elkészültél, folytasd a feladatgyűjtemény ehhez a témakörhöz kapcsolódó feladataival!