#include <iostream> /*
A „stream” (magyarul: adatfolyam)
elnevezésnek matematikai és informatikai eredete van.
Egy olyan adatforrást vagy adatszálat jelent,
amelyből sorban (folytonosan, egymás után)
lehet adatokat olvasni vagy írni,
mintha egy folyóban,
egymás után úsznának a bitek.
cin - standard input stream
cout - standard output stream
ifstream - file input stream
ofstream - file output stream
*/
#include <iomanip>, // setw, setprecision, formázott kiírás
#include <ctime> // idővel kapcsolatos függvények
#include <cmath> // matematikai műveletek (sqrt, log, cos)
#include <numbers> // std::numbers::pi
// Severity Code Description Project File Line Suppression State Details
// Warning STL4038 The contents of <numbers> are available only with C++20 or later.
#include <locale.h>
#define dendl endl << endl // 'C' stílusú megoldás, haladóbb: 2. laboron
/* https://en.cppreference.com/w/cpp/header.html Itt listázva van minden fejlécfájl,
rájuk kattintva részletesen láthatod a tartalmukat,
és hogy mire használhatók.*/
/* https://mogi.bme.hu/TAMOP/c++programozas/book.html#ch-AI.11 C++11-ig! */
using namespace std; // std névtér használata
// Ha két különböző könyvtárban ugyanaz a függvénynév vagy változónév, névütközés lenne.
// A névtérrel egyedi „tartományba” helyezed a neveket.
// Függvényprototípusok
void csere(int* elso, int* masodik); // Mutatóval történő értékcsere
void csere_referencia(int& elso, int& masodik); // Referenciával történő értékcsere
double veletlen_gauss(); // Gauss-eloszlású véletlenszám generálás (EXTRA)
void egyszeru_egyseges(double t, double& kimenet);// Egységugrás referenciával
int main()
{
setlocale(LC_ALL, ""); // Jó öreg ékezetes karakterek, mostmár van pl. ű is
cout << "Árvíztűrő tükörfúrógép" << dendl;
// 1. Egyszerű kiírások és beolvasások magyar változónevekkel
double valos_szam = 123456.123456; // Valós szám változó
int egesz_szam = 15;
cout << "Adj meg egy valós számot: ";
cin >> valos_szam;
cout << "Adj meg egy egész számot: ";
cin >> egesz_szam;
cout << "A beolvasott valós szám: " << valos_szam << endl <<
"A beolvasott egész szám: " << egesz_szam << endl << "\n";
// 2. Kiírási formátumok demonstrálása
cout << "valos_szam: " << valos_szam << " egesz_szam: " << egesz_szam << endl;
cout << "valos_szam: " << setw(15) << valos_szam << " egesz_szam: " << setw(8) << egesz_szam << endl;
cout << "valos_szam: " << left << setw(15) << valos_szam << " egesz_szam: " << setw(8) << egesz_szam << endl;
cout << "valos_szam: " << setfill('*') << setw(15) << valos_szam << " egesz_szam: " << setw(8) << setfill(' ') << egesz_szam << endl;
cout << "valos_szam: " << setprecision(4) << fixed << setw(15) << valos_szam << " egesz_szam: " << setw(8) << egesz_szam << endl;
cout << "valos_szam: " << setw(15) << valos_szam << " egesz_szam: 0x" << hex << setw(8) << egesz_szam << dec << endl;
cout << "valos_szam: " << scientific << setw(15) << valos_szam << dendl;
cout.unsetf(ios::floatfield); // Formázások visszaállítása
// A cout egy std::ostream típusú objektum (az std névtérből).
// Az unsetf egy tagfüggvény(member function, metódus),
// amely az ostream osztályban van.
// Az std::ios::floatfield egy flag,
// amely azt határozza meg,
// hogy a számokat milyen formátumban írja ki a cout (fixed, scientific vagy egyik sem).
// ios == input/output stream
cout << "Visszaállított formátum: valos_szam: " << valos_szam <<
" egesz_szam: " << egesz_szam << dendl;
cout << "\033[31m" << "Piros szöveg" << "\033[0m" << endl; // 31 = piros
cout << "\033[32m" << "Zöld szöveg" << "\033[0m" << endl; // 32 = zöld
cout << "\033[34m" << "Kék szöveg" << "\033[0m" << endl; // 34 = kék
cout << "\033[1;33m" << "Sárga (fényes)" << "\033[0m" << endl; // 1;33 = vastag sárga
cout << "Normál szöveg" << dendl;
// 3. Karaktertípusok
char betu = 'A'; // Karakter típusú változó
wchar_t szeles_karakter = L'ó'; // Széles karakter (magyar ékezetes karakter is lehet)
cout << "Karakter (betu): " << betu << endl;
wcout << L"Széles karakter: " << szeles_karakter << dendl;
// 4. Logikai típus
bool logikai = false;
cout << "Logikai (false) érték: " << logikai << dendl;
// 5. Mutatók
int szam = 100;
int* mutato = &szam;
printf("szam=%i *mutato=%i\n\n", szam, *mutato);
// 6. Dinamikus tömb foglalás és feltöltés véletlenszámokkal (C-s és C++-os mód)
srand((unsigned int)time(NULL));
double* tomb = (double*)malloc(sizeof(double) * 5);
if (tomb != NULL) {
cout << "Tömb (C): ";
for (int i = 0; i < 5; i++) {
tomb[i] = (double)(rand() % 21) / 2;
cout << tomb[i] << " ";
}
cout << endl;
free(tomb);
}
double* cpp_tomb = new double[5];
cout << "Tömb (C++): ";
for (int i = 0; i < 5; i++) {
cpp_tomb[i] = (double)(rand() % 21) / 2;
cout << cpp_tomb[i] << " ";
}
cout << dendl;
delete[] cpp_tomb;
// 7. Kétdimenziós dinamikus tömb (mátrix) létrehozása és feltöltése (C++26-tól <linalg> várható... utolsó ciklusos mátrixos félév?!?)
int meret = 3;
int** matrix = new int* [meret];
for (int i = 0; i < meret; i++)
matrix[i] = new int[meret];
for (int i = 0; i < meret; i++)
for (int j = 0; j < meret; j++)
matrix[i][j] = (i == j) ? 1 : 0; // Egységmátrix
cout << "Egységmátrix:" << endl;
for (int i = 0; i < meret; i++) {
for (int j = 0; j < meret; j++)
cout << matrix[i][j] << " ";
cout << endl;
}
for (int i = 0; i < meret; i++)
delete[] matrix[i];
delete[] matrix;
cout << dendl;
// 8. Referenciák használata
int alap = 13;
int& referencia = alap;
cout << "alap = " << alap
<< " referencia = " << referencia << endl;
alap++;
cout << "alap++ után: alap = " << alap
<< " referencia = " << referencia << endl;
referencia++;
cout << "referencia++ után: alap = " << alap
<< " referencia = " << referencia << dendl;
// 9. Értékcsere mutatóval és referenciával
int elso_szam = 10,
masodik_szam = 20;
cout << "Csere előtt: elso_szam = " << elso_szam
<< ", masodik_szam = " << masodik_szam << endl;
csere(&elso_szam, &masodik_szam);
cout << "Mutatós csere után: elso_szam = " << elso_szam
<< ", masodik_szam = " << masodik_szam << endl;
csere_referencia(elso_szam, masodik_szam);
cout << "Referenciás csere után: elso_szam = " << elso_szam
<< ", masodik_szam = " << masodik_szam << dendl;
// 10. Egyszerű egységugrás függvény hívása
double ido = 0.5,
kimenet = 0;
egyszeru_egyseges(ido, kimenet);
cout << "Egységugrás kimenet (t = " << ido << "): " << kimenet << dendl;
// 11. EXTRA: Gauss-eloszlású véletlenszám generálása
cout << "Gauss-eloszlású véletlenszámok (5db): ";
for (int i = 0; i < 5; i++)
cout << veletlen_gauss() << " ";
cout << endl;
return 0;
}
// Értékek cseréje mutatóval (C módon) - A változók címét (memóriahelyét) kapja meg a függvény.
//
// Sima változókkal mi volt a helyzet: Ha egy függvénynek simán átadsz egy változót, a függvény csak egy másolatot kap.
// Amit módosítasz, az csak a másolatot érinti, a hívó oldali változó nem változik meg.
// Ha azt akarod, hogy egy változó értéke ténylegesen megváltozzon, a címét kell átadnod (pointer).
void csere(int* elso, int* masodik) {
int temp = *elso;
*elso = *masodik;
*masodik = temp;
}
// Értékek cseréje referenciával (C++ módon) - A változók álneveként (referenciaként) kapja meg őket a függvény.
//
// Itt a függvény paraméterei a hívó oldali változókhoz lesznek „hozzákötve”.
// Bármit csinálsz a függvényben a paraméterekkel, az a hívó oldali változót is módosítja.
//
// A referencia NEM mutató (pointer) – de a háttérben gyakran pointerként valósítja meg a fordító.
void csere_referencia(int& elso, int& masodik) {
int temp = elso;
elso = masodik;
masodik = temp;
}
// Egyszerű egységugrás (unit step) függvény – csak bemenő értéktől függ - const: ahol csak olvasok adatot
void egyszeru_egyseges(const double t, double& kimenet) {
if (t >= 0) kimenet = 1;
else kimenet = 0;
}
// Gauss-eloszlású véletlenszám generálása (Box-Muller transzformáció)
//
// Cél: egyenletes eloszlású véletlenszámokból (uniform random) normális (Gauss) eloszlású véletlenszámot generálni.
// rand() egyenletes eloszlású számokat ad [0, RAND_MAX] intervallumon.
// Szükségünk van normális (Gauss) eloszlású véletlenszámra:
// Átlag (μ) = 0, szórás (σ) = 1 (standard normális eloszlás == uniform eloszlás)
double veletlen_gauss() {
// A Box–Muller-transzformáció
// két független, [0, 1) intervallumon egyenletes eloszlású változód van(u1, u2)
double u1 = (rand() + 1.0) / (RAND_MAX + 2.0); // +1, +2 azért hogy sose legyen 1.0 vagy 0.0
double u2 = (rand() + 1.0) / (RAND_MAX + 2.0); // log(0) értelmetlen
// ezekből így kapsz egy (két) független normális eloszlású számot:
return sqrt(-2.0 * log(u1)) * cos(2 * std::numbers::pi * u2); //(első)
// return sqrt(-2.0 * log(u1)) * sin(2 * pi * u2) //(második)
// Az egyenletes eloszlású u1-ből, u2-ből az (R, Θ)
// polárkoordinátarendszerben „random pontot” generálunk a síkon.
// Mire jó pl.:
// Szimulációk,
// mérési hibák modellezése,
// zajgenerálás,
/* Monte Carlo - módszerek: Olyan problémák megoldása,
amelyeket analitikusan vagy
determinisztikus módon nehéz kiszámolni
(pl. integrálok, statisztikai fizika, pénzügyi modellek).
Sok (akár millió) véletlenszerű szimulációt (próbát) végzel,
az eredmények statisztikai átlagából következtetsz a megoldásra.
*/
}