Kihagyás

1. gyakorlat

Bíró

A félév során a Bírót használjuk a ZH -hoz, míg a Bíró2-n órai és gyakorló feladatok lesznek

Be kell regisztrálni a Bíróra és Bíró2-re is

Környezet

Windows

Az alábbiakban három megoldást fogunk ismertetni, amelyből bármelyik megoldás használható az otthoni felkészülés során.

WSL

A Windows Subsystem for Linux segítségével Linuxos programokat futtathatunk Windowsos gépünkön. Amennyiben Windows 10-es gépünk van és dual boot vagy virtuális gép telepítése nélkül szeretnénk Linux felületet használni, ez a legegyszerűbb módja annak, hogy a kabinethez hasonló környezetben a GCC fordítóval dolgozzunk.

A WSL használatáról bővebben. A WSL 2 a fent említett rendszer újabb verziója

MinGW

A MinGW (Minimalist GNU for Windows) segítségével GNU fordítóprogramokat telepíthetünk Windowsra. Telepítése elején kisebb nehézségekbe ütközhetünk, de ezek után egész félévben segítségünkre lehet.

A MinGW letöltéséhez látogassunk el ide, majd töltsük le a "MinGW Installation Manager (mingw-get)" telepítő alkalmazást. Ezt követően telepítsük fel. Mindent nyugodtan hagyhatunk az alapértelmezett beállításon.

telepítés első lépés

Telepítés után indítsuk el a "MinGW Installation Manager"-t. Itt tudjuk kiválasztani, hogy milyen komponenseket szeretnénk telepíteni.

komponensek kiválasztása

A kurzus teljesítéséhez szükségünk lesz a "mingw32-gcc-g++-bin" csomagra, ha esetleg hagyományos C fordítót is szeretnénk, akkor a "mingw32-base-bin" csomagot is feltelepíthetjük. A telepítéshez a csomag(ok) melletti checkboxo(ka)t kell kipipálni (Mark for Installation), majd ezt követően az "Installation" menüben lévő "Apply changes" menüpontra kell kattintani, így megkezdődik a kiválasztott csomagok telepítése. Miután ez elkészült, a felugró ablakot a "Close" gomb lenyomásával bezárhatjuk. Ezt követően a MinGW telepítő segédre sincs már szükségünk, azt is bezárhatjuk.

Ahhoz, hogy mindig kényelmesen tudjuk használni a g++ parancsot, célszerű beállítani a PATH környezeti változót.

