podatkovni tipi v jeziku c++
DESCRIPTION
PODATKOVNI TIPI V JEZIKU C++. Osnovni podatkovni tipi. Sestavljeni podatkovni tipi. Celoštevilčni: int (zasede 4 zloge) short (2 zloga) long (4 zloge). Izpeljani: kazalci (4 zloge) reference. Homogeni: - polja. Znakovni: - char (1 zlog). Nehomogeni: strukture unije. Realni: - PowerPoint PPT PresentationTRANSCRIPT
PODATKOVNI TIPI V JEZIKU C++
Osnovni podatkovni tipi Sestavljeni podatkovni tipi
Celoštevilčni:
- int (zasede 4 zloge)
- short (2 zloga)
- long (4 zloge)
Znakovni:
- char (1 zlog)
Realni:
- float (4 zloge)
- double (8 zlogov)
- long double (8 zlogov)
Naštevni:
- enum (4 zloge)
Logični:
- bool (1 zlog)
Homogeni:
- polja
Nehomogeni:
- strukture
- unije
Izpeljani:
- kazalci (4 zloge)
- reference
POLJAPOMNILNIK
Fizični naslovi
Logični naslovi
Vsebina
Zaslon
Polje je zaporedje vrednosti istega tipa, ki jim damo eno ime. Posamezne vrednosti oziroma elemente polja dosegamo z indeksom. Definiramo lahko polja poljubnih tipov (polje celih števil, polje realnih števil, polje znakov, polje struktur, polje polj, itd.).
Polje je sestavljeni podatkovni tip, sestavljen iz elementov istega tipa.
Deklaracija polja in dostop do elementovPri deklaraciji polja se za shranjevanje elementov polja v pomnilniku rezervira ustrezno število sosednjih pomnilniških celic. Zato moramo določiti velikost polja, to je število, ki pove, koliko elementov polje vsebuje.Npr. z deklaracijo
int test[4]
določimo polje test s štirimi elementi tipa int. Pri tem imajo elementi polja nedoločene vrednosti.
Do elementov polja dostopamo tako, da za imenom polja zapišemo indeks v oglatem oklepaju. Vrednost izraza, ki predstavlja indeks, mora biti celoštevilčnega tipa. Indeks polja mora biti v območju [0, velikost polja-1], v našem primeru v območju [0, 3].
test[0] = 238;
238 test[0]test = 0x0012fe84
test[1]
test[2]
test[3]
POLJAPOMNILNIK
Fizični naslovi
Logični naslovi
Vsebina
Zaslon
int _tmain(int argc, _TCHAR* argv[]){ int test[4]; test[0] = 10; test[1] = 5; test[2] = 3; test[3] = 200; int vsota; vsota = test[0] + test[1] + test[2] + test[3]; printf("Vsota elementov polja je: %d\n“, vsota); return 0;}
Pri deklaraciji polja določimo podatkovni tip elementov polja, ime polja ter število elementov polja. Ime polja je konstantni kazalec, ki vsebuje fizični naslov prve lokacije prvega elementa polja.Pri deklaraciji polja prevajalnik dodeli začetni naslov in zadostno količino pomnilnika, kjer bodo shranjeni elementi polja. Začetni naslov polja je začetna lokacija v pomnilniku, kjer je polje shranjeno, in hkrati naslov prvega elementa polja (elementa z indeksom 0).
Inicializacija poljaInicializacija polja pomeni, da poleg definicije polja navedemo še vrednosti elementov, s katerimi polje napolnimo. Polje torej lahko inicializiramo tako, da med zavitimi oklepaji naštejemo vrednosti elementov, ki jih ločimo z vejicami.
int test[4] = {8, 7, 6, 4};
10 test[0]test = 0x0012fe84
test[1]
test[2]
test[3]
5
3
200
vsota2180x0012fe80
POLJAPOMNILNIK
Fizični naslovi
Logični naslovi
Vsebina
Zaslon
Prenos polja v funkcijo
const int vel_polja = 4;
int Sestej(int polje[vel_polja]){ int vsota=0; for (int i=0; i<vel_polja; i++) vsota += polje[i]; return vsota;}
int _tmain(int argc, _TCHAR* argv[]){ int prvo[vel_polja]; int drugo[vel_polja];
randomize(); for (int i=0; i<vel_polja; i++) { prvo[i] = random(31); drugo[i] = prvo[i] * prvo[i]; } printf("Prvo polje: %d %d %d %d\n", prvo[0], prvo[1], prvo[2], prvo[3]); printf("Drugo polje: %d %d %d %d\n", drugo[0], drugo[1], drugo[2], drugo[3]); printf("Vsota stevil je %d\n", Sestej(prvo)); printf("Vsota kvadratov je %d\n", Sestej(drugo)); return 0;}
drugo = 0x0012fe74 drugo[0]
vel_polja40x0014a960
prvo[0]
prvo[1]
prvo[2]
prvo[3]
drugo[1]
drugo[2]
drugo[3]
prvo = 0x0012fe84
POLJAPOMNILNIK
Fizični naslovi
Logični naslovi
Vsebina
Zaslon
Prenos polja se vedno izvaja po referenci. Vrednosti, ki jih v funkciji spremenimo v polju, ostanejo spremenjene tudi po zaključku funkcijeČe želimo polje prenesti v funkcijo, kot dejanski argument zapišemo ime polja: Sestej(prvo), formalni argument funkcije Sestej() pa zapišemo enako kot definiramo polje: int Sestej(int polje[vel_polja])Ob klicu funkcije se torej opravi deklaracija reference polja, ki ga navedemo kot dejanski argument pri klicu funkcije. (Npr.: int polje[vel_polja] = prvo; // oz. polje = prvo)V funkciji Sestej() uporabljamo konstantno spremenljivko vel_polja in jo zato definiramo globalno.Vemo, da lahko kazalcem prištevamo cela števila. Če mu prištejemo vrednost 1, se bo kazalec premaknil za toliko zlogov, kolikor je velikost tipa, na katerega kaže. Zapis (polje+i) pravzaprav pomeni (polje+i*sizeof(int)). Programerju torej ni potrebno skrbeti za pravilno premikanje kazalca ne glede na to, katerega podatkovnega tipa so elementi polja.Nad kazalci lahko izvajamo dve aritmetični operaciji. Prištevamo inodštevamo jim lahko cela števila ter jih med seboj odštevamo. Če kazalcu prištejemo ali od njega odštejemo celo število, dobimonovi kazalec, pri odštevanju dveh kazalcev pa dobimo celo število,ki pove razdaljo med kazalcema.
int _tmain(int argc, _TCHAR* argv[]){ const int velikost = 5; int polje[velikost] = {1, 10, 100, 1000, 10000}; int *zac_naslov = polje; // oz. &polje[0] int *konc_naslov = &polje[velikost-1]; int st_elementov = konc_naslov - zac_naslov + 1; printf("%d\n", st_elementov); return 0;}
polje = 0x0012fe74
polje[0]
velikost50x0014a960
polje[1]
polje[2]
polje[3]
polje[4]
0x0012fe70 zac_naslov
konc_naslov0x0012fe6c
0x0012fe74
0x0012fe84
st_elementov0x0012fe68 5
10000
100
100
10
1
PODATKOVNI TIPI V JEZIKU C++
Osnovni podatkovni tipi Sestavljeni podatkovni tipi
Celoštevilčni:
- int (zasede 4 zloge)
- short (2 zloga)
- long (4 zloge)
Znakovni:
- char (1 zlog)
Realni:
- float (4 zloge)
- double (8 zlogov)
- long double (8 zlogov)
Naštevni:
- enum (4 zloge)
Logični:
- bool (1 zlog)
Homogeni:
- polja
Nehomogeni:
- strukture
- unije
Izpeljani:
- kazalci (4 zloge)
- reference
STRUKTUREPOMNILNIK
Fizični naslovi
Logični naslovi
Vsebina
Zaslon
Struktura omogoča združitev podatkov različnega podatkovnega tipa v skupni objekt novega podatkovnega tipa. S strukturami združimo sorodne podatke pod enim imenom in jih nato obravnavamo kot celoto, ki vsebuje posamezne elemente, komponente oz. člene. Podatkom lahko še dodamo metode (funkcije), ki se izvajajo nad temi podatki.
Sintaksa:struct ime_strukture{ podatkovni_tip element1; podatkovni_tip element2; podatkovni_tip element3;} ime_objekta1, ime_objekta2;
Do posamezne komponente strukture dostopamo z izrazom ime_objekta.komponenta. Strukturni operator “.” naredi povezavo med imenom objekta in njegovo komponento.
Primer:struct naslov{ char mesto[20]; char ulica[20]; int postSt;} moj_naslov;
naslov naslov2;
moj_naslov.postSt = 2390;naslov2.postSt = 2380;
moj_naslov.mesto
2390 moj_naslov.postSt
moj_naslov.ulica
naslov2.mesto
2380 naslov2.postSt
naslov2.ulica
0x0012ff40
0x0012fe84
STRUKTURE
POMNILNIK
Fizični naslovi
Logični naslovi
Vsebina
Prenos strukture v funkcijo
Primer:enum spol {moski, zenski};struct datum{ int dan; int mesec; int leto;};struct oseba{ char ime_o[20]; spol spol_o; char naslov_o[30]; datum datum_r;};void IzpisiOsebo(oseba);
int _tmain(int argc, _TCHAR* argv[]){ oseba sosed = {"Marko", moski, "Trg svobode 13", {25, 2, 1998}}; IzpisiOsebo(sosed); oseba soseda = {"Klara", zenski, "Trg svobode 13", {6, 2, 1995}}; IzpisiOsebo(soseda); oseba klonSoseda; klonSoseda = soseda; klonSoseda.ime_o[4]='o'; klonSoseda.spol_o=moski; IzpisiOsebo(klonSoseda); return 0;}
void IzpisiOsebo(oseba nekdo){ printf("Ime osebe: %s\n", nekdo.ime_o); printf("Spol: %s\n", ((nekdo.spol_o == moski)?"moski":“zenski")); printf("Naslov: %s\n", nekdo.naslov_o); datum datum_r = nekdo.datum_r; printf("Datum rojstva: %d.%d.%d\n", datum_r.dan,
datum_r.mesec, datum_r.leto);
}
STRUKTUREPOMNILNIK
Fizični naslovi
Logični naslovi
Vsebina
Zaslon
Kazalci na strukture Kot pri ostalih podatkovnih tipih lahko tudi pri strukturah uporabimo kazalce. Kazalec definiramo kot kazalec na objekt strukture ter ga inicializiramo s fizičnim pomnilniškim naslovom, kjer se objekt te strukture nahaja v pomnilniku.
Primer:#include<iostream.h>#include<stdlib.h>struct str_film{ char naslov [70]; int leto;};
int _tmain(int argc, _TCHAR* argv[]){ char vmesnik[70]; str_film film, *kaz_film; kaz_film = &film; printf("Naslov: "); cin.getline(kaz_film->naslov, 70); printf("Leto: "); cin.getline(vmesnik, 70); kaz_film->leto = atoi(vmesnik); printf("\nVnesel si: %s (%d)\n", kaz_film->naslov, kaz_film->leto); return 0;}
Operator -> uporabljamo za dostop do posamezne komponente strukture, na katero kaže kazalec. Imenujemo ga dereferenčni operator. Namesto (*kaz_film).naslov lahko napišemo kaz_film->naslov.
PODATKOVNI TIPI V JEZIKU C++
Osnovni podatkovni tipi Sestavljeni podatkovni tipi
Celoštevilčni:
- int (zasede 4 zloge)
- short (2 zloga)
- long (4 zloge)
Znakovni:
- char (1 zlog)
Realni:
- float (4 zloge)
- double (8 zlogov)
- long double (8 zlogov)
Naštevni:
- enum (4 zloge)
Logični:
- bool (1 zlog)
Homogeni:
- polja
Nehomogeni:
- strukture
- unije
Izpeljani:
- kazalci (4 zloge)
- reference
UNIJE, Bitna polja
VARČEVANJE S SPOMINOMC++ nam omogoča varčevati s spominom na dva načina.Spremenljivke, ki obsegajo malo vrednosti, lahko opišemo s toliko biti, kot je to potrebno in nič več.Večje strukture pa lahko razbijemo glede na to, kaj trenutno lahko vsebujejo.
Bitna poljaPrecej potratno je za spremenljivko, ki lahko zasede samo dve vrednosti, uporabiti tip char, ki lahko zasede 256 vrednosti. Zato lahko več takšnih spremenljivk povežemo v strukturo, ki bo zavzela toliko prostora, kot ga spremenljivke potrebujejo. Bitna polja definiramo preprosto kot strukture, katere elementi so vsi tipa unsigned int, le da vsakemu elementu dodamo še podatek, ki pove število bitov, ki jih bo ta podatek zasedel:
struct tiskalnik{ unsigned prost : 1; unsigned pise : 1; unsigned papir_vstavljen : 1; unsigned tip_papirja : 1; unsigned font : 3;}
UnijeUnije so podobne strukturam, le da je v njih vedno veljaven le en element. Unija zasede vedno toliko prostora, kot ga zasede njen največji element:
#include <iostream.h>struct complex{ double re, im;};union vrednost{ int v_int; double v_dbl; complex v_cpx;};
void main(){ vrednost v; printf("Velikost celotne unije: %d\n", sizeof(vrednost)); printf("Velikost elementa int: %d\n", sizeof(v.v_int)); printf("Vel. elementa double: %d\n", sizeof(v.v_dbl)); printf("Vel. elementa complex: %d\n", sizeof(v.v_cpx)); printf("Naslovi spremenljivk so:\n"); printf("naslov v: %d\n", &v); printf("naslov v.v_int: %d\n", &v.v_int); printf("naslov v.v_dbl: %d\n", &v.v_dbl); printf("naslov v.v_cpx: %d\n", &v.v_cpx); printf("naslov v.v_cpx.re: %d\n", &v.v_cpx.re); printf("naslov v.v_cpx.im: %d\n\n", &v.v_cpx.im);}
GENERIRANJE NAKLJUČNIH ŠTEVIL
#include <stdlib.h>#include <stdio.h>#include <time.h>#define SPODNJA_M 65#define ST_ELEM 26
int main(void){ srand((unsigned)time(NULL));// Prikaz 10 naključnih števil. int i; for(i = 0; i < 10; i++) printf(" %6d\n", rand()); printf("\n");// Generiranje naključnih števil v razponu od 1 do 6: for (i = 0; i < 10; i++) { int rand100 = (((double)rand() / (double)RAND_MAX) * 6 + 1); printf( " %6d\n", rand100); } printf("\n");// Generiranje naključnih črk v razponu od A do Z: for (i = 0; i < 10; i++) { int rand100 = (((double)rand() / (double)RAND_MAX) * ST_ELEM + SPODNJA_M); printf( " %6c\n", (char)rand100); }}
POMNILNIK
Fizični naslovi
Logični naslovi
Vsebina
Zaslon
Naključna števila se generirajo na osnovi trenutnega časa. Zato so generirana števila vedno drugačna.
Naključna števila se generirajo na osnovi trenutnega časa. Zato so generirana števila vedno drugačna.
Običajno želimo generirati števila znotraj
nekega razpona.
Običajno želimo generirati števila znotraj
nekega razpona.
Delo z datotekami
Kaj je datoteka.
Datoteka je osnovna organizacijska enota z računalnikom zapisanih podatkov, pri čemer je podatek vse, kar lahko zapišemo na pomnilniški nosilec.
Vsebina vsake datoteke je niz binarnih števil. Njen binarni prikaz je nepregledna množica ničel in enic. Bolj pregleden je njen šestnajstiški zapis, ker je vsak bajt predstavljen le z dvema šestnajstiškima števkama. Seveda bo nam najbolj razumljiv izpis datoteke v obliki ASCII znakov, vendar bo tak izpis smiseln le, če datoteka predstavlja besedilo.
Vsaka datoteka ima svoje ime in zaseda določen prostor na disku. Lahko je različnega tipa – lahko vsebuje besedilo, lahko so izvršljive in podobno. Katerega tipa je datoteka, pa nam pove njena končnica, npr. .doc, .exe, .bmp itn.
Pri delu z datotekami upoštevamo standardno zaporedje postopkov:
1. Deklariramo datotečni kazalec
2. Odpremo podatkovni tok in ga usmerimo proti datoteki
3. Beremo ali zapisujemo podatke (z zanko while)
4. Datoteko zapremo
POMNILNIK
Fizični naslovi
Logični naslovi
Vsebina
Zaslon
Delo z datotekami
Primer:
char beseda[30]; FILE* tok1; tok1 = fopen("c:\\test1.txt", "rt"); while(! feof(tok1)) { fscanf(tok1, "%s", beseda); printf("%s\n", beseda); } fclose(tok1);
Datoteko lahko odpremo v različnih načinih. Najpogostejši so:
"r" - odpre datoteko za branje; če datoteka ne obstaja, vrne fopen vrednost NULL."w" - odpre prazno datoteko za pisanje; če datoteka že obstaja, bo njena vsebina zbrisana."a" - odpre datoteko za dodajanje teksta na konec; če datoteka ne obstaja, jo fopen ustvari."r+" - odpre datoteko za branje in pisanje; datoteka mora obstajati."w+" - odpre prazno datoteko za branje in pisanje; če datoteka že obstaja, bo njena vsebina uničena.
POMNILNIK
Fizični naslovi
Logični naslovi
Vsebina
Delo z datotekami
Nekatere funkcije (metode razreda FILE) za delo z datotekami:
fopen(…) – odpre datoteko,
fclose(…) – zapre datoteko,
feof(…) – ugotavlja konec datoteke,
fscanf(…) – formatirano branje iz datoteke,
fprintf(…) – formatirano pisanje v datoteko,
rewind(…) – vrnitev datotečnega kazalca na začetek,
fgetc(…) – branje enega znaka,
fputc(…) – pisanje enega znaka,
fread(…) – neformatirano branje,
fwrite(…) – neformatirano pisanje,
fgetpos(…) – vrne pozicijo datotečnega kazalca,
fsetpos(…) – nastavi pozicijo datotečnega kazalca, …
POMNILNIK
Fizični naslovi
Logični naslovi
Vsebina
Delo z datotekami
Še en primer programa:
int _tmain(int argc, _TCHAR* argv[]){ int stevila[10] = {123,231,304,512,8,65,66,67,10,13}; FILE* tok1; tok1 = fopen("c:\\Zdravko\\Šola\\test1.bin", "w"); fwrite(stevila, sizeof(int), 10, tok1); fclose(tok1); printf("Konec\n"); return 0;}
POMNILNIK
Fizični naslovi
Logični naslovi
Vsebina
Zaslon
Urejanje podatkov
Podatke v tabelah lahko uredimo na več možnih načinov:
Urejanje po metodi izbora najmanjšega elementa:• poiščemo najmanjše število v neurejeni tabeli,• postavimo ga na prvo mesto neurejenega dela tabele, hkrati pa število, ki je bilo do tedaj na prvem mestu neurejenega dela tabele, postavimo na mesto, na katerem smo našli najmanjše število v neurejeni tabeli,• neurejeni del tabele se s tem zmanjša za eno število,• to ponavljamo dokler v neurejenem delu tabele ne ostane samo eno število, ki je hkrati največje v urejeni tabeli.
#define DIM 5void UrediTabelo(int[], int);int Najmanjse(int[], int, int);
int _tmain(int argc, _TCHAR* argv[]){ int stevila[DIM] = {304, 231, 123, 512, 66}; UrediTabelo(stevila, DIM); for(int i = 0; i < DIM; i++) printf("%d\n", stevila[i]); return 0;}
POMNILNIK
Fizični naslovi
Logični naslovi
Vsebina
Zaslon
5 DIM
66
512
123
231
304 stevila[0]
stevila[1]
stevila[2]
stevila[3]
stevila[4]
void UrediTabelo(int tabela[], int dim){ int indeks, pom; for(int i = 0; i < dim-1; i++) { indeks = Najmanjse(tabela, dim, i); pom = tabela[i]; tabela[i] = tabela[indeks]; tabela[indeks] = pom; }}
int Najmanjse(int polje[], int ki, int zi){ int najS = polje[zi]; int ind = zi; for(int j = zi+1; j < ki; j++) { if(polje[j] < najS) { najS = polje[j]; ind = j; } } return ind;}
POMNILNIK
Fizični naslovi
Logični naslovi
Vsebina
Zaslon
Urejanje podatkov
5 DIM, dim
66
512
123
231
304 stevila[0], tabela[0]
stevila[1], tabela[1]
stevila[2], tabela[2]
stevila[3], tabela[3]
stevila[4], tabela[4]
indeks
pom
i
void UrediTabelo(int tabela[], int dim){ int indeks, pom; for(int i = 0; i < dim-1; i++) { indeks = Najmanjse(tabela, dim, i); pom = tabela[i]; tabela[i] = tabela[indeks]; tabela[indeks] = pom; }}
int Najmanjse(int polje[], int ki, int zi){ int najS = polje[zi]; int ind = zi; for(int j = zi+1; j < ki; j++) { if(polje[j] < najS) { najS = polje[j]; ind = j; } } return ind;}
POMNILNIK
Fizični naslovi
Logični naslovi
Vsebina
Zaslon
Urejanje podatkov
5 DIM, dim, ki
66
512
123
231
304 stevila[0], tabela[0], polje[0]
stevila[1], tabela[1], polje[1]
stevila[2], tabela[2], polje[2]
stevila[3], tabela[3], polje[3]
stevila[4], tabela[4], polje[4]
indeks
pom
najS
ind
i, zi
j
Urejanje podatkov
Urejanje po metodi mehurčkov (Bubble sort):
• začnemo na začetku tabele, primerjamo i-ti in i+1-vi element tabele; če nista v predpisanem zaporedju, ju zamenjamo,
• v enem prehodu skozi tabelo pomaknemo največje število na konec tabele, manjša števila pa pomikamo proti začetku tabele,
• zgornja koraka ponavljamo dokler ni tabela urejena.
#define DIM 5void Bubble(int[], int);
int _tmain(int argc, _TCHAR* argv[]){ int stevila[DIM] = {304, 231, 123, 512, 66}; Bubble(stevila, DIM); for(int i = 0; i < DIM; i++) printf("%d\n", stevila[i]); return 0;}
POMNILNIK
Fizični naslovi
Logični naslovi
Vsebina
Zaslon
5 DIM
66
512
123
231
304 stevila[0]
stevila[1]
stevila[2]
stevila[3]
stevila[4]
void Bubble(int tabela[], int n){ int pom; for(int i = 0; i < n; i++) { for(int j = 0; j < n-1; j++) { if(tabela[j] > tabela[j+1]) {
pom = tabela[j];tabela[j] = tabela[j+1];tabela[j+1] = pom;
} } }}
POMNILNIK
Fizični naslovi
Logični naslovi
Vsebina
Zaslon
Urejanje podatkov
5 DIM, n
66
512
123
231
304 stevila[0], tabela[0]
stevila[1], tabela[1]
stevila[2], tabela[2]
stevila[3], tabela[3]
stevila[4], tabela[4]
j
pom
i
Urejanje podatkov
Urejanje z vstavljanjem:
Vse elemente od drugega mesta do konca tabele vstavimo na ustrezno mesto v urejeni del tabele.
Vedno primerjamo vrednost elementa, ki ga vstavljamo z vsemi predhodnimi elementi v urejenem delu tabele.Pri tem vse večje elemente pomikamo za eno mesto v desno, da pridobimo prostor za vstavljanje na ustrezno mesto v urejenem delu tabele.Z ustreznim vstavljanjem enega elementa se urejeni del tabele poveča za ena.
#define DIM 5void UrediVstavi(int[], int);
int _tmain(int argc, _TCHAR* argv[]){ int stevila[DIM] = {304, 231, 123, 512, 66}; UrediVstavi(stevila, DIM); for(int i = 0; i < DIM; i++) printf("%d\n", stevila[i]); return 0;}
POMNILNIK
Fizični naslovi
Logični naslovi
Vsebina
Zaslon
5 DIM
66
512
123
231
304 stevila[0]
stevila[1]
stevila[2]
stevila[3]
stevila[4]
void UrediVstavi(int tabela[ ], int n){ int element; for(int i = 1; i < n; i++) { element = tabela[i]; for(int j = 0; j < i; j++) { if(element < tabela[j]) {
for(int k = i-1; k >= j; k--){ tabela[k+1] = tabela[k];}tabela[j] = element;break;
} } }}
POMNILNIK
Fizični naslovi
Logični naslovi
Vsebina
Zaslon
Urejanje podatkov
5 DIM, n
66
512
123
231
304 stevila[0], tabela[0]
stevila[1], tabela[1]
stevila[2], tabela[2]
stevila[3], tabela[3]
stevila[4], tabela[4]
element
i
i
k
Podatke v tabelah lahko poiščemo na več načinov.
Zaporedno iskanje:
#define DIM 5int PoisciZaporedno(int[], int, int);
int _tmain(int argc, _TCHAR* argv[]){ int iskanoSt = 123; int stevila[DIM] = {304,231,123,512, 66}; int ind = PoisciZaporedno(stevila, DIM, iskanoSt); if(ind >= 0) printf("%d je v tabeli na indeksu %d\n", iskanoSt, ind); else printf("%d ni v tabeli\n", iskanoSt);
return 0;}
int PoisciZaporedno(int tabela[], int n, int stevilo){ int indeks; for(indeks = 0; indeks < n; indeks++) { if(tabela[indeks] == stevilo) return indeks; } return (-1);}
POMNILNIK
Fizični naslovi
Logični naslovi
Vsebina
Zaslon
Iskanje podatkov
5 DIM, n
66
512
123
231
304 stevila[0], tabela[0]
stevila[1], tabela[1]
stevila[2], tabela[2]
stevila[3], tabela[3]
stevila[4], tabela[4]
iskanoSt, stevilo
ind
indeks
123
Podatke v tabelah lahko poiščemo na več načinov.
Binarno iskanje:Pogoj za binarno iskanje je, da so elementi tabele urejeni po velikosti. Urejeno tabelo razdelimo enakomerno na dve polovici. Iskani podatek je lahko v prvi ali drugi polovici. Ustrezno polovico tabele izberemo s pomočjo primerjave iskanega podatka s sredinskim elementom tabele. Tako izločimo polovico tabele. Iskanje nadaljujemo na isti način v izbrani polovici. V dveh korakih izločimo tri četrtine podatkov. Postopek ponavljamo dokler ne najdemo števila, ki ga iščemo ali dokler ne ugotovimo, da iskanega števila ni v tabeli.
#define DIM 5int PoisciBinarno(int[], int, int);
int _tmain(int argc, _TCHAR* argv[]){ int iskanoSt = 304; int stevila[DIM] = {66, 123, 231, 304, 512}; int ind = PoisciBinarno(stevila, DIM, iskanoSt); if(ind >= 0) printf("%d je v tabeli na indeksu %d\n", iskanoSt, ind); else printf("%d ni v tabeli\n", iskanoSt);
return 0;}
POMNILNIK
Fizični naslovi
Logični naslovi
Vsebina
Zaslon
Iskanje podatkov
5 DIM
512
304
231
123
66 stevila[0]
stevila[1]
stevila[2]
stevila[3]
stevila[4]
iskanoSt
ind
304
int PoisciBinarno(int tabela[ ], int n, int stevilo){ int sredina; int spodaj = 0; int zgoraj = n-1; while(spodaj <= zgoraj) { sredina = (spodaj+zgoraj)/2; if(stevilo > tabela[sredina])
spodaj = sredina + 1; else if(stevilo < tabela[sredina])
zgoraj = sredina; else
return sredina; } return (-1);}
POMNILNIK
Fizični naslovi
Logični naslovi
Vsebina
Zaslon
Iskanje podatkov
5 DIM, n
512
304
231
123
66 stevila[0], tabela[0]
stevila[1], tabela[1]
stevila[2], tabela[2]
stevila[3], tabela[3]
stevila[4], tabela[4]
iskanoSt, stevilo
sredina
spodaj
304
zgoraj
Rekurzivne funkcije so takšne funkcije, ki kličejo same sebe. Uporabljamo jih takrat, ko lažje izrazimo rešitev problema tako, da se pri rešitvi sklicujemo na rešitev samo.Primer Faktoriela (rekurzivna definicija):
n! = n * (n-1) * (n-2) * … * 3 * 2 * 1To lahko zapišemo tudi na drugi način:
n * (n-1) * (n-2) * … * 3 * 2 * 1 = n * (n-1)!Po predpostavki, da je 1! enaka 1 lahko zapišemo naslednji program:
int _tmain(int argc, _TCHAR* argv[]){ printf("%d\n", fakt(4)); return 0;}
int fakt(int n){ if (n == 1) return 1; return n * fakt(n - 1);}
POMNILNIK
Fizični naslovi
Logični naslovi
Vsebina
Zaslon
REKURZIJA
fakt(4)
4*
Rekurzivne funkcije so takšne funkcije, ki kličejo same sebe. Uporabljamo jih takrat, ko lažje izrazimo rešitev problema tako, da se pri rešitvi sklicujemo na rešitev samo.Primer Faktoriela (rekurzivna definicija):
n! = n * (n-1) * (n-2) * … * 3 * 2 * 1To lahko zapišemo tudi na drugi način:
n * (n-1) * (n-2) * … * 3 * 2 * 1 = n * (n-1)!Po predpostavki, da je 1! enaka 1 lahko zapišemo naslednji program:
int _tmain(int argc, _TCHAR* argv[]){ printf("%d\n", fakt(4)); return 0;}
int fakt(int n){ if (n == 1) return 1; return n * fakt(n - 1);}
POMNILNIK
Fizični naslovi
Logični naslovi
Vsebina
Zaslon
REKURZIJA
fakt(4)
4*
fakt(3)
3*
Rekurzivne funkcije so takšne funkcije, ki kličejo same sebe. Uporabljamo jih takrat, ko lažje izrazimo rešitev problema tako, da se pri rešitvi sklicujemo na rešitev samo.Primer Faktoriela (rekurzivna definicija):
n! = n * (n-1) * (n-2) * … * 3 * 2 * 1To lahko zapišemo tudi na drugi način:
n * (n-1) * (n-2) * … * 3 * 2 * 1 = n * (n-1)!Po predpostavki, da je 1! enaka 1 lahko zapišemo naslednji program:
int _tmain(int argc, _TCHAR* argv[]){ printf("%d\n", fakt(4)); return 0;}
int fakt(int n){ if (n == 1) return 1; return n * fakt(n - 1);}
POMNILNIK
Fizični naslovi
Logični naslovi
Vsebina
Zaslon
REKURZIJA
fakt(4)
4*
fakt(3)
3*
fakt(2)
2*
Rekurzivne funkcije so takšne funkcije, ki kličejo same sebe. Uporabljamo jih takrat, ko lažje izrazimo rešitev problema tako, da se pri rešitvi sklicujemo na rešitev samo.Primer Faktoriela (rekurzivna definicija):
n! = n * (n-1) * (n-2) * … * 3 * 2 * 1To lahko zapišemo tudi na drugi način:
n * (n-1) * (n-2) * … * 3 * 2 * 1 = n * (n-1)!Po predpostavki, da je 1! enaka 1 lahko zapišemo naslednji program:
int _tmain(int argc, _TCHAR* argv[]){ printf("%d\n", fakt(4)); return 0;}
int fakt(int n){ if (n == 1) return 1; return n * fakt(n - 1);}
POMNILNIK
Fizični naslovi
Logični naslovi
Vsebina
Zaslon
REKURZIJA
fakt(4)
4*
fakt(3)
3*
fakt(2)
2*
fakt(1)
1
Rekurzivne funkcije so takšne funkcije, ki kličejo same sebe. Uporabljamo jih takrat, ko lažje izrazimo rešitev problema tako, da se pri rešitvi sklicujemo na rešitev samo.Primer Faktoriela (rekurzivna definicija):
n! = n * (n-1) * (n-2) * … * 3 * 2 * 1To lahko zapišemo tudi na drugi način:
n * (n-1) * (n-2) * … * 3 * 2 * 1 = n * (n-1)!Po predpostavki, da je 1! enaka 1 lahko zapišemo naslednji program:
int _tmain(int argc, _TCHAR* argv[]){ printf("%d\n", fakt(4)); return 0;}
int fakt(int n){ if (n == 1) return 1; return n * fakt(n - 1);}
POMNILNIK
Fizični naslovi
Logični naslovi
Vsebina
Zaslon
REKURZIJA
fakt(4)
4*
fakt(3)
3*
fakt(2)
2*
fakt(1)
1
1
Rekurzivne funkcije so takšne funkcije, ki kličejo same sebe. Uporabljamo jih takrat, ko lažje izrazimo rešitev problema tako, da se pri rešitvi sklicujemo na rešitev samo.Primer Faktoriela (rekurzivna definicija):
n! = n * (n-1) * (n-2) * … * 3 * 2 * 1To lahko zapišemo tudi na drugi način:
n * (n-1) * (n-2) * … * 3 * 2 * 1 = n * (n-1)!Po predpostavki, da je 1! enaka 1 lahko zapišemo naslednji program:
int _tmain(int argc, _TCHAR* argv[]){ printf("%d\n", fakt(4)); return 0;}
int fakt(int n){ if (n == 1) return 1; return n * fakt(n - 1);}
POMNILNIK
Fizični naslovi
Logični naslovi
Vsebina
Zaslon
REKURZIJA
fakt(4)
4*
fakt(3)
3*
fakt(2)
2*
fakt(1)
1
12
Rekurzivne funkcije so takšne funkcije, ki kličejo same sebe. Uporabljamo jih takrat, ko lažje izrazimo rešitev problema tako, da se pri rešitvi sklicujemo na rešitev samo.Primer Faktoriela (rekurzivna definicija):
n! = n * (n-1) * (n-2) * … * 3 * 2 * 1To lahko zapišemo tudi na drugi način:
n * (n-1) * (n-2) * … * 3 * 2 * 1 = n * (n-1)!Po predpostavki, da je 1! enaka 1 lahko zapišemo naslednji program:
int _tmain(int argc, _TCHAR* argv[]){ printf("%d\n", fakt(4)); return 0;}
int fakt(int n){ if (n == 1) return 1; return n * fakt(n - 1);}
POMNILNIK
Fizični naslovi
Logični naslovi
Vsebina
Zaslon
REKURZIJA
fakt(4)
4*
fakt(3)
3*
fakt(2)
2*
fakt(1)
1
126
Rekurzivne funkcije so takšne funkcije, ki kličejo same sebe. Uporabljamo jih takrat, ko lažje izrazimo rešitev problema tako, da se pri rešitvi sklicujemo na rešitev samo.Primer Faktoriela (rekurzivna definicija):
n! = n * (n-1) * (n-2) * … * 3 * 2 * 1To lahko zapišemo tudi na drugi način:
n * (n-1) * (n-2) * … * 3 * 2 * 1 = n * (n-1)!Po predpostavki, da je 1! enaka 1 lahko zapišemo naslednji program:
int _tmain(int argc, _TCHAR* argv[]){ printf("%d\n", fakt(4)); return 0;}
int fakt(int n){ if (n == 1) return 1; return n * fakt(n - 1);}
POMNILNIK
Fizični naslovi
Logični naslovi
Vsebina
Zaslon
REKURZIJA
fakt(4)
4*
fakt(3)
3*
fakt(2)
2*
fakt(1)
1
12624
Naloga:
1. Napišite rekurzivno funkcijo, ki poišče vsoto N celih števil.
2. Napišite rekurzivno funkcijo, ki vpisana števila izpiše v obratnem vrstnem redu.
POMNILNIK
Fizični naslovi
Logični naslovi
Vsebina
Zaslon
REKURZIJA
Oglejmo si zaporedje Fibonaccijevih števil: 0, 1, 1, 2, 3, 5, 8, 13, 21, ...
To zaporedje je definirano z naslednjo enačbo: fib(n) = fib(n - 1) + fib(n - 2)Pri tem velja, da je fib(0) = 0 in fib(1) = 1
Program, ki računa Fibonaccijeva števila je naslednji:
int _tmain(int argc, _TCHAR* argv[]){ printf("%d\n", fib(5)); return 0;}
int fib(int n){ if(n <= 0) return 0; else if(n == 1) return 1; else return fib(n - 1) + fib(n - 2) ;}
POMNILNIK
Fizični naslovi
Logični naslovi
Vsebina
Zaslon
DREVESNA REKURZIJA
fib(5)
DREVESNA REKURZIJA
fib(5)
fib(4) fib(3)
DREVESNA REKURZIJA
fib(5)
fib(4) fib(3)
DREVESNA REKURZIJA
fib(5)
fib(4) fib(3)
fib(3) fib(2)
DREVESNA REKURZIJA
fib(5)
fib(4) fib(3)
fib(3) fib(2)
DREVESNA REKURZIJA
fib(5)
fib(4) fib(3)
fib(3) fib(2)
fib(2) fib(1)
DREVESNA REKURZIJA
fib(5)
fib(4) fib(3)
fib(3) fib(2)
fib(2) fib(1)
DREVESNA REKURZIJA
fib(5)
fib(4) fib(3)
fib(3) fib(2)
fib(2) fib(1)
fib(1) fib(0)
DREVESNA REKURZIJA
fib(5)
fib(4) fib(3)
fib(3) fib(2)
fib(2) fib(1)
fib(1) fib(0)
DREVESNA REKURZIJA
fib(5)
fib(4) fib(3)
fib(3) fib(2)
fib(2) fib(1)
fib(1) fib(0)
1
DREVESNA REKURZIJA
fib(5)
fib(4) fib(3)
fib(3) fib(2)
fib(2) fib(1)
fib(1) fib(0)
1
DREVESNA REKURZIJA
fib(5)
fib(4) fib(3)
fib(3) fib(2)
fib(2) fib(1)
1 fib(0)
1
DREVESNA REKURZIJA
fib(5)
fib(4) fib(3)
fib(3) fib(2)
fib(2) fib(1)
1 fib(0)
1
DREVESNA REKURZIJA
fib(5)
fib(4) fib(3)
fib(3) fib(2)
fib(2) fib(1)
1 fib(0)
1 0
DREVESNA REKURZIJA
fib(5)
fib(4) fib(3)
fib(3) fib(2)
fib(2) fib(1)
1 fib(0)
1 0
DREVESNA REKURZIJA
fib(5)
fib(4) fib(3)
fib(3) fib(2)
fib(2) fib(1)
1 0
1 0
DREVESNA REKURZIJA
fib(5)
fib(4) fib(3)
fib(3) fib(2)
1 fib(1)
1 0
1 0
DREVESNA REKURZIJA
fib(5)
fib(4) fib(3)
fib(3) fib(2)
1 fib(1)
1 0
1 0
DREVESNA REKURZIJA
fib(5)
fib(4) fib(3)
fib(3) fib(2)
1 fib(1)
1 0
1
1
0
DREVESNA REKURZIJA
fib(5)
fib(4) fib(3)
fib(3) fib(2)
1 fib(1)
1 0
1
1
0
DREVESNA REKURZIJA
fib(5)
fib(4) fib(3)
fib(3) fib(2)
1 1
1 0
1
1
0
DREVESNA REKURZIJA
fib(5)
fib(4) fib(3)
2 fib(2)
1 1
1 0
1
1
0
DREVESNA REKURZIJA
fib(5)
fib(4) fib(3)
2 fib(2)
1 1
1 0
1
1
0
DREVESNA REKURZIJA
fib(5)
fib(4) fib(3)
2 fib(2)
1 1 fib(1) fib(0)
1 0
1
1
0
DREVESNA REKURZIJA
fib(5)
fib(4) fib(3)
2 fib(2)
1 1 fib(1) fib(0)
1 0
1
1
0
DREVESNA REKURZIJA
fib(5)
fib(4) fib(3)
2 fib(2)
1 1 fib(1) fib(0)
1 0
1
1 1
0
DREVESNA REKURZIJA
fib(5)
fib(4) fib(3)
2 fib(2)
1 1 fib(1) fib(0)
1 0
1
1 1
0
DREVESNA REKURZIJA
fib(5)
fib(4) fib(3)
2 fib(2)
1 1 1 fib(0)
1 0
1
1 1
0
DREVESNA REKURZIJA
fib(5)
fib(4) fib(3)
2 fib(2)
1 1 1 fib(0)
1 0
1
1 1
0
DREVESNA REKURZIJA
fib(5)
fib(4) fib(3)
2 fib(2)
1 1 1 fib(0)
1 0
1
1 1
0
0
DREVESNA REKURZIJA
fib(5)
fib(4) fib(3)
2 fib(2)
1 1 1 fib(0)
1 0
1
1 1
0
0
DREVESNA REKURZIJA
fib(5)
fib(4) fib(3)
2 fib(2)
1 1 1 0
1 0
1
1 1
0
0
DREVESNA REKURZIJA
fib(5)
fib(4) fib(3)
2 1
1 1 1 0
1 0
1
1 1
0
0
DREVESNA REKURZIJA
fib(5)
3 fib(3)
2 1
1 1 1 0
1 0
1
1 1
0
0
DREVESNA REKURZIJA
fib(5)
3 fib(3)
2 1
1 1 1 0
1 0
1
1 1
0
0
. . . . .
DREVESNA REKURZIJA
fib(5)
3 fib(3)
2 1 1 1
1 1 1 0 1 0
1 0
1
1 1 1
1
0
0 0
DREVESNA REKURZIJA
fib(5)
3 2
2 1 1 1
1 1 1 0 1 0
1 0
1
1 1 1
1
0
0 0
DREVESNA REKURZIJA
5
3 2
2 1 1 1
1 1 1 0 1 0
1 0
1
1 1 1
1
0
0 0
DREVESNA REKURZIJA