[itk] Számítástechnika kezdőknek

C++ programozás kezdőknek - első lépések

[2016. szeptember 06.] [ christo161 ]

Ez a tananyag azoknak készült, akik még soha életükben nem programoztak, és nem tudják hogyan kezdjék el. Esetleg azoknak is ajánlom, akik már elkezdtek programozni, de valamit nem értenek, valahol elakadtak.
Ez nem egy gyorstalpaló tananyag, inkább a dolgok alaposabb elmagyarázása a tananyag célja, de ha valaki nem szeret sokat olvasni, akkor esetleg megpróbálhatja csak a példaprogramok forráskódját nézegetni, megérteni, kipróbálni.
Aki nem C++ nyelven szeretne később programozni, annak is hasznos lehet ez a tananyag, hiszen többnyire a programozással kapcsolatos alapfogalmakat magyarázza el.
A tananyagban asztali számítógépre (beleértve a laptopokat), parancssorban futó programokat fogunk írni. Pár sorral lejjebb van egy kép, amin láthatjuk, hogy néz ki egy ilyen program. A futó példaprogram a fekete hátterű, fehér szöveget tartalmazó ablakban látható (ez a példaprogram kiír egy szöveget (Hello World!) a parancssorba). A parancssoros programok az átlagos felhasználók számára nem olyan érdekesek mint a grafikus felülettel rendelkező programok, de azért érdemes mégis ilyen programok készítésével kezdeni a programozás tanulását, mert a grafikus felülettel rendelkező programok készítéséhez már nem árt ismerni olyan fogalmakat, mint például a függvény vagy osztály/objektum, a parancssoros programok írása esetén viszont az alapoktól kezdve lehet megtanulni a programozással kapcsolatos fogalmakat.
Ebben a részben még nem kezdünk el programozni, hanem csak összefoglaljuk, hogy milyen módon kezdhetjük el, például mit kell ahhoz telepíteni, hogy egy programkódból működő programot állíthassunk elő.

Ez itt a C++ programozás kezdőknek tananyag legelső része.
Ha valaki esetleg a következő tananyagrészt keresi, itt találja: Az első program

codeblocks_hello_world.png

Ennek a tananyagrésznek a tartalma:

Egyéb tudnivalók:

Előfeltételek?

Aki nem volt jó matekból, az is tanulhat programozni?

Ez az egyik leggyakoribb kérdés a programozással kapcsolatban. Erre azt szoktam mondani, hogy sok program elkészítéséhez nem szükséges haladó matektudás. Például egy olyan program elkészítéséhez, ami egy adatbázis adataiból kilistázza azokat az adatokat, amik megfelelnek a felhasználó által megadott feltételeknek (pl. egy adott felhasználóhoz tartozó összes adat megjelenítése email címre rákeresve). Természetesen vannak olyan részterületei a programozásnak, amik haladó matektudást igényelnek, mint például a 3d grafika, a titkosítás, satöbbi.
Ezen tananyag megértéséhez matekból elég ha valaki nagyjából tudja, hogy mi a különbség a valós és egész számok között, mit jelent az abszolút érték, milyen sorrendben végezzük el az alapvető aritmetikai műveleteket ha nincs bennük zárójel (pl. 3+60/5 esetén a 60/5-öt számítjuk ki előbb, és csak utána adjuk hozzá a 3-hoz), és hasonlók. Jellemzően nem kellenek a programozáshoz szögfüggvények, egyenletek, megoldóképletek, legkisebb közös többszörös, legnagyobb közös osztó és hasonlók.
Az persze elképzelhető, hogy bizonyos tanfolyamokon olyan példaprogramok szerepelnek, amik mondjuk egy másodfokú egyenlet megoldásait számítják ki, de a programozási alapismeretek elmagyarázásához szerintem nem szükségesek ilyen jellegű feladatok, ugyanazokat a dolgokat meg lehet mutatni például olyan feladatokon keresztül is, mint mondjuk egy szövegben a szóközök kicserélése alsóvonalra, vagy mondjuk egy fájlban szereplő számok növekvő sorrendbe rendezése.

Milyen számítógépre, hardverre van szükség?

Nem kell drága számítógépet venni ahhoz, hogy valaki elkezdhessen programozást tanulni. Sőt, jellemzően egy 10 éves számítógép vagy laptop is teljesen tökéletes.
Erős fejlesztői gép csak akkor jön jól, ha valaki több millió kódsorból álló projekteken dolgozik, de ha valaki most kezd programozni, akkor szerintem bőven van ideje egy jobb gépet beszerezni, ha szeretne.
Később majd nem árthat ha valaki nem az otthoni, általános feladatokra használt számítógépét használja fejlesztésre, hanem egy másik számítógépet tart fent a programozásra.

Tanács

A tananyag első részének csupán annyi a célja, hogy egy működő programot készítsünk el, ami kiír egy szöveget a parancssorba. Ennek ellenére annyira azért nem rövid olvasmányok kapcsolódnak a témához. Természetesen jó ha valaki elolvassa őket, de nem kell az itt leírtakat bemagolni, illetve nem kell minden operációs rendszeren minden módszert kipróbálni (mint ahogy az a tananyag első részeiben szerepel), mert ezekkel rengeteg idő el tud menni anélkül, hogy valaki elkezdene programozni tanulni.

