c++

Változók definiálása, kezdőértékek

Amikor egy változót definiálunk (létrehozunk), jelezzük a fordítóak, hogy a számítógép memóriájában szeretnénk lefoglalni valamennyi helyet, azért, hogy egy előre meghatározott típusú (szám, szöveg, karakter, logikai) értéket tárolhassunk, mely értéket a program futása során többször felhasználhatunk, megváltoztathatunk.
(A számítógép merevlemezén többnyire a későbbi használat céljából tárolunk adatokat, a feldolgozás alatt lévő adatokat a gyorsabb kezelhetőség érdekében a számítógép memóriájában tároljuk.)
Egy változó egyszerre csak egy érték tárolására alkalmas. Egyidejűleg több érték tárolásához például tömböket használhatunk.

A változók értékét tetszőleges alkalommal megváltoztathatjuk, akár egy általunk (a program forráskódjában) megadott konkrét értékre (az ilyen értékeket literáloknak nevezzük), akár egy másik (hasonló típusú) változó értékére, akár egy olyan értékre, amit a felhasználó adhat majd meg a program futása közben (jelen feladatokban parancssorban történő begépeléssel), akár egy függvény által visszaadott értékre, akár egy fájlból beolvasott értékre, vagy valamilyen összetett kifejezés értékére

Egy változó definiálása például így néz ki:

int b;

Vagyis egyszerűen leírjuk a típusát, a nevét, és nem felejtünk el az utasítás végére pontosvesszőt tenni. Jelen példa esetén a típus int (egész szám), a név pedig b.

C++-ban nem változtathatjuk meg egy változó típusát. Vagyis ha definiáltunk egy egész szám típusú változót, abban nem tárolhatunk például szöveget.
Ez ugyan kényelmetlennek tűnhet más programnyelvekkel szemben, viszont C++-ban sokkal gyorsabban működő programokat írhatunk (ha jól használjuk a nyelvi elemeket).

Ügyeljünk arra, hogy C++-ban egy változót mindig definiálni kell a használata előtt, és egy adott blokkon belül nem lehet két változót azonos névvel definiálni.

A változók neve betűkből, számokból, és alsóvonalból ( _ ) állhat, nem kezdődhet számmal, nem tartalmazhat szóközt, valamint nem egyezhet meg a C++ nyelv kulcsszavaival (pl. if, while, double, class, typedef,..satöbbi).
A változók nevében számít a kis- és nagybetű (case sensitivity). Például az int b; és int B; utasítások különböző változót definiálnak. Egyes fordítók csak a nevek első 32 karakterét veszik figyelembe.
Ezek a megkötések nem csak a változók neveire vonatkoznak, hanem tömbök, függvények, osztályok, objektumok és egyéb dolgok neveire is. Az elnevezéseket összefoglaló néven azonosítóknak nevezzük a programozási nyelvekben.

A C++ adattípusok csoportosítása

Az adattípus meghatározza a tárolásra használt memóriaterület (változó) bitjeinek darabszámát és értelmezését. Az adattípus hatással van az adatok feldolgozására is, hisz a C++ nyelv erősen típusos, így nagyon sok mindent ellenőriz a fordítóprogram.

A C++ adattípusait (röviden típusait) sokféle módon csoportosíthatjuk. Szerepeljen itt most a Microsoft VC++ nyelvben is alkalmazott felosztás . E szerint vannak alaptípusaink, amelyek egy-egy érték (egész szám, karakter, valós szám) tárolására képesek. Vannak azonban származtatott típusaink is, amelyek valamilyen módon az alaptípusokra épülve bonyolultabb, akár több értéket is tároló adatstruktúrák kialakítását teszik lehetővé.

Típusmódosítók

C++ nyelvben az egész alaptípusok jelentését típusmódosítókkal pontosíthatjuk. A signed/unsigned módosítópárral a tárolt bitek előjeles vagy előjel nélküli értelmezését írhatjuk elő. A short/long párral pedig a tárolási méretet rögzíthetjük 16 illetve 32 bitre. A legtöbb C++ fordító támogatja a 64-bites tárolást előíró long long módosító használatát, ezért könyvünkben ezt is tárgyaljuk. A típusmódosítók önmagukban típuselőírásként is használhatók. Az alábbiakban összefoglaltuk a lehetséges típuselőírá­sokat. Az előírások soronként azonos típusokat jelölnek.

