Keele põhikonstruktsioonid I
Pärast selle praktikumi läbimist üliõpilane
- teab ja oskab kasutada tingimuslauseid, sh kolmepoolset tingimuslauset
- teab korduslausete erinevaid võimalusi C++ programmi koostamisel
- oskab kasutada C++ massiive
- oskab genereerida juhuarve
Tingimuslause
Avaldiste võrdlemiseks kasutatakse C++ samu operaatoreid, mis paljudes teistes keeltes: <
, <=
, >
, >=
, ==
, !=
. Loogilised operaatorid on järgmised:
Operaator | Tähendus | Näide |
---|---|---|
! | Eitus | !a |
&& | AND | a&&b |
|| | OR | a||b |
Avaldisi &&
ja ||
väärtustatakse vasakult paremale. Paremal pool asuvat operandi väärtustatakse ainult siis, kui vasaku poole väärtus ei määra tulemust üheselt. Näiteks koodilõigu
int a{1}; int b{2}; cout << boolalpha << (a == b && b > a) << "\n"; | false |
tulemuseks on false
. Kuna avaldise vasaku poole tõeväärtus on false
ja tulemuseks on sõltumata paremast poolest false
, siis operaatorist &&
paremal pool olevat avaldist b > a
ei väärtustata. Märgime siin, et ümarsulud väljundvoos cout
on avaldise väärtustamiseks vajalikud.
if-lause
põhikuju on järgmine:
if (tingimus) { //käsud1 } else { //käsud2 }
Tingimus (mis võib olla keeruline loogiline avaldis) peab olema ümarsulgudes ja else
osa võib puududa. Kui lausete plokk koosneb ühest käsust, siis võib loogelised sulud ära jätta. Samuti võivad if
laused olla üksteise sees.
int aastaaeg; cout << "Sisesta aastaaeg (1-4):"; cin >> aastaaeg; if (aastaaeg == 1){ cout << "Kevad!\n"; } else if (aastaaeg == 2){ cout << "Suvi!\n"; } else if (aastaaeg == 3){ cout << "Sügis!\n"; } else if (aastaaeg == 4){ cout << "Talv!\n"; } else{ cout << "Vale aastaaeg!\n"; } | Sisesta aastaaeg (1-4):2 Suvi! ---- Sisesta aastaaeg (1-4):8 Vale aastaaeg! |
Tegelikult võib tingimuslause olla palju keerulisem, näiteks võib kasutada initsialiseerimist, vt https://en.cppreference.com/w/cpp/language/if.
Tingimusoperaator
Tingimusoperaator võimaldab lühendada teatud kujul if-else
lauseid. Olgu meil tingimuslause (muutujad a, b, suurim
on varem defineeritud).
if (a > b){ suurim = a; } else{ suurim = b; }
Tingimusoperaatoriga saab sama koodi kirja panna ühel real:
suurim = (a > b) ? a : b;
Avaldist omistamisoperaatorist =
paremal nimetatakse tingimusoperaatori avaldiseks. Kui tingimus enne ?
on tõene (true
), siis tagastatakse esimene kahest avaldisest (antud näites a
), vastasel juhul tagastatakse teine avaldis (antud näites b
).
Kolmepoolne võrdlemine <=>
(three-way comparison)
Alates C++20 saab kasutada kolmepoolse võrdlemise operaatorit <=>
, mida nimetatakse ka "kosmoselaeva" operaatoriks, sest kellelegi meenutas selle operaatori kuju lendavat taldrikut. Täpsemalt, hüüdnime võttis kasutusele programmeerimiskeele Perl ekspert Randal L. Schwartz, kuna kujund meenutas talle kosmoselaeva 1970ndate tekstipõhises arvutimängus "Star Trek".
Operaatoris on koos kolm võrdlemist (<
, ==
, >
). Avaldis a<=>b
määrab, kas a
on väiksem, võrdne või suurem kui b
:
(a <=> b) < 0
kui a < b
, (a <=> b) > 0
kui a > b
, (a <=> b) == 0
kui a == b
(a
ja b
on võrdsed).
Võrdlemise tulemuse saab salvestada muutujasse, mida saab hiljem nulliga võrrelda. Vaatame näidet
double a{3.2}; double b{2.3}; auto tulemus = a <=> b; if (tulemus < 0) std::cout << "a < b"; else if (tulemus > 0) std::cout << "a > b"; else if (tulemus == 0) std::cout << "a == b"; else std::cout << "a ja b ei ole võrreldavad"; | a > b |
Kolmepoolse võrdlemisega saab võrrelda ka keerulisemaid operande, nendega saab tutvuda aadressil https://en.cppreference.com/w/cpp/language/operator_comparison.
Korduslaused, break
, continue
for
-tsükkel
for
-tsükli üldkuju on järgmine:
for (eeltegevused; jätkamistingimus; sammu järeltegevused) { // käsud, mida tuleb täita niikaua, kuni jätkamistingimus kehtib }
Järgmises näites kasutatakse tsüklimuutujat, mille tüüp on unsigned int
:
for(unsigned int i{0} ; i < 3 ; ++i){ cout << i << " : Mulle meeldib C++!\n"; } | 0 : Mulle meeldib C++! 1 : Mulle meeldib C++! 2 : Mulle meeldib C++! |
Tavaliselt (nt massiivi läbimisel) kasutatakse tsüklimuutujat kasutades size_t
(alates C++11). size_t
ei ole andmetüüp, ta on standardteegis defineeritud aliasena märgita täisarvutüübile.
for(size_t i{0} ; i < 3 ; ++i){ cout << i << " : Mulle meeldib C++!\n"; } | 0 : Mulle meeldib C++! 1 : Mulle meeldib C++! 2 : Mulle meeldib C++! |
Tsüklimuutuja for
-tsüklis ei pea tingimata olema täisarvutüüpi. Järgmises näites arvutatakse ringi pindala raadiuse eri väärtuste korral ja tsükli täitmist juhitakse ujukomaarvuga.
double pi{3.14159265}; for (double raadius{2.0}; raadius <= 12.0; raadius += 2.5){ cout << raadius << " " << pi * raadius * raadius << "\n"; } | 2 12.5664 4.5 63.6173 7 153.938 9.5 283.529 12 452.389 |
Väljundi formaatimine
Eelmise näite väljund on raskesti loetav. C++ väljundit on võimalik käskudega juhtida. Vaatame näidet, kus on kasutatud teeki <iomanip>
võimalusi väljundi formaatimiseks. Selleks tuleb teek <iomanip>
programmi kaasata. Selguse mõttes esitame terve programmi.
#include <iostream> #include <iomanip> using namespace std; int main(){ double pi{3.14159265}; cout << setw(7) << "Raadius" << setw(10) << "Pindala\n"; cout << "-----------------\n"; cout << right; for (double raadius{2.0}; raadius <= 12.0; raadius += 2.5){ cout << setw(7) << raadius << setw(10) << pi * raadius * raadius << "\n"; } return 0; } | Raadius Pindala ----------------- 2 12.5664 4.5 63.6173 7 153.938 9.5 283.529 12 452.389 |
Käsk cout << setw(7)
annab väljundile korralduse, et järgnev info on vaja paigutada väljale laiusega 7 märki. Käsk cout << right
annab korralduse, et info tuleb paigutada joondatult paremale (vaikimisi on joondus vasakule). Teek <iomanip>
pakub mitmeid teisi võimalusi väljundi formaatimiseks, mida saab uurida siit: https://en.cppreference.com/w/cpp/header/iomanip.
for
-tsüklil on mitmeid teisi vorme, nendest tuleb juttu hiljem.
while
-tsükkel
while
-tsükli üldkuju on sarnane nagu paljudes teistes programmeerimiskeeltes
while (tingimus){ // käsud, mida tuleb täita niikaua, kuni tingimus kehtib }
Oluline on, et tingimus oleks ümarsulgudes ja tsükli kehas peab hoolitsema selle eest, ei tekiks lõpmatu tsükkel. Kirjutame eelmise programmi ümber kasutades while
-tsüklit (programmi algus ja lõpp on ära jäetud):
cout << setw(7) << "Raadius" << setw(10) << "Pindala\n"; cout << "-----------------\n"; cout << right; double pi{3.14159265}; double raadius{2.0}; while (raadius <= 12.0) { cout << setw(7) << raadius << setw(10) << pi * raadius * raadius << "\n"; raadius += 2.5; } | Raadius Pindala ----------------- 2 12.5664 4.5 63.6173 7 153.938 9.5 283.529 12 452.389 |
do while
-tsükkel
do while
-tsükli üldkuju on järgmine:
do{ // käsud, mida tuleb täita niikaua, kuni tingimus kehtib } while (tingimus);
do while
-tsükli keha täidetakse alati vähemalt üks kord. Ringi pindala arvutamise programm kasutades do while
-tsüklit:
cout << setw(7) << "Raadius" << setw(10) << "Pindala\n"; cout << "-----------------\n"; cout << right; double pi{3.14159265}; double raadius{2.0}; do{ cout << setw(7) << raadius << setw(10) << pi * raadius * raadius << "\n"; raadius += 2.5; }while (raadius <= 12.0); | Raadius Pindala ----------------- 2 12.5664 4.5 63.6173 7 153.938 9.5 283.529 12 452.389 |
Tsüklidirektiivid break
ja continue
Tsüklidirektiivi break
kasutatakse tsüklist väljumiseks. Tüüpiline kasutus on näiteks lõpmatute tsüklite
while (true){ ... }
või
for (; ; ;){ ... }
töö lõpetamiseks, aga ka teistel juhtudel. Näiteks lõpmatu tsükkel kasutajalt korrektse sisendi küsimiseks:
int arv; while(true){ cout << "Sisesta arv ühest kümneni:"; cin >> arv; if (arv >= 1 && arv <= 10){ cout << "Sisestasid arvu " << arv; break; } } | Sisesta arv ühest kümneni:15 Sisesta arv ühest kümneni:5 Sisestasid arvu 5 |
Tsüklidirektiiv continue
tsükli sees lõpetab käsil oleva tsüklisammu ja täitmisele tuleb järgmine tsüklisamm.
char ch{}; cout << left << setw(10) << "Märk" << setw(10) << "Kood\n"; do{ if (!isprint(ch)){ continue; } cout << left << setw(10) << ch << setw(10) << static_cast<int>(ch) << "\n"; }while (ch++ < 127); | Märk Kood 32 ! 33 " 34 # 35 $ 36 % 37 & 38 ' 39 |
Programm kuvab ekraanile ASCII kooditabelist prinditavad märgid, mille ASCII kood on väiksem kui 127. Standardnimeruumi funktsioon isprint
tagastab tõeväärtuse true
, kui koodile vastab prinditav sümbol. Väljundist on toodud vaid osa. Märgime siin, et ASCII koode 0 kuni 31 kasutatakse juhtsümbolitena ja nendel prinditav kuju puudub. Koodile 32 vastab tühik.
Käsk switch
- lüliti
switch
lause põhikuju on järgmine:
switch (avaldis) { case väärtus1: //käsud, mis täidetakse, kui avaldis = väärtus1 break; case väärtus2: //käsud, mis täidetakse, kui avaldis = väärtus2 break; ... default: //käsud, mis täidetakse, kui ükski eelnev ei sobinud }
Avaldise tüüp peab olema teisendatav kas char
või täisarvutüübiks.
Aastaaegade näite saab switch
abil kirja panna järgmiselt:
switch (aastaaeg) { case 1: cout << "Kevad!\n"; break; case 2: cout << "Sisestasid: " << aastaaeg << "\n"; cout << "Suvi!\n"; break; case 3: cout << "Sügis!\n"; break; case 4: cout << "Talv!\n"; break; default: cout << "Vale aastaaeg!\n"; } | Sisesta aastaaeg (1-4):2 Sisestasid: 2 Suvi! |
Paneme tähele, et siin ei pea plokis mitme käsu jaoks loogelisi sulge kasutama (aga võib). Käsk break
lõpetab siin switch
täitmise. Käsu break
võib jätta ära (näites on alates case 2:
käsud break
välja kommenteeritud), kuid sellel on kõrvalefekt:
switch (aastaaeg) { case 1: cout << "Kevad!\n"; break; case 2: cout << "Sisestasid: " << aastaaeg << "\n"; cout << "Suvi!\n"; //break; case 3: cout << "Sügis!\n"; //break; case 4: cout << "Talv!\n"; //break; default: cout << "Vale aastaaeg!\n"; } | Sisesta aastaaeg (1-4):2 Sisestasid: 2 Suvi! Sügis! Talv! Vale aastaaeg! |
Mitu case
haru on lubatud? C++
standard soovitab toetada vähemalt 16384 case
haru!
Ka switch
lausel on mitmeid eri võimalusi, lähemalt saab uurida siit https://en.cppreference.com/w/cpp/language/switch
Massiivid
Ühedimensionaalset massiivi saab defineerida järgmiselt:
tüüp muutuja_nimi[elementide_arv];
Massiivi definitsioonis on nurksulud alati muutuja nime järel. Näites toodud lause ei väärtusta massiivi elemente. Juba defineeritud massiiv on konstantse pikkusega, st elementide arvu ei saa muuta ja indeksid algavad nullist. Massiivi elementide läbivaatuseks on sobiv kasutada tsüklit.
int kaheastmed[5]; for (int i{0}; i < 5; ++i) { kaheastmed[i] = exp2(i); } cout << "Kaheastmed: \n"; for (int i{0}; i < 5; ++i) { cout << i << " " << kaheastmed[i] << "\n"; } | Kaheastmed: 0 1 1 2 2 4 3 8 4 16 |
Näites on kasutatud funktsiooni exp2
, mis arvutab argumendi kahe astme. Funktsioon asub teegis <cmath>
, st programmi alguses peab olema käsk #include <cmath>
.
Vaatame nüüd ujukomaarvude massiivi, mille elemente ei algväärtustata ja elementide väljastamisel minnakse indeksiga "üle otsa". Massiivi deklareerimisel määratakse massiivi muutujale mälupiirkonna algus. Ekraanile kuvamisel püütakse mälus olevat infot esitada double
tüüpi arvudena.
double d[3]; for (int i{0}; i < 5; ++i) { cout << i << " " << d[i] << "\n"; } | 0 7.3549e-312 1 2.122e-314 2 6.95148e-310 3 6.36599e-314 4 3.30536e-313 |
Massiivi elemente saab defineerimisel väärtustada, siis võib nurksulgudes elementide arvu ära jätta.
int massiiv[]{3, 8, 2};
Kui nurksulgudes on suurem arv kui on defineeritud elemente, siis ülejäänutele omistatakse null.
int massiiv[5]{3, 8, 2}; for (int i{0}; i < 5; ++i) { cout << i << " " << massiiv[i] << "\n"; } | 0 3 1 8 2 2 3 0 4 0 |
Näites massiivi elemendid indeksitega 3 ja 4 on nullid. Seni toodud näidetes on kasutatud massiivi indeksit. Kui massiivi indeksit ei vajata, siis on võimalik kasutada nn forEach
tsüklit (range-based for loop), kus pole vaja muretseda elementide arvu pärast.
int massiiv[]{3, 8, 2}; for (int arv : massiiv) { cout << arv << "\n"; } | 3 8 2 |
NB! C++ ei kontrolli massiivi indekseid, seda peab tegema programmeerija ise. Näiteks on võimalik eelmise massiivi korral omistada
massiiv[5] = 12;
kusjuures viga ei teki nii kompileerimisel kui ka täitmisel. Selline teguviis võib viia programmi kokkujooksmiseni.
Massiivi elementide arvu määramiseks kasutatakse sageli funktsiooni sizeof
, mis tagastab argumendi suuruse baitises (massiivi korral massiivi all oleva mälupiirkonna suuruse, tüübi korral tüübi suuruse baitides).
int massiiv[] {3, 8, 2}; size_t massiivi_elementide_arv = sizeof(massiiv)/sizeof(int); cout << massiivi_elementide_arv << "\n"; | 3 |
Palju mugavam on kasutada teegis <array>
(algselt teegis <iterator>
) defineeritud standardnimeruumi funktsiooni size
(alates C++17).
Mitmedimensionaalseid massiive defineeritakse analoogiliselt, kusjuures kõige vasakpoolsema dimensiooni võib ära jätta.
int tabel[][3][2] = {{{1, 2}, {3, 4}, {5, 6}}, {{7, 8}, {9, 10}, {11, 12}}}; for (size_t i{0}; i < size(tabel); ++i) { for (int j{0}; j < size(tabel[0]); ++j) { for (int k{0}; k < size(tabel[0][0]); ++k) { cout << tabel[i][j][k] << " "; } cout << "\n"; } cout << "---\n"; } | 1 2 3 4 5 6 --- 7 8 9 10 11 12 --- |
Massiiv char
tüüpi elementidest
Massiiv char
-tüüpi elementidest võib olla kahte tüüpi. Massiiv võib olla lihtsalt märkide kogum
char sõnum[]{'T', 'e', 'r', 'e'};
või märkide kogum, mille viimaseks elemendiks on nn nullmärk (null character)
char sõnum[]{'T', 'e', 'r', 'e', '\0'};
Viimati defineeritud massiiv võib esindada ka sõnet (string). Nullmärk on sõne lõpu tunnus. Märgimassiivi, mille lõpus on '\0', nimetatakse C-stiilis sõneks (string). Standardnimeruumis on olemas ka liittüüp string
, mida käsitletakse hiljem.
Sõne tüüpi char
massiivi saab defineerida ka järgmiselt:
char nimi[]{"Tuule Lohe"};
Tulemuseks luuakse C-stiilis sõne (nullmärk lisatakse siin automaatselt). Sellist massiivi saab otse ekraanile kuvada:
char nimi[]{"Tuule Lohe"}; cout << nimi << "\n"; | Tuule Lohe |
NB! Selliselt ei saa ekraanile kuvada teisi massiive (arvumassiive või char
massiive ilma nullmärgita lõpus). Näiteks, kui üritada ekraanile tuua täisarvumassiivi, siis tulemus võib olla midagi taolist:
int arvud[]{1, 2, 3}; cout << arvud << "\n"; | 0x6bf1ff5e4 |
char
massiivi läbivaatamist saab toimetada for
-tsükliga. Järgmises näites on vajalik päise #include <cctype>
olemasolu. Lõputunnusena kontrollitakse for
-tsüklis nullmärgi ('\0') olemasolu, aga võib ka i < size(massiiv)
.
const int max_pikkus{20}; // Massiivi suurus (peab defineerima konstandina) char massiiv[max_pikkus]{}; // Massiiv, kuhu lugeda cout << "Sisesta tekst:\n"; cin.getline(massiiv, max_pikkus); //cin meetod, võimalik lugeda tühikuid sisaldavat lauset cout << "Sisestasid:\n" << massiiv << "\n"; int tähemärke{}; int numbreid{}; for (int i{}; massiiv[i] != '\0'; i++) { if (isalpha(massiiv[i])) { tähemärke++; } if (isdigit(massiiv[i])) { numbreid++; } } cout << "Sisestatud lauses oli " << tähemärke << " tähemärki " << "ja " << numbreid << " numbrit.\n"; | Sisesta tekst: 254 Kolm k2 Sisestasid: 254 Kolm k2 Sisestatud lauses oli 5 tähemärki ja 4 numbrit. |
Etteantud suurusega char
massiivi saab defineerida konstantse pikkusega, seetõttu on vajalik võtmesõna const
muutuja max_pikkus
ees. Käsk cin.getline(massiiv, max_pikkus)
võimaldab klaviatuurilt lugeda lauset (tühikutega eraldatud teksti) ühte muutujasse (massiivi). Teegi <cctype>
funktsioonid isalpha
ja isdigit
teevad kindlaks, kas etteantud märk on vastavalt kas tähemärk või number. Teiste funktsioonidega teegist <cctype>
saab tutvuda siin https://en.cppreference.com/w/cpp/header/cctype.
Eriti mugav on defineerida kahedimensionaalseid C-stiilis sõnemassiive ja neid töödelda ühekordse tsükliga:
char kuulsused[][30]{ "Erki Nool ", "Ott Lepland", "Birgit Sarrap", "Tõnis Niinemets", }; for (int i{0}; i < size(kuulsused); ++i) { cout << kuulsused[i] << "\n"; } | Erki Nool Ott Lepland Birgit Sarrap Tõnis Niinemets |
vector
- dünaamiline massiiv
Standardmallide teek STL (Standard Template Library) sisaldab teeki std::<vector>
, mis võimaldab luua dünaamilist (muutuva suurusega) massiivi. Vektorisse võib elemente lisada, elemente kustutada või muuta. Selleks tuleb programmi algul kaasata teek <vector>
.
#include <vector>
Vektorisse saab salvestada ainult sama tüüpi elemente, mille tüüp tuleb vektori loomisel näidata:
vector<int> m; // tühi vektor vector<double> arvud(10); // sisaldab 10 elementi, kõik nullid vector<string> sõned(5); // 5 elementi, kõik tühisõned
Loogeliste sulgudega initsialiseeerimisel saab ette anda elementide loetelu:
vector<int> m1{5}; // üks element: 5 vector<double> arvud{1.1, 2.2}; // 2 elementi: 1.1 ja 2.2
Elemente saab kätte indeksi abil, elementide arvu annab funktsioon size
. Läbivaatuseks saab kasutada nii for
kui ka forEach
tsüklit:
#include <iostream> #include <vector> using namespace std; int main() { vector<double> arvud{1.1, 2.2}; // 2 elementi: 1.1 ja 2.2 arvud.push_back(3.3); // lisame elemendi 3.3 cout << "Esialgne:\n"; for (size_t i = 0; i < arvud.size(); ++i) { cout << arvud[i] << " "; } for (size_t i = 0; i < arvud.size(); ++i) { arvud[i] += 1; // suurendame ühe võrra } cout << "\nÜhe võrra suurendatult:\n"; for (size_t i = 0; i < arvud.size(); ++i) { cout << arvud[i] << " "; } erase(arvud, 1.1); // kustutame 1.1 esinemised cout << "\n1.1 on kustutatud:\n"; for (double d: arvud) { cout << d << " "; } return 0; } | Esialgne: 1.1 2.2 3.3 Ühe võrra suurendatult: 2.1 3.2 4.3 1.1 on kustutatud: 2.1 3.2 4.3 |
Lähemalt saab <vector>
võimalusi uurida aadressilt
https://en.cppreference.com/w/cpp/container/vector
NB! Dokumendis
https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines.html#Rsl-arrays
soovitatakse eelistada <vector>
tüüpi dünaamilisi massiive fikseeritud pikkusega massiividele.
Juhuarvude genereerimine
Esmalt tutvume C-keelest pärit juhuslike täisarvude genereerimisega. Teegis <cstdlib>
on funktsioon rand
, mis genereerib juhusliku täisarvu vahemikus 0..RAND_MAX
. Genereerime kuus täisarvu vahemikus 0..RAND_MAX
ja kuus täisarvu vahemikus 5 .. 15
, kus otspunktid on kaasa arvatud. Viimasel juhul sobiva tulemuse saamiseks kasutame jagamise jääki ja nihutamist rand()%11 + 5
. Mõned näited juhuslike täisarvude arvutamisest vahemiku järgi
arv1 = rand() % 100; // arv1 vahemikus 0..99 arv2 = rand() % 100 + 1; // arv2 vahemikus 1..100 arv3 = rand() % 40 + 1985; // arv3 vahemikus 1985..2024
Tulemus võiks olla näiteks selline:
#include <iostream> #include <cstdlib> using namespace std; int main() { cout << "Juhuarvud vahemikus 0 .. RAND_MAX:" << "\n"; for (int i = 0; i < 6; ++i) { cout << rand() << " "; } cout << "\nJuhuarvud vahemikus 5 .. 15:" << "\n"; for (int i = 0; i < 6; ++i) { cout << rand()%11 + 5 << " "; } return 0; } | Juhuarvud vahemikus 0 .. RAND_MAX: 41 18467 6334 26500 19169 15724 Juhuarvud vahemikus 5 .. 15: 10 15 6 5 12 12 |
Kui seda programmi käivitada mitu korda, siis iga kord saame samad arvud. Selle vältimiseks kasutatakse funktsiooni srand
, mille abil saab genereerijale ette anda nn "seemne", et funktsioon tagastaks igal käivitamisel uued juhuarvud. Seemneks sobib funktsiooni time
(teegist <ctime>
) tagastatud hetkeaeg, mis on igal käivitusel erinev.
#include <iostream> #include <cstdlib> #include <ctime> using namespace std; int main() { srand(time(0)); cout << "Juhuarvud vahemikus 0 .. RAND_MAX:" << "\n"; for (int i = 0; i < 6; ++i) { cout << rand() << " "; } cout << "\nJuhuarvud vahemikus 5 .. 15:" << "\n"; for (int i = 0; i < 6; ++i) { cout << rand()%11 + 5 << " "; } return 0; } | Esimene kord käivitades: Juhuarvud vahemikus 0 .. RAND_MAX: 41 18467 6334 26500 19169 15724 Juhuarvud vahemikus 5 .. 15: 10 15 6 5 12 12 Teine kord käivitades: Juhuarvud vahemikus 0 .. RAND_MAX: 16987 22816 1300 21150 20282 23915 Juhuarvud vahemikus 5 .. 15: 10 10 9 14 13 15 |
NB! Juhuslike arvude genereerimisel rand
abil on mitmeid puudusi, seetõttu ei soovitata seda lähenemist reaalsetes projektides kasutada, vt
https://en.cppreference.com/w/c/numeric/random/rand
Alates C++11
-st on kasutusel teek <random>
, millel on palju rohkem võimalusi: mitmed juhuslike arvude generaatorid, erinevad juhuslike arvude jaotused jne. Toome siin väikese näite:
#include <iostream> #include <random> using namespace std; int main() { default_random_engine genereerija; uniform_int_distribution<int> jaotus(5,15); cout << "Teegi <random> abil genereeritud täisarvud vahemikus 5..15 (ühtlase jaotusega)\n"; for (size_t i = 0; i < 10; ++i) { cout << jaotus(genereerija) << " "; } return 0; } | Teegi <random> abil genereeritud täisarvud vahemikus 5..15 (ühtlase jaotusega) 5 6 13 10 10 7 5 12 12 15 |
Täpsemalt saab <random>
võimalusi uurida aadressil
https://en.cppreference.com/w/cpp/numeric/random
NB! Enesetestides eeldame, et on kasutatud standardnimeruumi (using namespace std;
)