Alapvető tudnivalók

Milyen programokat írtak C++-ban?

Fentebb említve volt, hogy ebben a tananyagban parancssoros programokat fogunk írni, de érdemes lehet tudni, hogy mik a lehetőségek, ha valaki a C++ nyelvben gondolkodik hosszútávon.

C++-ban jellemzően asztali számítógépre (beleértve a laptopokat) lehet készíteni ablakos programokat, vagy 2d/3d grafikájú programokat (például játékprogramokat), operációs rendszereket, vagy akár mobiltelefon alkalmazásokat vagy beágyazott rendszerekre készült programokat.

Néhány C++ nyelven írt ablakos program: 3d studio max, Adobe Photoshop, Firefox, Google Chrome, Microsoft Office, Winamp
Néhány C++ nyelven írt 2d/3d grafikájú program: Doom 3, StarCraft

További példák: [1], [2], [3], [4], [5], [6]

Forráskód, fordító, futtatható program

Ahhoz, hogy elkészítsünk egy C++ nyelven írt programot, egyszerű (formázást nem tartalmazó) szöveges fájlba/fájlokba (angolul plain text file) kell írjunk bizonyos kifejezéseket, utasításokat, amik megfelelnek a C++ nyelv szabályrendszerének (szintaxisának). Ezeket a fájlokat nevezzük forrásfájloknak (angolul source file), a tartalmukat pedig forráskódnak (angolul source code), esetleg programkódnak.
A legismertebb plain text fájlok a txt kiterjesztésű/formátumú fájlok, amikkel biztos mindenki találkozott már. A programok forrásfájljai formátumukat tekintve teljesen egyeznek a txt fájlokkal, csak éppen a nevük után lévő kiterjesztés az eltérő, C++ esetén txt helyett cpp, esetleg cxx, c++, cc vagy c, valamint hpp, hxx, h++ vagy h.
A C++ nyelv esetén ezekből a fájlokból egy úgynevezett fordító (angolul compiler) hozza létre a futtatható programot (angolul executable, esetleg binary), vagyis azt a fájlt, amit elindítva használni tudjuk a programot.
A futtatható program használatához nincs szükség a forrásfájlokra és a fordítóra.

A tananyag elején szereplő egyszerű példaprogramoknak csak egyetlen forrásfájlja van, de a bonyolultabb programokat érdemes több fájlba tördelni, hogy könnyebben megtalálhassuk a különböző részfeladatokat elvégző részeit.

error, más néven compile time error: a fordító nem készíti el a futtatható programot (illetve az object fájlokat sem), ha ilyen típusú hiba szerepel a forráskódban. Magyarul fordítási hibának szokták nevezni.
warning: ha csak ilyen hibát tartalmaz a forráskód, a program lefordul, de lehet, hogy hibás működést fog eredményezni, sok esetben javasolt kijavítani az ilyen típusú hibákat is.

Ebben a tananyagban azt a tevékenységet nevezzük programozásnak, amikor valaki egy program forrásfájljait készíti el vagy módosítja, beleértve az ehhez szükséges gondolkodást, tervezést. A programozás hivatalos definíciója: algoritmizálás és adatmodellezés.
Ha valaki egy program forráskódjában például egy hibát javít ki, előfordul, hogy órákig, esetleg napokig kell nézegetnie, tesztelnie a kódot, a végeredmény pedig csak egy sornyi, vagy akár pár szavas módosítás. A programozásba fektetett munka minősége tehát többnyire nem a létrehozott vagy módosított kódsorok számától függ.

A C++ programozás lehetséges módjai

A tananyagban az itt felsoroltakon belül több lehetőség is ismertetve lesz, például több fejlesztői környezet telepítése és használata, vagy a különböző operációs rendszereken a parancssoros fordítás különböző módjai. Nem kell mindegyiket megtanulni, kezdésnek bőven elég ezek közül egyet vagy kettőt kipróbálni.

Fejlesztői környezet

A programozás egyik legkézenfekvőbb módja, ha valamilyen integrált fejlesztői környezetet használunk. Angolul: integrated development environment, rövidítve: IDE. Egy szövegszerkesztőt és sok esetben fordítót is tartalmazó, programozást segítő kényelmi funkciókkal ellátott program.
Például könnyen tudunk vele több forrásfájlból álló programokat fordítani, a programkód különböző típusú elemeit különböző színekkel jeleníti meg (syntax highlight), ha elkezdünk írni valamilyen kifejezést, akkor meg tudja mutatni, hogy milyen lehetséges módokon fejezhetjük be azt (autocomplete, intellisense), sok esetben megmutatja, hogy a programkódunk melyik sora tartalmaz hibát, rendelkezik hibakereső, nyomkövető (debug) funkcióval, satöbbi.

qt_creator_hello_world.png

A C++ programozás tanulásának elkezdéséhez valamilyen fejlesztői környezet használatát ajánlom. Ezeknek az egyszerű példaprogramoknak a kipróbálásához, amik a tananyagban szerepelnek, igazából bármelyik megfelel a lentebb felsoroltak közül.

A C++ nyelven történő fejlesztéshez használt legismertebb fejlesztői környezetek talán a következők:

  • CodeBlocks
  • Qt Creator
  • Microsoft Visual Studio
  • Apple Xcode