char signed char    
short int short signed short int signed sh o rt
int signed signed int  
long int long signed long int signed long
long long int long long signed long long int signed long long
unsigned char      
unsigned short int unsigned short    
unsigned int unsigned    
unsigned long int unsigned long    
unsigned long long int unsigned long long    

Inicalizálás

Inicializálásnak nevezzük, ha a változók definiálásakor megadjuk a kezdőértéküket is:

int b = 0;
float f = -2.17;
char c = 'y';
string s = "szoveg";

Egy utasításban akár több azonos típusú változót is definiálhatunk:

int a=-2, b, c=7;

Értékadások és műveletek 

Természetesen ugyanazokat a kifejezéseket használhatjuk, amikor egy változónak kezdőértéket adunk, illetve amikor később megváltoztatjuk az értékét.

Például így adhatunk értéket szám alapú (int, float, és hasonló típusú) változóknak:

b = -3;
a = b;
a = b = c;

c(4); //ugyanaz, mint c = 4;
/* A tananyag későbbi részeiben előfordulhat, hogy egyes dolgokat, csak így adhatunk értékül.
Pl. az a = nullptr kifejezés helyett az a(nullptr) kifejezés az elfogadott .*/

a = b = c esetén a és b változók értéke c változó értékével lesz egyenlő. Az értékadások jobbról balra lesznek kiértékelve, vagyis először b = c értékelődik ki, ezt követően a = b

a = b * -c; //ebben az utasításban a csillag karakter szorzásjel
a += b; //jelentése: a = a + b;

Az összeadáson kívül egyéb műveletek is rövidíthetők ily módon (pl: -=, *=, /=, %=), viszont ügyeljünk arra, hogy a kifejezést alkotó két műveleti jel közé ne tegyünk szóközt, különben a program nem fog lefordulni.

++c; //vagy c++; /*1-el növeljük a c változó értékét*/
--c; //vagy c--; /*1-el csökkenjük a c változó értékét*/
b = ++c; /*c változó értékét 1-el növeljük, és ezt értékül adjuk b változónak*/
b = c++; /*b változónak c meg nem növelt értékét adjuk értékül, majd 1-el növeljük c változó értékét*/

Egy változó értékének 1-el való megnövelését inkrementálásnak, csökkentését pedig dekrementálásnak nevezzük (magyarul léptetésnek szokták fordítani).
Fontos: a c++ vagy ++c kifejezések jelentése nem c + 1, hanem c = c + 1.

/* Teszt */
int a, b;
int i = 1, j = 1;

a = i++; //a értéke 1 lesz, majd i értéke 2 lesz
b = ++j; //j értéke 2 lesz, majd b értéke 2 lesz

/* kiíratjuk az a és b változók értékét (szóközzel elválasztva): */
std::cout << a << " " << b;

Így könnyű megjegyezni: ha a léptető operátor a változónév előtt szerepel, akkor az értékének az összetett kifejezésben való felhasználása előtt meg lesz növelve az értéke, ha pedig utána szerepel, akkor csak azt követően.

Amikor char (karakter) típusú változónak adunk értéket (a kezdőértéket is beleértve), akkor idézőjelek helyett aposztrófokat használunk:

c = '3';
c = '\n';

Ha aposztrófok helyett mégis idézőjelet használunk karakter típusú változó értékének megadásakor, a program nem fog lefordulni.

Ha esetleg pont egy aposztrófot szeretnénk értékül adni egy karakter típusú változónak, akkor azt escape karakterrel tehetjük meg:

c = '\'';

A ‘\” kifejezés végén nem egy idézőjel, hanem két aposztróf szerepel.

Idézőjelek között adjuk meg azonban a string (karakterlánc) típusú változók értékét. Az értékként megadható szövegben speciális karakterek is szerepelhetnek.

s = "tobb szobol es\ntobb sorbol allo szoveg";

Két string típusú változó értékét összefűzhetjük (ezt a műveletet konkatenációnak hívjuk):

