Konzol alkalmazás készítése; szöveg, szám, szám értékű kifejezés kiírása, szöveg, szám beolvasása, értékadás, beolvasott adat ellenőrzése; C++ elemek: int, double, bool, char és string, kapcsolódó operátorok, if else
{esszé}
Adja meg az alábbi, adatokra vonatkozó fogalmak jelentését egy-egy mondatban!
Írja le a C++ elágazás utasítás szintaxisát!
{/esszé}
A C++ nyelven készült konzol alkalmazás szerkezete madártávlatból szemlélve az alábbi. Figyeljük meg a Helló világ! programot!
C++ forráskód | megjegyzés |
|---|---|
#include <iostream>
using namespace std;
int main()
{
cout << "Hello world!" << endl;
return 0;
}
| ← a standard C-n túli I/O-függvényekre hivatkozás kedvéért ← az std (standard) névtér elemeinek könnyebb eléréséért ← a fő (az elsőként induló) program ← utasításblokkjának kezdete ← a "Hello world!" szöveg kiírása, majd soremelés ← kilépés 0-val a főprogramból, amely most mint függvény a 0 értéket adja vissza ← utasításblokk vége |
Az std névtér szerepének kiderítésére próbáljuk ki az alábbi programot is!
C++ forráskód | megjegyzés |
|---|---|
#include <iostream>
//using namespace std;
int main()
{
std::cout << "Hello world!" << std::endl;
return 0;
}
| . . ← lekommentezve a névtér kijelölést . . . ← a névtér-hivatkozást egyedileg megadva . . . |
A fenti példát némileg általánosítva lássuk az egyetlen függvényből álló C++ program struktúráját!
C++ forráskód | megjegyzés |
|---|---|
#include <iostream>
using namespace std;
típ main()
{
…
…
return fvÉrték;
}
| . . . ← a main függvény feje; eredményének típusa: típ . ← lokális adatdeklarációk (ha vannak) ← a függvénytörzs végrehajtható utasításai . ← megálláskor fvÉrtéket ad vissza eredményként, amelynek típusa típ . . |
A típ szokás szerint int, azaz egész szám típus.
Az alábbi animáció bemutatja a konzolalkalmazások készítésével kapcsolatos legfőbb tudnivalókat.
int – egész szám
float, double – valós
char – karakter (egyetlen jel)
string – szöveg (karakterlánc)
bool – logikai
típ adatazonosító;
Az adatazonosító nevű adatnak, helyet foglalunk a memóriában. A típ típusnak megfelelő mennyiségű területet kap, és a típ által meghatározott műveletekkel lesz manipulálható.
változó = kifejezés; //típusegyezés!!!
A kifejezés kiértékelésre kerül, és a kapott érték a változóba másolódik.
cin >> változó; //változó←konzol; konzol=billentyűzet
cin : Consol INput; a cin egy karakterekből álló ún. inputfolyam, amely a consol nevű berendezésről (vagyis a billentyűzetről) jön; a következő eleme a változóba konvertálódik; ha a változó szám típusú, akkor az elem (ha lehetséges) bináris számként kerül a változóba, ha szöveg típusú, akkor a következő szóközig tartó jelsorozat kerül a változóba.
cout << kifejezés; //konzol←kifejezés; konzol=képernyő
cout : Consol OUTput; a cout egy karakterekből álló ún. outputfolyam, amely a consol nevű berendezésre (vagyis a képernyőre) kerül; a következő eleme a kifejezés értékéből konvertálódik stringgé.
return egész-kifejezés; //kilépés a (fő/al)programból
exit(egész-kifejezés); //kilépés a programból
Az aktív alprogram végrehajtása megszakad. Ha az alprogram a main() függvény, akkor a program megáll. Az operációs rendszer számára hozzáférhető az egész-kifejezés értéke. A két utasítás között nincs lényegi különbség, ha a main() függvényben használjuk.
if (logikai-kifejezés)
{
… az igaz-ág utasításai …
}
else
{
… a hamis-ág utasításai …
}
A hamis-ág elhagyható.
A logikai kifejezés tartalmazhat – többek közt – relációjeleket (<, <=, ==, >=, >, !=; az utóbbi a nem egyenlő), logikai műveleti jeleket (! – tagadás, && – és, || – vagy).
A logikai-kifejezés kiértékelődik, majd annak igaz értéke esetén az igaz-ág utasításaira kerül a vezérlés, hamis értéke esetén pedig a hamis-ág utasításaira kerül a vezérlés. Ha nincs hamis-ág, akkor a logikai-kifejezés hamis értékekor a végrehajtás az if utasítás utáni, azaz az igaz-ág utáni utasításnál folytatódik.
Az alábbi animáció bemutatja az elágazások használatát és a kódolásukkal kapcsolatos legfőbb tudnivalókat.
A programnak egy pozitív egész számot kell beírni! Ha nem pozitív egész számot kapott, akkor jelezzen hibát, és álljon meg. Helyes szám beolvasása után írja is ki a beolvasott számot a képernyőre!
Több lépésben fogjuk megoldani a feladatot.
Bemenet
Szám:Egész
Kimenet
Szám:Egész
Előfeltétel
–
Utófeltétel
Szám>0 → cout=Szám és
Szám≤0 → cout="Hibás szám!"
A specifikációhoz: az utófeltételben két implikáció (→) szerepel logikai és művelettel összekapcsolva. Olvassuk és értelmezzük ekképpen: ha a Szám pozitív, akkor a konzol outputra a Szám érteke kerüljön, ha a Szám 0 vagy negatív, akkor a konzul outputra a »Hibás szám!« szöveg!
Ezzel a specifikációval az a baj, hogy nincs összhang a kimenet és az utófeltétel között: a kimeneten egyetlen számról esik szó, az utófeltételben egy szöveges adatról is.
Az nem baj, de – a későbbiekben tapasztalni fogjuk, hogy – nem szokás specifikálni a képernyőn megjelenő dolgokat, pláne egy programozási nyelv szókincsét felhasználva. A megjelenés mikéntjét nem tartjuk fontosnak, nem tartjuk specifikálandónak. Általában feltesszük, hogy a kimenet minden adata valahogy megjelenik az outputon (általában a képernyőn).
Bemenet
Szám:Egész
Kimenet
Üzenet: Szöveg
Előfeltétel
–
Utófeltétel
Szám>0 → Üzenet=Szöveg(Szám) és
Szám≤0 → Üzenet="Hibás szám!"
A specifikációhoz: a Szöveg függvény egy előre definiáltnak feltételezett konverziós függvény (Egész→Szöveg).
A PozitívSzám feladat algoritmusa, struktogrammal.Ezzel az algoritmussal az a probléma, hogy tartalmaz a későbbiekben nem algoritmizálandó részletkérdéseket is. Sem a beolvasást, sem a kiírást nem tartjuk az algoritmizálás szempontjából fontosnak, ezért később elhagyjuk. Folytassuk a kódolással!
Az elkövetkezőkben az egyébként szokásos bevezető kommentsorokat nem tüntetjük föl.
#include <iostream>
using namespace std;
int main()
{
int Szam;
string Uzenet;
cout << "Kérem a pozitív számot!"; cin >> Szam;
if (Szam>0)
{
Uzenet=itoa(Szam);
}
else
{
Uzenet="Hibás szám!";
}
cout << Uzenet;
return 0;
}
A kódoláshoz: látható, hogy a beolvasás szertartása két dolgot jelent. Egyrészt egy kérdés szövegének kiírását (cout << "Kérem a …), másrészt a tényleges beolvasást (cin >> Szam). A fenti kód hibája, hogy az itoa (integer to alfa) konverziós függvény nem tartozik a C++ standard implementációjához, így gyakran a fordítóprogram szintaktikus hibát jelez. Megjegyezzük, hogy ezt a hiányosságot a későbbi gyakorlatok egyikén kiküszöböljük, és megírjuk a saját változatunkat.
Bemenet
Szám:Egész
Kimenet
Szám:Egész
Előfeltétel
Szám>0
Utófeltétel
Szám’=Szám
A furcsaság annyi, hogy a be- és a kimeneten ugyanaz az adat jelenik meg. Ha belegondolunk a feladatba, ez természetes: ki kell írni a beolvasott adatot. Ha tehát nem kell a specifikációban a kiírással sem törődni, akkor világos, hogy ez esetben a kimenet nem más, mint a bemenet. Viszont az utófeltételben ugyanaz az adat bemeneti és kimeneti értéke is előfordul. Ezt a két pillanatbeli értéket meg kell tudnunk különböztetni. Erre használjuk majd az aposztrófot, mégpedig a kimeneti érték mellé biggyesztve.
Az előfeltétel tartalmazza azt az extra elvárást, amelyet a feladat szövege megfogalmaz, amely teljesüléséhez köthető a lényegi számítás. Megállapodunk abban, hogy a kódoláskor intézendő el:
Algoritmizálandó valójában nincs is: hiszen a feladat csak egy beolvasást és egy kiírást ír elő, a köztük lévő lényegi transzformáció most nem létezik.
#include <iostream>
#include <windows.h> //az exit-hez szükséges
using namespace std;
int main()
{
int Szam;
cout << "Kérem a pozitív számot!"; cin >> Szam;
if (Szam<=0)
{
cout << "Hibás szám!" << endl;
exit(1);
}
cout << "Szám:" << Szam << endl;
return 0;
}
A kódoláshoz: a beolvasás szertartása továbbiakkal bővült: az előfeltétel teljesülésének ellenőrzésével és a hiba esetén végrehajtandó tevékenységgel. A kiírásnál is megjelent egy újdonság: a kiírandót kísérő szöveg (cout << "Szám:" ).
Még ez sem igazán tetszetős megoldás, mert a programnak két végpontja lett: az egyik a hibás esethez, a másik a normál esethez tartozik. Ez nem szerencsés. Hogy lehetne ezt elkerülni? Válasz: kétirányú elágazással, valamint a megállási kódot tartalmazó segédváltozó bevezetésével és használatával.
Érdemes egy konvenciót is megszokni, követni: a normál, azaz problémamentes megálláshoz a 0 megállási érték tartozzék, a hibásakhoz 0-tól különböző.
#include <iostream>
using namespace std;
int main()
{
int Szam; //a specifikációból
int megall;//a kilépési kód
cout << "Kérem a pozitív számot!"; cin >> Szam;
if (Szam<=0)
{
cout << "Hibas szam!";
megall=1;
}
else
{
cout << "A szám:" << Szam << endl;
megall=0;
}
return megall;
}
Kódoláshoz továbbiak:
Képernyőkép: a PozitívSzám feladat programja futás közben.ezen segíthetünk az alábbi függvény elhelyezésével (még az első kiírás előtti pontra): setlocale(LC_ALL,"hun").
A programban adott a licit alsó értéke, ennél kevesebbet nem lehet ajánlani. Olvassa be a licitet! Amennyiben a licit alsó értékénél kisebbet adott meg, akkor jelezze a hibát és lépjen ki, különben írja ki a beolvasott licit értéket!
Bemenet
Licit:Egész
[Konstans LicitAlsó:Egész=10]
Kimenet
Licit:Egész
Előfeltétel
LicitAlsó≤Licit
Utófeltétel
Licit’= Licit
A specifikációhoz: az algoritmushoz bementi funkciójú, ámde ténylegesen be nem olvasandó a LicitAlsó adat, ezért jelenik meg a specifikáció bemeneti részében amolyan megjegyzés gyanánt a Konstans megjelöléssel.
Algoritmus valójában nincs is: hiszen a program csak egy beolvasást és egy kiírást ír elő.
A kódolás az előbbiek után pofonegyszerű, hiszen a Szám helyett a Licit változót kell következetesen használni. Egyetlen újdonságot a LicitAlsó konstans jelenti.
#include <iostream>
using namespace std;
int main()
{
int Licit; //a specifikációból
const int LicitAlso=10; //a specifikációból
int megall; //a kilépési kód
cout << "Kérem a licitet!"; cin >> Licit;
if (Licit<LicitAlso)
{
cout << "Hibás licit!";
megall=1;
}
else
{
cout << "A licit:" << Licit << endl;
megall=0;
}
return megall;
}
Mennyi pénzt költhet el szórakozásra? Elhatározza, hogy ha 5000 Ft-nál kevesebbet keres (készpénzt kap), akkor azt azonnal elkölti – ennél nagyobb összeg esetében azonban 5000 Ft egész számú többszörösét a számlájára utalja, és csak a maradékot költi el.
Bemenet
Pénz:Egész
[Konstans Határ:Egész=5000]
Kimenet
Ebeké:Egész
Előfeltétel
0≤Pénz és 5 | Pénz
Utófeltétel
Ebeké=Pénz Mod Határ
A specifikációhoz: az előfeltételben a Pénz 5-tel való oszthatóságát írtuk elő (a nem negativitás mellett), amihez felhasználtuk a matematikában szokásos | osztója operátort. Az utófeltételben kulcs szintén egy a matematikában jól ismert művelet, a {forráskodbe}Mod{/forráskodbe}, vagyis a maradékképzés művelet.
A Pénz feladat algoritmusa, struktogrammal.#include <iostream>
using namespace std;
int main()
{
int Penz; //a Bemenet
const int Hatar=5000; //a Bemenet
int Ebeke; //a Kimenet
int megall; //a kilépési kód
cout << "Mennyit keresett?"; cin >> Licit;
if (0>Penz || (Penz % 5)!=0)
{
cout << "Ennyit nem lehet!";
megall=1;
}
else
{
Ebeke=Penz % Hatar;
cout << "Elköltheti:" << Ebeke << endl;
megall=0;
}
return megall;
}
A kódoláshoz: a maradékképzés C++ operátora a %.
Reggeli hőmérséklet értékelése, átszámítása Fahrenheit-fokra. [°F]=[°C]9/5+32 Olvassuk be a hőmérsékletet – a Földön eddig előfordult leghidegebb és legmelegebb hőmérsékletek a kódban adottak (-89° C, 58° C). (Hibás beolvasás esetén jelezzük a hibát, és lépjünk ki.) Helyes érték esetén adjuk meg és írjuk is ki, hogy fagypont alatti vagy feletti-e a hőmérséklet, és számoljuk azt át Fahrenheitre!
Segítségként megadjuk a specifikációt, alkossa meg az algoritmust és a kódot!
Specifikáció
Bemenet
Hőm:Egész
[Konstans MinH,MaxH:Egész(-89,58)]
Kimenet
Fagyott: Logikai, HőmF:Egész
Előfeltétel
Höm[MinH..MaxH]
Utófeltétel
Fagyott=Hőm≤0 és HőmF=Hőm*9/5+32
Algoritmus
házi feladat
Kód
házi feladat
![]() ![]() |
![]() |
![]() |