Ezek közül a CodeBlocks ingyenes, a Qt Creatornak és a Visual Studionak van ingyenesen használható verziója (amiket community vagy open-source verziónak neveznek), az Apple Xcode pedig az OS X operációs rendszeren ingyenesen telepíthető. A CodeBlocks és Qt Creator több operációs rendszeren is natívan (virtuális gép, emulátor vagy wine használata nélkül) telepíthető.

Természetesen sok más egyéb fejlesztői környezet is alkalmas C++ fejlesztésre, például:

  • CLion
  • Anjuta
  • KDevelop
  • NetBeans
  • Eclipse
  • Dev-C++
  • C++ Builder

Ezek közül a NetBeanst és az Eclipse-t leggyakrabban Java nyelven írt programok fejlesztéséhez szokták használni, illetve a C++ Buildernek létezik ingyenes verziója, a CLionnak pedig talán csak 30 napos kipróbálható próbaverziója van és csak diákok számára ingyenes, de bevallom őszintén, hogy ennek nem néztem utána részletesen. És persze az idők során változhat, hogy melyik fejlesztői környezetben milyen licensz alatt fejleszthetünk C++ nyelven.

A fejlesztői környezetek telepítése Windowson nagyon egyszerű, aki pedig bevállalja, hogy más operációs rendszert használ (pl. Linux, macOS, BSD), általában feltalálja magát legalább annyira, hogy egy program telepítését meg tudja oldani.
Az alapvető használatuk sem bonyolult, ennek ellenére mégis készítettem leírásokat egy-két fejlesztői környezet telepítéséről és alapvető használatáról, melyek itt érhetőek el:

Text editor és parancssoros fordítás

Oly módon is tudunk programozni, hogy az elkészítendő program kódját valamilyen szövegszerkesztővel írjuk meg, a fordítót pedig külön szerezzük be, telepítjük és használjuk.

Fontos: a szövegszerkesztő (angolul text editor) alatt egyszerű szöveges fájlok (angolul plain text file) szerkesztésére alkalmas programot értünk, melybe beletartoznak a programozást segítő funkciókkal ellátott szerkesztők is (angolul code editor). A lényeg, hogy ne dokumentumszerkesztőt (angolul word processor) használjunk, melyekkel formázott szövegfájlokat készíthetünk.

Néhány egyszerű text editor:

  • notepad.exe, más néven jegyzettömb (csak Windows)
  • gedit
  • kate vagy kwrite
  • leafpad

Néhány parancssorban használható text editor:
(ezeket általában Linuxon, esetleg macOS-en használjuk)

  • nano
  • pico
  • joe
  • vi (csak profiknak)

Néhány code editor (programozást segítő funkciókkal ellátott text editor):

  • Visual Studio Code
  • Sublime Text
  • Notepad++ (csak Windows)
  • Geany
  • Emacs (csak profiknak)

Amit ne használjunk programkódok szerkesztéséhez:

  • Microsoft Word
  • WordPad
  • LibreOffice
  • OpenOffice
  • Google Docs

Persze ha valamilyen dokumentációt írunk egy programhoz, mely dokumentáció forráskódokat is tartalmaz, annak az elkészítéséhez nyugodtan használhatunk dokumentumszerkesztőt.

Azt gondolom, hogy aki programozás tanulására adja a fejét, annak nem okoz problémát megnyitni egy letöltött forrásfájlt, vagy létrehozni egy text editorban egy új fájlt, és abba beilleszteni egy valahonnan kimásolt kódrészletet.
A parancssorban történő fordításról viszont készítettem egy leírást, mely itt érhető el:

Fordítás parancssorban (Windows és Linux)

Vannak, akik ezt a módszert ajánlják a fejlesztői környezetek használata helyett. Én azon a véleményen vagyok, hogy mindenképp érdemes tisztában lenni ennek a módszernek a létezésével, és ha valaki komolyabban belemerül a programozás rejtelmeibe, akkor nyilván nem szabad, hogy gondot okozzon neki a parancssorban történő fordítás. Viszont úgy gondolom, hogy első körben bőven jó egy fejlesztői környezet használata is. Vannak olyan munkahelyek, egyetemi kurzusok, tanfolyamok, ahol nem fogadják el a fejlesztői környezetek használatát.

Online fordítók

Mint ahogy azt már fentebb említettem, az online fordítók használatát csak rövidebb forráskódok, kódrészletek kipróbálásához javaslom (például mondjuk ha meg szeretnénk nézni, hogy mi történik, ha C++-ban átkonvertálunk egy valós számot egész számmá, vagy ha egy karakterlánc egyik karakterének értékét megváltoztatjuk).
Több fájlból álló, terjedelmesebb forráskódok kipróbálására az online fordítók jellemzően nem alkalmasak.

cpp_online.png

Az online fordítók használata akkor is jól jöhet, ha például egy olyan számítógépet használunk, ahol nincs jogosultságunk, vagy időnk programokat telepíteni (pl. iskola, munkahely, kávézó).

Néhány online fordító, amivel C++ kódot is lehet fordítani, futtatni:

Egyes oldalakon több különböző C++ fordítót is használhatunk online, és kipróbálhatjuk, hogy mi a különbség közöttük, ha ugyanazt a forráskódot, forráskódrészletet bemásoljuk, és kipróbáljuk különböző fordítókkal is (pl. g++, CLang, MSVC). A tananyagban majd látunk apró példákat erre, például a műveletek változókkal résznél.

Forráskódok megosztása

Ha oda szeretnénk adni, meg szeretnénk mutatni valakinek valamilyen forráskódunkat, kezdőként nem biztos, hogy magától értetődő, hogy mit használjunk.
Ha bemásoljuk fórumokra, vagy valamilyen közösségi oldalra, előfordulhat, hogy nehezen olvashatóan illesztődik be. Vannak persze erre szakosodott fórumok (pl. stackoverflow), ahol egy bejegyzésbe könnyen be lehet ágyazni valamilyen kódrészletet, de ha csak gyorsan át szeretnénk küldeni egy ismerősünknek, ahhoz nem biztos, hogy célszerű bejegyzést írni egy fórumon.
Kép vagy screenshot formájában azért nem jó átküldeni, mert ha esetleg ki akarja próbálni akinek átküldtük, be kell gépelnie.
Átküldhetjük magukat a forrásfájlokat is, de például mobiltelefonon nem olyan magától értetődő, hogyan kell megtekinteni a tartalmukat.

Forráskódok megosztására való például a pastebin.com oldal, ami plain text formátumban tárolja a kódokat, nem törli az egymást követő szóközöket és tabulátorokat, és kódszínezést (syntax highlight) is használ.

Egy forráskód, amivel kipróbálhatjuk:

#include <iostream>
int main(){
	std::cout << "Hello World!\n";
}

Ez a módszer természetesen csak rövid kódrészletek megosztására alkalmas. Több száz forrásfájl tartalmát kényelmetlen lenne így megosztani.
Egy program összes forrásfájljának megosztásához jellemzően a github.com-ot szokták használni.

Forráskód formázott szövegből történő másolása

Előfordulhat, hogy a programkód szövegét egy honlapról, vagy egy formázott szöveges fájlból (pl. Word dokumentum, PDF dokumentum) másoljuk át fejlesztői környezetbe, vagy text editorba, és a bemásolt szöveg díszített idézőjeleket tartalmaz. Ekkor ahhoz, hogy a program működjön, ezeket ki kell cserélnünk hagyományos idézőjel karakterre.

Ez a hagyományos idézőjel: " "
Ez díszített: “ ”
Ez is díszített: „ ”
Ez is: „ “

Sajnos ez a probléma nem csak idézőjelek és aposztrófok esetén jelentkezhet, hanem egyéb karakterek (például szóközök, tabulátorok) esetén is, és igencsak macerás például minden szóközt kicserélni egy hosszú kódban.
Ha valaki ilyen jellegű hibába fut bele, jellemzően először nem fogja érteni, hogy mivel lehet a baj, hiszen amelyik sorban a fordító a hibát jelzi a programkódban, ott látszólag minden rendben van.

Tanács: ha valamilyen forráskódot, kódrészletet írunk, amit egy formázott dokumentumba vagy egy honlapra szeretnénk majd elhelyezni, akkor először lehetőleg valamilyen integrált fejlesztői környezetben, vagy code editorban, vagy text editorban, esetleg online fordítóban, vagy kódmegosztóban tegyük, mert ezek nem használnak például díszített idézőjeleket, vagy egyéb forráskód szempontjából problémás karaktereket. Onnan aztán át lehet másolni dokumentumszerkesztőbe vagy honlapra, viszont ha valamilyen dokumentumszerkesztővel írunk kódot, akkor abban jó eséllyel lesznek a forráskód szempontjából problémás karakterek.

Build automation, makefile

Ha egy program forrásfájljait megosztjuk, az eddig ismeretett módszerek szerint ahhoz, hogy valaki abból futtatható programot tudjon készíteni, le kell töltenie és telepítenie kell azokat a fejlesztői eszközöket, amiket mi is használtunk. Például mondjuk egy integrált fejlesztői környezetet.
Ennek kikerülésére találták ki a makefájlokat, melyek segítségével megoszthatjuk úgy a forrásfájljainkat, hogy egy makefájl futtatásával futtatható programot lehessen készíteni belőlük.

Pl. GNU Make, CMake

Ez viszonylag nagyobb (több száz forrásfájlból álló) programok esetén lehet esedékes, a tananyagban nem lesz szó erről, de hasznos lehet tudni, hogy ilyen is létezik.

Debuggolás

Bár a debuggolással jó eséllyel leghamarabb akkor érdemes foglalkozni, ha már ciklusok és függvények is szerepelnek a programjaink forráskódjában, de azért néhány alapvető debuggolással kapcsolatos tudnivalóról már most szót ejtünk. Később lesz majd egy részletesebb tananyagrész a debuggolással kapcsolatban.

Ha debug (nyomkövető, hibakereső) módban indítunk el egy programot, akkor például lehetőség nyílik arra, hogy amikor a program futása a forráskód egy általunk megjelölt soránál tart (ezt nevezzük breakpointnak), addig ne fusson tovább a program, amíg arra nem utasítjuk, és az adott ponton megvizsgáljuk, hogy a program pontosan milyen adatokból milyen részeredményeket állított elő, és ha észrevesszük, hogy valamelyik részeredmény rossz, akkor megpróbáljuk kitalálni, hogy mitől romlik el, és megpróbáljuk kijavítani a forráskód megfelelő részét.