s1 = "egyik szoveg";
s2 = "masik szoveg";
s3 = s1 + " " + s2;

String típusú változók bizonyos szakaszait is felhasználhatjuk:

s4 = s1.substr(0,4) + ", " + s2.substr(0,4);

Például az s1.substr(0,4) kifejezésben a substr tagfüggvény visszaadja az s1-ben tárolt szöveg első karakterétől az ötödik karakteréig tartó részét (értelemszerűen a 0 paraméter jelenti az első karaktert, a 4 pedig az ötödiket). Így ezen kifejezés értéke jelen példa esetén “egyik” lesz. Ennek alapján könnyen kikövetkeztethető, hogy az s4 változó értékéül adott kifejezés értéke “egyik, masik” lesz.

Ha csak egyetlen karaktert szeretnénk felhasználni egy string értékéből, akkor például a valtozonev[0] kifejezést használhatjuk. Itt a 0 szintén a legelső karaktert jelenti, és például a 12 a tizenharmadikat.

string s5 = "tetszoleges";
cout << "s5 elso karaktere: " << s5[0] << endl;
s5[1] = '3';
s5[s5.length()-1] = '5';
cout << "s5 modositott erteke: " + s5 << endl;

Egy string értékébe be is szúrhatunk valamilyen szöveg típusú értéket, például:

string s6 = "aaa";
s6.insert( 2, "bb"); //ekkor s6 erteke erre modosul: aabba

Adott szövegrész törlésével is egybeköthetjük a beszúrást (felülírás), ekkor meg kell adni, hogy mettől meddig töröljük az aktuális érték egy részletét. A 0 szintén az első karaktert jelenti.

string s7 = "szoveg";
s7.replace( 1, 4, "qwert" ); //s7 erteke ezt kovetoen: sqwertg

Hasonlóan működik az erase tagfüggvény is. Értelemszerűen csak két paramétert vár, hogy mettől meddig töröljük az adott string típusú változó értékét.

A string típusú változók méretét a length() vagy size() tagfüggvénnyel adhatjuk meg.
Például a cout << “s4 karaktereinek szama: ” << s4.size() << endl; utasítással kiíratjuk az s4 változóban tárolt érték karaktereinek számát.
Illetve a length() vagy size() tagfüggvény által visszaadott értéket valamilyen szám típusú változónak értékül is adhatjuk. Például:

int s4_merete = s4.size();

A string típusú változók további tagfüggvényei, és a használatukat bemutató példák például ezen az oldalon találhatóak.

A string típusú változók használatához szükség lehet a program elején elhelyezett #include <string> utasításra. Bizonyos fordítók használata esetén előfordulhat, hogy a program enélkül az utasítás nélkül is lefordul, és ugyanúgy működik, mintha az utasítás szerepelne a program elején. Ki lehet próbálni, hogy mi történik, ha lehagyjuk, de mindenesetre a végleges programjainkban biztonság kedvéért érdemes szerepelnie (pl. előfordulhat, hogy odaadjuk valakinek a forráskódot, aki más fordítóval készíti el a futtatható állományt).

Változók értékeinek kiíratása (parancssorba)

Változók értékeit például cout-tal írathatjuk ki a parancssorba. Bármilyen értéket kiírathatunk, amit egy változóban tárolni tudunk, de bizonyos speciális karaktereknek parancssorban nem biztos, hogy értelmezve lesz a jelentésük (pl. függőleges tabulátor). Olyan esettel is találkozunk majd, hogy nem az az érték íródik ki, amit a programkódban látunk (pl. ha kiíratjuk egy logikai változó értékét, akkor nem true vagy false íródik ki, hanem jó eséllyel 1 vagy 0).
Ha valamilyen értéket csak egyszer használunk a programunkban, akkor természetesen megfontolható, hogy eltároljuk-e egy változóba, vagy rögtön kiírassuk/feldolgozzuk.

cout << "b valtozo erteke: " << b << ", b valtozo abszoluterteke: " << abs(b) << endl;

Természetesen ha nem csak gyakorlásképp írunk programokat, hanem a programunkat valóban használni fogja rajtunk kívül valaki, akkor nem szükséges az egyes változók pontos neveit közölni a felhasználóval.

