Algoritmi un programmēšana Praktiskie darbi Cikli Funkcijas C++ Doc. Dr. Sc. Comp. Edgars Rencis, Latvijas Universitāte, Datorikas fakultāte, 27. septembris, 2018.
Cikli
Cikli Iespēja izpildīt noteiktas darbības atkārtoti Trīs veidu cikli ar skaitītāju – for ja precīzi zināms, cik reizes cikls jāizpilda ar priekšnosacījumu – while ja nav zināms, cik reizes cikls jāizpilda ar pēcnosacījumu – do ... while ja nav zināms, cik reizes cikls jāizpilda, bet ir zināms, ka tas jāizpilda vismaz vienu reizi
Cikls ar priekšnosacījumu while (<loģiska izteiksme>) { ... } Sākuma vērtības jāpiešķir pirms cikla Cikla mainīgā izmaiņas jāveic cikla ķermenī Loģiskās izteiksmes vietā drīkst būt arī aritmētiska izteiksme Figūriekavas blokam obligātas gadījumā, ja tas satur vairāk par vienu komandu
Cikla ar priekšnosacījumu piemērs Izdrukāt vienā stabiņā ciparus no 0 līdz 9 int i=0; while (i<10) { cout << i << endl; i++; } while (i<10) cout << i++ << endl;
Cikls ar pēcnosacījumu do { ... } while (<loģiska izteiksme>) Sākuma vērtības jāpiešķir pirms cikla Cikla mainīgā izmaiņas jāveic cikla ķermenī Loģiskās izteiksmes vietā drīkst būt arī aritmētiska izteiksme Figūriekavas blokam obligātas gadījumā, ja tas satur vairāk par vienu komandu Šāds cikls izpildās vismaz vienu reizi!
Cikla ar pēcnosacījumu piemērs Izdrukāt vienā stabiņā ciparus no 0 līdz 9 int i=0; do { cout << i << endl; i++; } while (i<10); do cout <<i++<<endl; while (i<10);
Vadības nodošanas komandas Komandu izpildes secība pamatā atbilst fiziskajai komandu secībai main funkcijā ir stingri definēta atsevišķām komandām (zarošanās, cikliem, ...) atsevišķos gadījumos ir koriģējama Vadības nodošanas komandas break nodod vadību laukā no cikla nākamajai komandai continue nodod vadību nākamajai cikla iterācijai (for cikla gadījumā izpildot arī pēc-iterācijas darbību (-as)) goto nodod vadību citai patvaļīgai komandai (nav ieteicams izmantot, jo padara kodu nelasāmu)
break un continue for (int i=0; i<10; i++) { if (i>6) break; if (i%2) continue; cout << i << endl; } Ja i>6, iet laukā no cikla (beigt darbu) Nepāra skaitļiem pārejam pie nākamās iterācijas, izlaižot drukāšanas komandu Līdz šejienei nokļūstam tikai, ja i ir pāra skaitlis, kas nav lielāks par 6: 2 4 6
Uzdevums 1 Lietotājs ievada naturālu skaitli. Noskaidrot, vai tas ir pirmskaitlis! katram pirmskaitlim ir tieši 2 pozitīvi dalītāji #include <iostream> using namespace std; int main() { int x; cin >> x; int i,count=0; for(i=1; i<=x; i++) if(x%i==0) count++; if (count==2) cout << "Ir"; else cout << "Nav"; return 0; }
Uzdevums 1 – alternatīvs risinājums #include <iostream> using namespace std; int main() { int x; cin >> x; int i; for(i=2; i<x; i++) if(x%i==0) break; if (x==i) cout << "Ir"; else cout << "Nav"; return 0; }
Funkcijas C++
Problēma Uzdevums Algoritms Lietotājs vienu pēc otra ievada vairākus naturālus skaitļus. Ievade beidzas, kad lietotājs ievada kādu pirmskaitli. Izdrukāt visus pirmskaitļus, kas mazāki par lietotāja ievadīto pirmskaitli. Algoritms pirmais cikls – likt lietotājam vadīt skaitļus katram skaitlim pārbaudīt, vai tas nav pirmskaitlis un iet laukā no cikla, ja ir otrais cikls – ciklā iet cauri visiem naturālajiem skaitļiem no 2 līdz iepriekš ievadītajam skaitlim katram skaitlim pārbaudīt, vai tas nav pirmskaitlis un izdrukāt tos, kas ir
Problēma Uzdevums Algoritms Lietotājs vienu pēc otra ievada vairākus naturālus skaitļus. Ievade beidzas, kad lietotājs ievada kādu pirmskaitli. Izdrukāt visus pirmskaitļus, kas mazāki par lietotāja ievadīto pirmskaitli. Algoritms pirmais cikls – likt lietotājam vadīt skaitļus katram skaitlim pārbaudīt, vai tas nav pirmskaitlis un iet laukā no cikla, ja ir otrais cikls – ciklā iet cauri visiem naturālajiem skaitļiem no 2 līdz iepriekš ievadītajam skaitlim katram skaitlim pārbaudīt, vai tas nav pirmskaitlis un izdrukāt tos, kas ir
Problēmas risinājuma variants #include <iostream> using namespace std; int main() { int x; bool isPrime; do { cin >> x; if (x<2) isPrime=false; else isPrime=true; for (int i=2;i<x;i++) if (x%i==0) isPrime=false; } while (!isPrime); cout <<"Pirmskaitļi, kas mazāki par " << x << ":\n"; for (int y=2;y<x;y++) { for (int i=2;i<y;i++) if (y%i==0) isPrime=false; if (isPrime) cout << y << endl; } return 0;
Problēmas risinājuma variants #include <iostream> using namespace std; int main() { int x; bool isPrime; do { cin >> x; if (x<2) isPrime=false; else isPrime=true; for (int i=2;i<x;i++) if (x%i==0) isPrime=false; } while (!isPrime); cout <<"Pirmskaitļi, kas mazāki par " << x << ":\n"; for (int y=2;y<x;y++) { for (int i=2;i<y;i++) if (y%i==0) isPrime=false; if (isPrime) cout << y << endl; } return 0; Koda dublēšana – ļoti slikta lieta
Problēmas risinājuma variants #include <iostream> using namespace std; int main() { int x; bool isPrime; do { cin >> x; if (x<2) isPrime=false; else isPrime=true; for (int i=2;i<x;i++) if (x%i==0) isPrime=false; } while (!isPrime); cout <<"Pirmskaitļi, kas mazāki par " << x << ":\n"; for (int y=2;y<x;y++) { for (int i=2;i<y;i++) if (y%i==0) isPrime=false; if (isPrime) cout << y << endl; } return 0; Kods "isPrimeNumber" ar parametru sk ------------------------------------ isPrime=true; for (int i=2;i<sk;i++) if (sk%i==0) isPrime=false;
Problēmas risinājuma variants #include <iostream> using namespace std; int main() { int x; bool isPrime; do { cin >> x; if (x<2) isPrime=false; else izsaukt "isPrimeNumber" ar parametru x ielikt rezultātu iekš mainīgā isPrime } while (!isPrime); cout <<"Pirmskaitļi, kas mazāki par " << x << ":\n"; for (int y=2;y<x;y++) { izsaukt "isPrimeNumber" ar parametru y if (isPrime) cout << y << endl; } return 0; Kods "isPrimeNumber" ar parametru sk ------------------------------------ isPrime=true; for (int i=2;i<sk;i++) if (sk%i==0) isPrime=false;
Problēmas risinājuma variants #include <iostream> using namespace std; int main() { int x; bool isPrime; do { cin >> x; izsaukt "isPrimeNumber" ar parametru x ielikt rezultātu iekš mainīgā isPrime } while (!isPrime); cout <<"Pirmskaitļi, kas mazāki par " << x << ":\n"; for (int y=2;y<x;y++) { izsaukt "isPrimeNumber" ar parametru y if (isPrime) cout << y << endl; } return 0; Kods "isPrimeNumber" ar parametru sk ------------------------------------ if (sk<2) isPrime=false; else isPrime=true; for (int i=2;i<sk;i++) if (sk%i==0) isPrime=false; Funkcija Funkcijas izsaukumi
Problēmas risinājuma variants #include <iostream> using namespace std; int main() { int x; bool isPrime; do { cin >> x; isPrime=isPrimeNumber(x); } while (!isPrime); cout <<"Pirmskaitļi, kas mazāki par " << x << ":\n"; for (int y=2;y<x;y++) { isPrime=isPrimeNumber(y); if (isPrime) cout << y << endl; } return 0; bool isPrimeNumber(int sk) { if (sk<2) return false; for (int i=2;i<sk;i++) if (sk%i==0) return false; return true; } Funkcija Funkcijas izsaukumi
Kas ir funkcija? Funkcija ir patstāvīgs programmas bloks, kas veic noteiktas darbības un atgriež noteikta tipa vērtību Katrā C++ programmā ir vismaz viena funkcija main Funkcija sastāv no nosaukuma atgriežamā datu tipa ķermeņa parametru saraksta
Funkcijas piemērs int main () { cout << "Hello!"; return 0; } Atgriežamais datu tips – int Funkcijas nosaukums – main int main () { cout << "Hello!"; return 0; } Parametru saraksts – tukšs (0 parametri iekavās) Funkcijas ķermenis (sastāv no 2 komandām) Funkcijas atgrieztā vērtība – 0 (atbilst atgriežamajam datu tipam int)
Cits funkcijas piemērs Viens int tipa parametrs – sk bool isPrimeNumber(int sk) { if (sk<2) return false; for (int i=2;i<sk;i++) if (sk%i==0) return false; return true; }
Vēl cits funkcijas piemērs Divi int tipa parametri – a un b int sum (int a, int b) { int c=a+b; return c; } Funkcija izsaucama, padodot kā parametrus divus veselus skaitļus int x,y; cin >> x >> y; int z=sum(x,y); cout << z; Funkcijas atgriežamā vērtība c – parametru a un b summa int x,y; cin >> x >> y; cout << sum(x,y);
Vērtību atgriešana Funkcija var atgriezt tāda datu tipa vērtību, ar kādu šī funkcija definēta parasts datu tips – int, double, char, bool, ... speciālais datu tips – void Vērtības atgriešana notiek ar atgriešanas operatora `return` palīdzību parastu datu tipu gadījumā return 0; return c; return 'e'; return a+b; return a>3; void gadījumā return; Atgriešanas operators pārtrauc darbu ar funkciju
Netukša atgriešanas operatora piemērs Atgriezt lielāko pāra skaitli, kas nepārsniedz doto skaitli x int getEvenNumber(int x) { if (x%2==0) return x; else return x-1; }
Netukša atgriešanas operatora piemērs Atgriezt lielāko pāra skaitli, kas nepārsniedz doto skaitli x int getEvenNumber(int x) { if (x%2==0) return x; return x-1; }
Tukša atgriešanas operatora piemērs Izdrukāt vienu zem otras divas vērtības – doto veselo skaitli x un tā apgriezto vērtību 1/x void printNumbers(int x) { if (x==0) return; cout << x << endl << 1.0/x << endl; return; }
Tukša atgriešanas operatora piemērs Izdrukāt vienu zem otras divas vērtības – doto veselo skaitli x un tā apgriezto vērtību 1/x void printNumbers(int x) { if (x==0) return; cout << x << endl << 1.0/x << endl; }
Funkcijas izsaukšana Funkcija tiek izsaukta, norādot tās vārdu un argumentus Argumentu skaitam un to datu tipiem jāsakrīt ar attiecīgās funkcijas parametru skaitu un to datu tipiem (pareizā secībā) Ja funkcija atgriež vērtību, to var izmantot kā parastu attiecīgā datu tipa vērtību
Funkcijas izsaukšanas piemērs int sum (int a, int b) { int c=a+b; return c; } int main () { int x,y; cin >> x >> y; int summa=sum(x,y); cout << summa << endl; return 0;
Funkcijas izsaukšanas piemērs int sum (int a, int b) { return a+b; } int main () { int x,y; cin >> x >> y; cout << sum(x,y) << endl; return 0;
Funkcijas izsaukšanas piemērs void printNumbers(int x) { if (x==0) return; cout << x << endl << 1.0/x << endl; } int main () { int x; cin >> x; printNumbers(x); return 0;
Parametri un argumenti Parametri – mainīgie, kas norādīti funkcijas deklarēšanas vietā Argumenti – mainīgie vai vērtības, kas padotas funkcijas izsaukšanas vietā int sum (int a, int b) {return a+b;} int main () {int x,y; cin >>x >>y; cout << sum(x,y) << endl; return 0;} Parametri – a un b Argumenti – x un y
Uzdevums 2 Lietotājs ievada divus veselus pozitīvus skaitļus. Noskaidrot, kuram no šiem skaitļiem ir vairāk dalītāju, izmantojot C++ funkciju, kas prot atrast dotā skaitļa dalītāju skaitu
Uzdevums 2 – risinājums int dalSk(int x) { int sk=0; for (int i=1; i<=x; i++) if (x%i==0) sk++; return sk; } int main() { int a,b; cin >> a >> b; int dalA=dalSk(a),dalB=dalSk(b); if (dalA==dalB) cout << "Abiem skaitļiem ir vienāds dalītāju skaits\n"; else { cout << "Vairāk dalītāju ir skaitlim "; if (dalA>dalB) cout << a << endl; else cout << b << endl; return 0;