A program debug módban történő futtatásához viszont szükség van arra, hogy a fordító bizonyos információkat belerakjon az futtatható programba, továbbá ahhoz, hogy megfelelően működjön a debuggolás, a fordító ne optimalizálja a kódot, ezáltal a futtatható program is lassabb lesz, illetve több helyet foglal.
Kereskedelmi forgalomba szánt programok esetén debug információkat tartalmazó programot a felhasználónak ellenjavallt átadni.
Az integrált fejlesztői környezetekben jó eséllyel elég szembetűnő helyen ki lehet választani a debug vagy release fordítási beállításokat (angolul build configuration). Értelemszerűen ha a debugot választjuk ki, akkor a debuggoláshoz szükséges információk belekerülnek a futtatható programba, és a kód nem lesz optimalizálva, ha pedig a release-t, akkor nem kerülnek bele debug információk, illetve be lesz kapcsolva a kód optimalizálása.
Ha parancssorból fordítunk, akkor is meg lehet adni a debuggolásra és az optimalizálásra vonatkozó kapcsolókat, ezekre konkrétan ki is térünk a parancssoros fordításról és a debuggolásról szóló részletesebb tananyagrésznél.

Ha esetleg egyszerre állítunk be kódoptimalizálást és azt, hogy a fordító a futtatható programban debug információkat helyezzen el, akkor a debuggolás jó eséllyel nem fog rendeltetésszerűen működni.

A példaprogramok kipróbálása esetén ez a beállítás jó eséllyel lényegtelen, kivéve ha pont a debuggolást szeretnénk kipróbálni.

Egyéb segédeszközök a C++ programozáshoz

A C++ programozáshoz rengeteg segédeszközt lehet használni, amiket nem fogok felsorolni ebben a tananyagban, de például itt lehet olvasni egy listát ezekről az eszközökről. Egy rövid videó ugyanerről a témáról.

Egyéb tudnivalók

Alacsony- és magas szintű programozási nyelvek

A számítógép nyelve a gépi kód, amit általában 1-esek és 0-k (vagyis kettes számrendszerbeli számok) sorozataként szoktak emlegetni. A számítógép processzora csak a gépi kódú utasításokat tudja végrehajtani, és persze különböző processzortípusonként eltérő gépi kódok léteznek.
Mivel nehéz lenne gépi kódú programokat írni, ezért létrehoztak kényelmesebb, emberközelibb programnyelveket. (Ezeknek a szintjeit nem fogom pontosan kifejteni, csak két szintet említek meg. Részletesebb információ: Andrew S. Tanenbaum Számítógép architektúrák c. könyvében.)
A gépi kódú programozáshoz közelebb álló nyelveket hívjuk assembly nyelveknek, melyek használata esetén a programozó feladata hadverközeli dolgok kezelése (pl. a processzor regiszterei). A mai magas szintű nyelvekkel ellenténben az assembly nyelvekben jellemzőek a (goto-szerű) ugróutasítások is.
Ahhoz, hogy egy adott assembly nyelven írt kódot a számítógép processzora végre tudjon hajtani, először át kell alakítani gépi kóddá. Ezt végzi el az assembler. Különböző processzortípusokhoz eltérő assembly nyelvek léteznek.
Az assemblynél könnyebben tanulható, és hardverfüggetlenebb nyelveket hívjuk magas szintű programozási nyelveknek. Ezek közé tartozik például a C, C++, C#, Java, Visual Basic, Pascal, Javasctipt, Perl, Phyton, Ruby, shell script, bash script, ... stb.
A magas szintű nyelvek létrejöttével természetesen nem szűnt meg teljesen az alacsonyabb szintek létjogosultsága. Noha magas szintű nyelveken könnyebb programozni, az alacsony szintű nyelveken viszont jobban kihasználhatjuk a számítógép hardvere által nyújtott lehetőségeket, és hatékonyabb programokat írhatunk.
A lényegi különbség tehát az alacsony és magas szintű programozási nyelvek között, hogy az alacsony szintű nyelven írt forráskódból csak egy adott architektúrájú számítógépre/eszközre készülhet futtatható program, a magas szintű nyelvekből pedig akár több különböző architektúrájú számítógépre/eszközre is. Azért csak akár, mert a különböző operációs rendszereken futtatható programoknak is eltérő a forráskódja. Emiatt van az, hogy például a Windowsra írt programok Linuxon csak segédprogrammal (Wine) képesek futni.

gepi_kod_assembly_cpp.png

A C, és C++ nyelveket egyaránt szokták a magas szintű, és tévesen az alacsony szintű programozási nyelvek közé sorolni. Valójában magas szintű nyelvek, de alacsony szintű műveleteket, valamint bitstruktúrákat is támogatnak (sok más magas szintű programozási nyelvvel ellentétben).

Természetesen a magas szintű programozási nyelveken írt kódot is át kell alakítani gépi kóddá, ahhoz, hogy a számítógép processzora futtatni tudja, de ennek több módja is létezik, melyeknek természetesen megvannak az előnyei és hátrányai is.