Változók értékeinek bekérése a felhasználótól (parancssorban)

Ha azt szeretnénk, hogy a program a felhasználótól kérje be egy adott változó értékét, akkor például a cin utasítást használhatjuk:

cin >> b;

Érdemes felhívni a felhasználó figyelmét arra, hogy éppen milyen típusú érték megadását várja el a program, így minden bekérés előtt cout segítségével kiírathatunk egy erre vonatkozó szöveget.
Amikor majd valaki futtatja a programot, és a program eljut egy bekérést tartalmazó utasításig, akkor az illető egy, a lentebbi képen láthatóhoz hasonló parancssoros ablakban írhatja be az értékeket, és szokás szerint az enter billentyű megnyomásával fejezheti be egy adott érték beírását. Természetesen ekkor nem kell idézőjelek vagy aposztrófok közé tenni a begépelt szöveget.

Egyszerre több változó értékét is bekérhetjük egy utasításban. A program futtatásakor ezt több egymás utáni bekérésnek fogjuk érzékelni. Ennek a nyilvánvaló hátránya, hogy a bekérések közé nem tudunk egyéb utasításokat beilleszteni (például kiírásokat arra vonatkozóan, hogy milyen érték megadását várja el a program).

cin >> a >> b;

Konstansok (állandók)

Ha olyan értékeket szeretnénk tárolni, melyeket nem szeretnénk a program futása során megváltoztatni, akkor erre a célra a konstansokat érdemes használni.
Konstansokat hasonlóan definiálhatunk mint változókat.

const int b2 = 123;
const char c = 'a';

Ne felejtsünk el (kezdő)értéket adni nekik, különben a program nem fog lefordulni.

/* Hibás kód: */
const float d; //kezdőérték megadásának hiánya fordítási hibát okoz

továbbiak erről a témáról>

Matematikai függvények

Amennyiben a fenti alapműveleteken túlmenően további matematikai műveletekre is szükségünk van, a szabványos C++ könyvtár matematikai függvényeit kell használnunk. A függvények eléréséhez a cmath deklarációs állományt szükséges beépíteni a programunkba.. A könyvtár minden függvényt három változatban bocsát rendelkezésünkre, a három lebegőpontos típusnak (floatdoublelong double) megfelelően.

Példaként tekintsük a mindenki által jól ismert egyismeretlenes, másodfokú egyenlet megoldóképletét, ahol ab és c az egyenlet együtthatói!

   
Másodfokú egyenlet megoldóképlete

A megoldóképlet C++ programban:

#include <iostream>
#include <cmath>
using namespace std;
 
int main() 
{
    double a = 1, b = -5, c =6, x1, x2;
    x1 = (-b + sqrt(b*b-4*a*c))/(2*a);
    x2 = (-b - sqrt(b*b-4*a*c))/(2*a);
    cout << x1 << endl;
    cout << x2 << endl;

Néhány gyakran használt matematikai függvény

Használat Típusa Függvény Include fájl
abszolút érték képzése valós fabs(valós x) cmath
abszolút érték képzése egész abs(egész x) cstdlib
szög (radián) koszinusza valós cos(valós x) cmath
szög (radián) szinusza valós sin(valós x) cmath
szög (radián) tangense valós tan(valós x) cmath
az argumentum arkusz koszinusza (radián) valós acos(valós x) cmath
az argumentum arkusz szinusza (radián) valós asin(valós x) cmath
az argumentum arkusz tangense (radián) valós atan(valós x) cmath
az y/x arkusz tangense (radián) valós atan(valós x, valós y) cmath
természetes alapú logaritmus valós log(valós x) cmath
tízes alapú logaritmus valós log10(valós x) cmath
ex   valós exp(valós x) cmath
hatványozás (xy) valós pow(valós x, valós y) cmath
négyzetgyök valós sqrt(valós x) cmath
véletlen szám 0 és RAND_MAX között valós int rand(void) cstdlib
π értéke valós 4.0*atan(1.0) cmath

Ahol a valós típus a floatdouble és a long double típusok egyikét jelöli, míg az egész az int és long típusok valamelyikét.

Verified by MonsterInsights