PATH környezeti változó beállítása Windows 8-ig

  1. Ehhez először is Start menü, majd jobb klikk a Számítógépen (vagy Sajátgépen) és a lenyíló menüben válasszuk a Tulajdonságok menüpontot.
  2. A bal oldali menüben válasszuk ki a "Speciális rendszerbeállítások" menüpontot.
  3. A felugró ablakon kattintsunk a Speciális fülre, majd a Környezeti változók gombra.
  4. A rendszerváltozók közül válasszuk ki a PATH környezeti változót, majd kattintsunk a Szerkesztés gombra.
  5. Navigáljunk a sor elejére, majd ide írjuk be a MinGW /bin/ könyvtárának elérési útvonalát, és tegyünk a végére egy pontosvesszőt. (Tehát a PATH környezeti változó ehhez hasonlóan kezdődjön (A JDK útvonala adott esetben más lehet!): C:\MinGW\bin;
  6. Okézzuk le az összes megnyitott ablakot.

PATH környezeti változó beállítása Windows 10-en

  1. A Windows vagy a kereső gombra kattintva keressünk rá "A rendszer környezeti változóinak módosítása" Vezérlőpult-elemre.

environment_step1

  1. A megjelenő ablakban kattintsunk a Környezeti változók... gombra.

environment_step2

  1. Az alsó táblázatban keressük ki a Path változót, jelöljük ki, majd Szerkesztés...

environment_step3

  1. Kattints az Új gombra, majd a megjelenő szerkeszthető táblázatsorba másold be a MinGW bin mappájának útvonalát.

environment_step4

  1. OK az összes párbeszédablakon.

Kész a telepítés, ellenőrizzük le, hogy működik-e. Ezt az alábbi módon tehetjük meg: Nyissuk meg a parancssort (Start menü, Futtatás, cmd), majd írjuk be a g++ parancsot. A parancs hatására a g++ hiányzó input hibaüzenetét kell látnunk.

Microsoft Visual Studio command prompt

A Microsoft Visual Studio egy nagyon sokrétűen használható fejlesztői környezet C, C++, C#, stb. fejlesztők számára. Ez a fejlesztői környezeten kívül tartalmaz Windowsra szánt fordítóprogramot is, amit parancssorból is használhatunk. Mielőtt használni tudnánk, fel kell telepítenünk a Visual Studiot, amit itt tölthetünk le (bőven elegendő lesz a kurzushoz a Community edition is).

Az alkalmazás telepítése (ez elég sok ideig is eltarthat) után használhatjuk a parancssori fordítót is. Ezt legegyszerűbben a Start menüből érhetjük el, "Developer Command Prompt for VS 2019" néven. Ez egy olyan parancsablakot indít, amiben már benne vannak a Visual Studio fejlesztői eszközei, köztük a cl nevű parancssori fordító is.

A kurzuson Linuxot fogunk használni, így célszerűbb a fenti két megoldás közül választani.

Linux

Néhány népszerűbb Linux változaton már előre telepítve van a gcc és g++ fordítóprogram. Amennyiben mégsem lenne telepítve, a központi csomagtárolóból könnyedén telepíthetjük.

1
sudo apt install g++

Clang

Egyre elterjedtebb fordító program a clang. Ez általában nem előre telepített program. Telepítésével kapcsolatban itt kapunk bővebb információt.

Online fordítás, futtatás

Léteznek olyan megoldások is, hogy a böngészőbe írjuk a programkódot és az egyből fordítja. Ne ez legyen az elsőszámú fordító környezet, de lehet használni (ZH alatt NEM), és olyan esetekben indokolt is, amikor olyan dolgot akarunk kipróbálni, amit az éppen használt fordítóprogramunk nem ismer.

Kabinet használata

Programozás alapjairól ismerős lehet a kabinetes rendszer. Mindenki a saját hxxxxxx-es azonosítójával fel tud csatlakozni egy Linux-os rendszerre és ott fájlokat tárolhat, kezelhet és természetesen fordíthat. A rendszer számunkra lényeges programjainak, leginkább a C++ fordítónak, azonos a verziója a Kabineten és a Biro rendszerben. Így ha valami nem fordul a Kabinetes rendszeren, azt a bíró sem fogadja el, hiába volt sikeres a lokális fordítás.

Bejelentkezés

ssh hxxxxxx@linux.inf.u-szeged.hu

Ezután meg kell adnunk a hxxxxxx-s azonosítóhoz tartozó jelszót.

kabinet login

Természetesen a bejelentkezést a képen látott WSL rendszerből is meg lehet tenni, használható hozzá a PuTTY program, a MobaXterm és egyéb lehetőségek is. Utóbbi használata során lehetőségünk van grafikus felületet is használni.

A kurzushoz fontos programok a gcc és a g++.

gcc verziók

Adatok másolása

Az adatokat másolhatjuk pl. WinSCP segítségével Windows rendszer alatt vagy akár csak a scp parancs segítségével.

IDE

A fejlesztéshez tetszőleges szövegszerkesztő használható, néhány javasolt fejlesztői környezet (melyek esetlegesen ismerősek lehetnek korábbról):

  • CodeLite
  • Anjuta
  • DevC++
  • Visual Studio
  • CLion
  • Visual Studio Code
  • Code::Blocks

Aki korábban használta a Jetbrains termékeit, annak a CLion megfelelő választás lehet, hiszen ez nagyon hasonló fejlesztőkörnyezet a korábban ismertekhez (IntelliJ IDEA, WebStorm, PHPStorm, PyCharm).

Első program

Ahhoz, hogy tudjunk fordítani, szükségünk lesz egy fordítandó forráskódra is. Mivel még nem tudunk C++-ban programozni, nyugodtan írhatunk egy C nyelvű programot is, mentsük el elso.cpp néven (a .cpp kiterjesztés fontos).

1
2
3
4
5
6
#include <stdio.h>

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

Fordítás

Ha már eddig kész vagyunk, a Programozás alapjairól már ismert módon fordíthatjuk a programunkat, annyi különbséggel, hogy az eddigi gcc parancs helyett g++ parancsot kell használnunk.

g++ -o elso -Wall elso.cpp

Ismétlés a kapcsolókról:

  • -o kapcsolóval adhatjuk meg a kimeneti fájl nevét
  • -Wall kapcsolóval további fordítóprogram figyelmeztetést (warningot) kapcsolhatunk be
  • Ilyen például az, hogy egy boolean értéket egy nem boolean-nek megfelelő egésszel hasonlítunk össze
  • vagy mondjuk a kiírt, de üresen hagyott if/else blokkokról is kaphatunk warningot.
  • elso.cpp a fordítandó forrás fájl neve

A lefordított, linkelt alkalmazást ezután már futtathatjuk elso.exe vagy ./elso utasítással. A fordító -o paraméter nélkül a.exe vagy a.out nevű futtatható állományt készít.

Fordítás fázisai

Ugyanaz, mint C esetében (lásd Programozás Alapjai jegyzet).

Hello Világ C++-ban

A megszokott, jól ismert C programunkat átalakíthatjuk úgy, hogy a C++-ban használatos kiíratás szerepeljen benne.

1
2
3
4
5
6
#include <iostream>

int main() {
  std::cout << "Hello World!" << std::endl;
  return 0;
}

Hogy ne kelljen mindenhova kiírni az std:: előtagot, a program elejére beírhatjuk a using namespace std; sort. (Ennek a jelentéséről majd később beszélünk.)

1
2
3
4
5
6
7
8
#include <iostream>

using namespace std;

int main() {
  cout << "Hello World!" << endl;
  return 0;
}

A felkommentelt fájl letöltése

C++ input/output

A hagyományos C-ben megtanult beolvasás és kiíratás is működik C++-ban.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#include <stdio.h>

int main(int argc, char* argv[]) {
  int kor = 0;
  float magassag = 0.0;
  char nev[10]; // fix meret

  printf("Adja meg a korat es magassagat szokozzel elvalasztva: ");
  scanf("%d %f", &kor, &magassag);
  printf("\n");

  printf("Adja meg a nevet: ");
  scanf("%s", nev);

  printf("Nev: %s, kor: %d, magassaga: %f", nev, kor, magassag);

  return 0;
}

A fájl letöltése

C++-ban az input/output műveletek streamek (folyamok) segítségével vannak megvalósítva

  • cout: az alapértelmezett kimenet
  • cerr: az alapértelmezett hibakimenet
  • cin: az alapértelmezett bemenet

A streamekbe (folyamokba) a << operátor segítségével írhatunk, és a >> operátor segítségével olvashatunk belőlük.

Ezek használatához a C-ben megszokott stdio.h header fájl helyett a C++-ban használatos iostream header fájlt kell include-olni. Ezzel az új, stream-eken alapuló műveleteket adjuk hozzá programunkhoz.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#include <iostream>

using namespace std;

int main(int argc, char* argv[]) {
  int kor = 0;
  float magassag = 0.0;
  char nev[10];

  cout << "Adja meg a korat (evek szama) es magassagat szokozzel elvalasztva: ";
  cin >> kor >> magassag;

  cout << "Adja meg a nevet: ";
  cin >> nev;

  cout << "Nev: " << nev << " kor: " << kor << " ev, magassag: " << magassag << " cm" << endl;
  return 0;
}

Sorvéget az endl segítségével írhatunk.

A fájl letöltése

C++ string

Mi történik az alábbi programmal akkor, ha a fix méretű karakter tömbbe hosszabb méretű karakterláncot adunk meg?

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#include <iostream>
#include <string>

using namespace std;

int main() {
  char nev[10];
  cout << "Adja meg a nevet: ";
  cin >> nev;
  cout << "A nev: " << nev << endl;
}

Az eredmény (ha a program lefut):

1
2
Adja meg a nevet: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Nev: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

Azonban ha túl hosszú a bemenet, akkor a program hibával megállhat. A megoldás az, hogy az inputnak megfelelő méretű területet foglalunk, és oda írjuk be a felhasználó által megadott nevet. A C++-ban a "szövegeknek" van egy hatékonyabb, kevésbé körülményes megvalósítása is, a string osztály (osztályokról később lesz szó, most csak azt mutatjuk be, hogyan lehet használni a string-et). A string objektumok dinamikusan változtatják a méretüket a tartalmazott karakterek számától függően. A félév folyamán stringek alatt ezt a reprezentációt értjük, nem pedig a char*-ot. A string objektumok használatához, string műveletekhez szükségünk lesz a string header include-olására is (és nem string.h). Ezt követően kényelmesen használhatjuk a szövegeket, ahogy már Javaban is megszoktuk. Itt csak a fontosabb használati eseteket emeljük ki, bővebb leírásokhoz linkek:

A string osztály fontosabb metódusai, amelyeket a leggyakrabban használunk:

Létrehozás, azaz a konstruktorok

1
2
3
4
string s1;           // ures string
string s2("alma");   // string, amely az "alma" szoveget tartalmazza
string s3 = "korte"; // string, amely az "korte" szoveget tartalmazza
string s4(s2);       // string, amely az "alma" szoveget tartalmazza, mert az s2 "alma"

Beolvasás, kiírás

1
2
3
string str;
cin >> str;
cout << "A beolvasott szoveg: " << str << endl;

A scanf nem használható a string beolvasására, de a cin segítségével be tudjuk olvasni, és a cout segítségével ki tudjuk írni.

Összehasonlítás

1
2
3
4
5
6
string s1, s2;
cin >> s1 >> s2;
if (s1 == s2)
    cout << "A ket string azonos" << endl;
else
    cout << "A ket string nem azonos" << endl;

A string-eket az == operátor segítéségével össze lehet hasonlítani.

Összefűzés

1
2
3
4
string s1("Hello"), s2("World"), s3;
s3 = s1 + " " + s2 + "!";
cout << s3 << endl;
// kimenet: Hello World!

Méret, üres-e, tartalom törlése

1
2
3
4
5
6
7
8
string s("alma");
// size() es length() ugyanaz, length olvasmanyosabb
cout << "meret: " << s.size() << " " << s.length() << endl; // meret: 4 4
if (s.empty()) // van benne karakter -> false
    cout << "s ures" << endl;
s.clear();
if (s.empty())
    cout << "s ures" << endl; // most kiirja, hogy "s ures"

i-edik elem

1
2
3
4
5
string s("alma");
cout << s[2] << endl; // m
s[0] = 'l';
s[1] = 'a';
cout << s << endl;    // lama

Ha olyan indexre hivatkozunk, amelyik érvénytelen, azaz a string hosszánál nagyobb, akkor nem definiált viselkedés lesz az eredménye.

Konverzió szám és string között

Számból string-gé a to_string segítségével konvertálhatunk.

1
2
3
4
int i = 5;
string s1 = to_string(i);
string s2 = to_string(3.14);
cout << s1 << " " << s2 << endl; // 5 3.140000

string-et számmá konvertálni az stoi függvénnyel lehet.

1
2
3
string s1("12345");
int i = stoi(s1);
cout << i << endl; // 12345

Konverziók a különböző típusokra:

  • int: stoi
  • long: stol
  • long long: stoll
  • unsigned long: stoul
  • unsigned long long: stoull
  • float: stof
  • double: stod
  • long double: stold

Mi történik,

  • ha a szöveg elején van szám, de van mögötte ,,egyéb'', akkor a számot átkonvertálja
1
2
string s("123 alma");
cout << stoi(s) << endl; // 123
  • ha nem fér bele a tartományba, akkor std::out_of_range kivétel dobódik (kivételkezelés, const és referencia később)
1
2
3
4
5
6
7
try {
  string s1("999999999999999999999999999999");
  cout << stoi(s1) << endl;
}
  catch (const out_of_range& e_out) {
  cout << "out_of_range exception" << endl;
}
  • ha nem lehet konvertálni, akkor std::invalid_argument kivétel dobódik
1
2
3
4
5
6
7
try {
  string s1("alma");
  cout << stoi(s1) << endl;
}
  catch (const invalid_argument& e_inv) {
  cout << "invalid_argument exception" << endl;
}

Otthoni gyakorló feladatok

  1. Írjuk meg az első C++ programot, ami kiírja a képernyőre a "Hello Vilag!" üdvözlést!
    • Írjuk meg a C-s I/O művelettel, majd fordítsuk le és futtassuk!
    • Írjuk meg a C++-os I/O művelettel, majd fordítsuk le és futtassuk!
  2. Nézzük meg mit van, ha elhagyjuk az "std::"-t. A "using namespace std;" segítségével javítsuk a hibát.
  3. Írjuk egy olyan programot, ami bekéri a felhasználó korát (egész), magasságát (valós) és nevét, majd ezt ki is írja a képernyőre.
  4. Írjuk ki hibaüzenetet az error stream-re (cerr), majd nézzük meg mi történik. Hogyan tudjuk "szétválasztani" a cout és cerr kimeneteket a Linux shellben?
  5. Nézzük meg, hogy mi történik, ha a felhasználó túl hosszú inputot ad meg névnek. Valósítsuk meg a 3. feladatot C++-os string segítségével.
  6. Nézzük meg, hogy a C++-os string-et hogyan lehet
    • létrehozni
    • beolvasni, kiírni
    • összehasonlítani
    • hosszát meghatározni
    • összefűzni
    • i-edik karakterét kiolvasni vagy megváltoztatni
    • számot string-gé konvertálni
    • string-et számmá konvertálni
  7. Írjunk egy olyan programot, ami a programunk argumentumait összeadja és kiírja az eredményt a képernyőre.

A feladatsor letölthető itt.

Megoldások az első feladatra: C, C++

Megoldások string kezelésre: C, C++

Otthoni gyakorló feladatok II

  1. Írjunk egy programot, ami kiírja a hét napjait

    • külön sorokba
    • vesszővel elválasztva!
    Megoldás
  2. Írjunk egy programot, ami bekér két egész számot, majd kiírja az összegüket majd egy sorvége jelet a következő formában:

    A {szám1} es {szam2} osszege: {összeg}

    Megoldás
  3. Írjunk egy programot, ami bekéri a felhasználó nevét és kedvenc állatát és kiírja a következő formában:

    1
    "{kedvenc állat}\n{név}\n\n{kedvenc állat}"
    
    Megoldás
  4. Írjunk egy programot, mely egész számokat olvas be amíg nem a 42 értéket adjuk meg! A 42-s érték kivételével minden bevitt értéket írjon is ki a képernyőre!

    Megoldás
  5. Írjunk egy programot, mely egészeket kér be a -1 jelzőértékig (csak ezzel lép ki) s eldönti, hogy páros vagy páratlan-e a szám! Próbáljuk ki a programot negatív páros és páratlan számokkal is!

    Megoldás
  6. Írjunk egy programot, mely kiírja a beolvasott számoknak a kettővel vett maradékát a -1 végjelig!

    Megoldás

Otthoni gyakorló feladatok III

  1. Írjunk programot, mely bekér két stringet és összefűzi azokat úgy, hogy bekérés sorrendjétől függetlenül mindig a hosszabb kerül előre (egyenlő hosszúságnál a bekérés sorrendjében fűzze össze)! Az eredményt írja is ki!

    Megoldás
  2. Írjunk egy programot, mely beolvas egy stringet és egy számot. Írja ki a string elemeit a kapott indextől! Ha az index nem valid, írja ki, az alapértelmezett hiba csatornára, hogy ,,invalid index''!

    Megoldás
  3. A stringhez kapcsolódó referencia oldalak segítségével írjunk olyan programot, mely bekér két stringet és a hosszabban megkeresi a rövidebbet! Ha nem található, írja ki, az alapértelmezett hibacsatornára, hogy "not found"! Ha megtalálta, írja ki a pozíciót ahol kezdődik!

    Megoldás
  4. A referencia oldalak segítségével írjunk olyan programot, mely a legjobboldalabbi 'b' betű pozícióját írja ki egy bekért szövegben! Nézzük meg, mit kapunk, ha nem található 'b' betű a szövegben!

    Megoldás
  5. Írjunk programot, mely kideríti [-100;100] -on, hogy melyik számnak egyezik meg az értéke és a string reprezentáció hossza!

    Megoldás
  6. Írjunk programot, mely bekér 2 stringet és 2 számot (lehetséges értékek: 2,8,10,16)! A program a 2 stringet rendre a 2 bekért szám szerinti számrendszerben vett számként értelmezze és váltsa át azokat tízes számrendszerbeli számmá! (megj.: a konvertáló függvények átnézése a referencia oldalakon!)

    Megoldás

Utolsó frissítés: 2022-09-15 09:40:31