Magas szintű programozási nyelvek futtathatóvá alakításának módjai

  • Pl. C++ esetén a C++ nyelven írt programkódot tartalmazó fájlok (forrásfájlok) alapján egy fordító (compiler) hozza létre a gépi kódú utasításokat tartalmazó fájlokat (a futtatható programot, mely futtatásához a fordítást követően már nincs szükség a fordítóra).
  • Pl. a Perl, Phyton, vagy a (jellemzően Linuxos) shell script, vagy Bash script esetén a forráskód nem kerül lefordításra, nem jönnek létre gépi kódot tartalmazó fájlok a forrásfájlokból, hanem egy értelmező (interpreter) alakítja át a program forráskódját a program futtatásának minden egyes alkalmával gépi kódra, amit az átalakítást követően végre is hajt.
    Ezekhez hasonló a Javascript is, ám az esetében az internetes böngészőkbe van beépítve a Javascript értelmező.
  • Pl. a Java ebből a szempontból a fenti opciók hibridje. A fordítás által keletkező köztes kódot (bájtkódot) egy értelmező (Java Virtual Machine) futtatja.

Megjegyzés: a fent felsoroltak csak néhány szemléltető példa, egy programnyelv ezek közül akár több lehetőséget is támogathat (pl. Java kódból is lehet fordított fájlt készíteni), illetve az idők folyamán változhat a helyzet.

A C++ nyelven írt forrásfájlok gépi kódra történő fordításának lépései:

  • Előfeldolgozás, más néven előfordítás vagy preprocesszálás:
    C++ esetén először egy úgynevezett preprocesszor (előfordító) végez módosításokat a programkód szövegén, például a programkódban elhelyezett, preprocesszornak szóló (# jellel kezdődő) utasítások alapján.
    Ebben a lépésben még nem kezdődik meg a gépi kódra történő átalakítás.
  • Fordítás:
    ezt követően a fordító az egyes fordítási egységekből úgynevezett object fájlokat hoz létre, melyek már gépi kódú utasításokat (úgynevezett tárgykódot) tartalmaznak, de még nem futtathatóak. (Ennek előnye, hogy ha csak egy forrásfájl tartalmát módosítjuk, nem kell az összes forrásfájlt újrafordítani).
  • Linkelés:
    végül az object fájlokat a linker szerkeszti össze futtatható fájllá.

Fordítási egységnek (angolul translation unit) nevezzük annak az eredményét amit a preprocesszor egy forrásfájból a header fájlok bemásolásával állít elő.

Több C++ fordító is létezik (lásd még: [2] [3]), melyeket különböző szervezetek/cégek készítettek, tartanak karban. Talán a 3 legismertebb C++ fordító a g++, a CLang és az msvc.
A különböző fordítók között lehetnek különbségek, előfordulhat, hogy ugyanaz a forráskód más fordítókkal más eredményt produkál, ezért érdemes lehet szabványos C++ kódot írni, illetve tisztában lenni azzal, hogy mik azok a dolgok, amik az egyes rendszereken eltérőek lehetnek (erre használják az implementációfüggő szakkifejezést), valamint hogy mik azok az utasítások/kifejezések amik undefined behaviort (lásd még: [2]) okozhatnak. Ezekről szó lesz majd a tananyag különöbző témáiban.
Minden C++ fordítónak meg kell felelnie a C++ szabvány előírásainak. A C++ szabvány pl. ezeken a linkeken érhető el:

Nem egy könnyű olvasmány, de a C++ nyelv tanulásához érdemes lehet tudni a létezéséről. Vannak egyszerűsített olvasatai, kicsit lentebb megtalálható néhány link.

Néhány megjegyzés:

  • Toolchainnek nevezik együttesen a fordítót, a standard libraryt, a debuggert és egyéb alapvető, fordításhoz használható eszközöket. Egy példa erre a GNU toolchain.
  • A GCC rövidítés (GNU Compiler Collection) egy programcsomag, mely tartalmazza a gcc-t, és a g++-t. A g++ fordítót C++ programkódok fordítására használjuk, a gcc-t pedig C programkódok fordítására.
    Elképzelhető, hogy valahol mégis úgy fogalmaznak, hogy "GCC fordító", de ezalatt nyilvánvalóan C kód esetén a gcc-t, C++ kód esetén pedig a g++-t kell érteni.
  • Különböző processzortípusokhoz különböző fordító készíti el a gépi kódot a forrásfájlokból. Tehát például g++ fordítóból is több létezik, különböző architektúrájú számítógépekhez/eszközökhöz. Pl. az a gépi kód, amit egy x86-os processzortípushoz állítottunk elő, nem fog működni egy ARM processzoros eszközön.
  • Hasonló a helyzet a különböző operációs rendszerek esetén. Pl. egy Windowsos g++ más objectfájlokat hoz létre, mint egy Linuxos g++.
  • Ha a C++ nyelven írt program csak egyetlen forrásfájlból áll, akkor is keletkezik object fájl, amiből szintén a linker hozza létre a futtatható fájlt.
  • Unix-szerű rendszereken az object fájlok formátuma/kiterjesztése .o, Windowsban pedig .obj
  • Ha esetleg olyannal találkoznánk, hogy a.out, az már egy futtatható fájl, nem pedig object fájl. Akkor kapunk a.out (assembly output) elnevezésű fájlt, ha Unix-szerű rendszeren nem adunk meg nevet az indítható állománynak (például a g++ helloworld.cpp parancs esetén).
    Windowsban a.out helyett a.exe jön létre hasonló esetben.
  • A fordító (illetve az értelmező) nem képes egy programkód minden hibáját felismerni. Előfordulhat, hogy noha egy helyes kifejezést írunk a programkódunkba, de ez a kifejezés mégsem azt jelenti, mint amire gondoltunk. Ennek eredményeképp ha a programunk le is fordul, lehet, hogy nem egészen úgy fog működni, mint ahogy elvárnánk.
    Az ilyen hibák felderítése nem könnyű egy több ezer soros kódban, ezért jó ha tisztában vagyunk egy programozási nyelv apróbb részleteivel, illetve hogy pontosan milyen hibákat követhetünk el (erről a témáról több száz oldalas könyvek szólnak (pl. C++ hibaelhárító)).

Nyílt- és zárt forráskódú programok

Ha valakinek odaadjuk a forrásfájljainkat, akkor ha az illető ismeri azt a programozási nyelvet, amiben a forráskódot írtuk, lehetősége nyílik teljesen nyomon követni, hogy mit és hogyan csinál a programunk.
Viszont ha valakinek csak a futtatható programot adjuk oda, akkor csak tippelni tud arra, hogy a programunk nagyjából hogyan működhet. Persze vannak eszközök arra, hogy futtatható programok forráskódját visszafejtsük (ezt hívják angolul reverse engineeringnek), de ez nagyon nehéz feladat. (Debug információkat tartalmazó futtatható program forráskódját könnyebb visszafejteni.)
Vannak olyan programok, amiknek a forráskódját a készítői szándékosan nyilvánosságra hozzák. Ezeket hívják nyílt forráskódú (open-source) szoftvereknek. Ennek például az az előnye, hogy bárki kijavíthat benne hibákat, a javítást "elküldheti" a készítőknek, illetve az, hogy bárki leellenőrízheti, hogy a program pontosan mit csinál, így könnyen kiderülhetne, ha például egy ilyen program a beleegyezésünk nélkül adatokat gyűjtene a számítógépünkről.
Az átlagos felhasználók jó eséllyel többször találkoznak zárt forráskódú programokkal, melyeket angolul proprietary szoftvereknek neveznek.
Olyan is előfordulhat, hogy egy program nyílt forráskódú, de a készítők nem a nyilvánosság számára közrebocsátott forráskódból hozzák létre a futtatható programot, ami a honlapjukról letölthető, és így .

Néhány példa nyílt forráskódú szoftverekre: a Linux operációs rendszerek kernelje (magja), Firefox, Thunderbird, LibreOffice, Gimp, Blender, Audacity, VLC player, FileZilla, Notepad++, Visual Studio Code, Wireshark.
Továbbá: egy lista nyílt forráskódú szoftverekről. Ezek forráskódja általában github.com-on található meg.

A C++ nyelv különböző szabványai

A C++ nyelvnek különböző szabványai tulajdonképpen a nyelv különböző verziói.

cpp_timeline_1.png

cpp_timeline_2.png

képek forrása: modernescpp.com

itk_cpp_evolution.png

kép forrása: CppCon2016, [2]

Az újabb szabvány szerint értelmezett kódokban szerepelhetnek olyan kifejezések, amik a régi szabványban még nem szerepeltek, illetve az is lehet, hogy a régi szabványban valamilyen kifejezés az újabb szabványok szerint mást jelent.
Ez az egyszerű példaprogramok esetén jó eséllyel nem okozhat gondot, később viszont lehet, hogy szükség lesz rá, hogy az intergrált fejlesztői környezetünkben, vagy a paranccssoros fordításnál beállítsuk/jelezzük, hogy pontosan milyen szabvány szerint szeretnénk hogy a kód értelmezve legyen.
A C++11-es és újabb szabványokat összefoglaló néven szokták modern C++-nak nevezni.

Egy részletesebb leírás a C++ nyelv fejlődéséről itt érhető el.

A különböző C++ szabványokban bevezetett fontosabb újdonságokról itt találunk összefoglalókat: C++11, [2], C++14, [2], C++17, C++20
Videók: C++98, C++11, C++14, C++17

C++ libraryk

Egy library más programozók által készített alapvető és hasznos dolgokat tartalmaz, amiket felhasználhatunk a programjaink forráskódjában.
A C++ fordítókhoz mellékelve van egy úgynevezett C++ standard library, amivel önmagában csak parancssoros programokat tudunk készíteni, vannak olyan részei, amik nem parancssoros programok forráskódjában is hasznosak lehetnek.
(A C++ standard library például C# nyelvben a Framework Class Library a megfelelője, Java nyelvben pedig a Java Class Library.)

A C++ fordítókhoz nincs mellékelve ablakos, vagy 2d/3d grafikus programok készítéséhez használható library. Ha ilyen programokat szeretnénk készíteni C++ nyelven, akkor be kell szereznünk valamilyen erre alkalmas libraryt, vagy telepítenünk kell egy olyan fejlesztői környezetet, ami automatikusan telepíti az általunk használni kívánt libraryt/libraryket is.
Ezekről a librarykről egyenként több száz vagy több ezer oldalas tananyagok vannak, meg persze jókat lehet arról vitatkozni, hogy melyik libraryt érdemes használni, így egy ilyen kezdőknek szóló, alapfogalmakat tárgyaló tananyagban ezekről nem lesz szó, de azért legyen megemlítve néhány példa.

Néhány ablakos programok C++ nyelven történő készítéséhez használható library:
FLTK, Qt, GTK+, Tcl/Tk, wxWidgets, MFC, Windows Forms, UWP

Néhány 2d/3d grafikus programok C++ nyelven történő készítéséhez használható library:
SDL, SFML, imgui, OpenGL, Vulkan, DirectX

Egyéb C++ libraryk: [1], [2]
Az egyik legismertebb C++ library a boost, amit haladó C++ programozók gyakran használnak a standard library kiegészítéseként, illetve idővel a boostból sok dolog átkerült a standard librarybe is.

A framework, api, sdk hasonló fogalmak, mint a library: programok készítéséhez felhasználható alapvető és hasznos dolgok gyűjteménye, viszont a köztük lévő pontos különbségről ebben a tananyagban nem lesz szó.
Például a Qt valójában nem library, hanem framework.

Egyéb C++ tananyagok

Olyan tananyagok, amikből nulla programozás tudással el lehet kezdeni C++-t tanulni, és az egyes tananyagrészek egymásra épülnek:

Kiragadott tananyagrészeket, megoldásokat tartalmazó oldalak, blogok:

Referenciaoldalak:

C++ könyvek

Rengeteg könyv létezik a C++ nyelvről. Ezek nagy része olyan olvasóknak szól, akik már tudnak programozni, valamennyire ismerik a C++ nyelvet, pl. tipikusan ilyen a Hatékony C++ c. könyv. Én itt most olyan könyveket ajánlok, amikből az alapoktól kezdve, nagyjából nulla programozás tudással el lehet kezdeni C++-t tanulni.

Angol nyelvű:

Az utóbbit azoknak javaslom, akik komolyan gondolják a C++ nyelv tanulását, a jövőben is a C++ nyelvvel szeretnének foglalkozni.

Magyar nyelvű:

Magyary Gyula: Emelt ​szintű informatika érettségi - Programozás C++ és C# nyelven

Bevallom őszintén, hogy nem nagyon ismerek kezdőknek való uptodate magyar C++ könyveket, ez a példa talán nem a legjobb, mert C# nyelvvel is foglalkozik, de annyi biztos, hogy kezdőknek íródott, nem pedig olyan olvasóknak, akik valamennyire már értenek a programozáshoz.

Kódolási minták, konvenciók

Angolul coding standard, coding style guide, design patterns, core guidelines, esetleg clean code kulcsszavakkal kereshetünk rá a témára. Ezeket akkor érdemes olvasgatni, ha már egy adott programozási nyelvet viszonylag jól ismerünk, és arra vonatkozó tippeket szeretnénk olvasni, hogy hogyan írhatunk hatékonyabb, átláthatóbb, biztonságosabb kódot. Előfordulhat, hogy egyes nagyobb projektekben vagy nagyobb cégeknél ezeknek vagy ezek egy részének a betartása kötelező.

Néhány példa a C++ nyelv esetén:

Videók:

Könyvek:

  • C++ Coding Standards: 101 Rules, Guidelines, and Best Practices
  • Modern C++ Design: Generic Programming and Design Patterns Applied
  • Exceptional C++ Style: 40 New Engineering Puzzles, Programming Problems, and Solutions

Egyéb gondolatok a C++ nyelvről

A C++ egy különleges és sokoldalú programozási nyelv. Rengeteget lehet vitatkozni arról, hogy milyen nyelv is valójában (lásd: [1], [2], [3]), és rengeteg tévhit kapcsolódik a nyelvhez. Bár az emberek általában nem szeretnek nagyon utánajárni ezeknek a dolgoknak, ha esetleg mégis, akkor...

...a teljesség igénye nélkül.

Angolul a language-lawyer jelzőt szokták használni arra, ha valaki kíváncsi, hogy az egyik programozási nyelvben miért így van ez, miért úgy van az, és miért nem úgy mint a másik nyelvben. Noha ez szerintem is nagyon érdekes téma, azért érdemes nem megfeledkezni arról, hogy ezzel bizony nagyon el tud menni az idő, anélkül, hogy megtanulnánk hogy kell használni az adott nyelvet.

Következő tananyagrész: Az első program

A bejegyzés trackback címe:

https://itkezdoknek.blog.hu/api/trackback/id/tr507746690

Kommentek:

A hozzászólások a vonatkozó jogszabályok  értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai  üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a  Felhasználási feltételekben és az adatvédelmi tájékoztatóban.

ProgSuli 2019.03.29. 14:38:15

Gratulálok, nagyon korrekt és alapos leírás!

Roland Hompóth 2019.10.16. 23:37:50

Ennek segítségével végre könnyen el lehet indulni a C++ programozás világában. Ezer köszönet a blog írójának.
süti beállítások módosítása