Avditorne vaje Podprogrami v C ju Podprogrami v C‐ju • Napišite podprogram v programskem jeziku / p C/C++, ki bo vrnil polovico absolutne vrednosti vsote treh celih števil, brez uporabe matematične funkcije abs Rezultat naj bo matematične funkcije abs. Rezultat naj bo realno število. Podprogrami v C ju Podprogrami v C‐ju • Napišite podprogram v programskem jeziku / p C/C++, ki bo vrnil polovico absolutne vrednosti vsote treh celih števil, brez uporabe matematične funkcije abs Rezultat naj bo matematične funkcije abs. Rezultat naj bo realno število. Podprogram, ki vrne neko vrednost, je funkcija Podprogrami v C ju Podprogrami v C‐ju • Napišite podprogram v programskem jeziku / p C/C++, ki bo vrnil polovico absolutne vrednosti vsote treh celih števil, brez uporabe matematične funkcije abs Rezultat naj bo matematične funkcije abs. Rezultat naj bo realno število. Kaj je absolutna vrednost števila? abs(4) = 4 ||X|| abs(‐4) = 4 b( ) Negativne vrednosti postanejo pozitivne. Pozitivne vrednosti ostanejo pozitivne. Podprogrami v C ju Podprogrami v C‐ju • Napišite podprogram v programskem jeziku / p C/C++, ki bo vrnil polovico absolutne vrednosti vsote treh celih števil, brez uporabe matematične funkcije abs Rezultat naj bo matematične funkcije abs. Rezultat naj bo realno število. Kakšne parametre potrebujemo? Tri cela števila. Podprogrami v C ju Podprogrami v C‐ju • Napišite podprogram v programskem jeziku / p C/C++, ki bo vrnil polovico absolutne vrednosti vsote treh celih števil, brez uporabe matematične funkcije abs Rezultat naj bo matematične funkcije abs. Rezultat naj bo realno število. Kakšne je rezultat funkcije? Realno število. Ker ni določeno ž l želena natančnost (ali float č ( l fl ali double), l d bl ) izberemo enega izmed njiju. Podprogrami v C ju Podprogrami v C‐ju • Napišite podprogram v programskem jeziku / p C/C++, ki bo vrnil polovico absolutne vrednosti vsote treh celih števil, brez uporabe matematične funkcije abs Rezultat naj bo matematične funkcije abs. Rezultat naj bo realno število. Kaj podprogram naj naredi? 1. Izračuna vsoto 2. Določi absolutno vrednost l č b l d 3. Vrne polovico te vrednosti Ime podprograma ni bilo podano, zato si ga izmislimo sami Zgled double d bl absvsota2(int b t 2(i t a,int i t b, b int i t c)) { int vsota = a+b+c; if(vsota<0) vsota = -vsota; return vsota/2.0; } Parametri so cela števila a,b,c. Rezultat je realno število tipa double. Zgled double d bl absvsota2(int b t 2(i t a,int i t b, b int i t c)) { int vsota = a+b+c; if(vsota<0) vsota = -vsota; return vsota/2.0; } Zgled Deklaracija pomožne spremenljivke in Deklaracija pomožne spremenljivke in izračun vsote. Lahko bi napisali ločeno. double d bl absvsota2(int b t 2(i t a,int i t b, b int i t c)) { int vsota = a+b+c; if(vsota<0) vsota = -vsota; return vsota/2.0; } Zgled Izračun absolutne vrednosti vsote. Negativne vrednosti pretvorimo v pozitivne s spremembo predznaka pozitivne s spremembo predznaka (ali z množenjem z ‐1). double d bl absvsota2(int b t 2(i t a,int i t b, b int i t c)) { int vsota = a+b+c; if(vsota<0) vsota = -vsota; return vsota/2.0; } Zgled floatt absvsota2(int fl b t 2(i t a,int i t b, b int i t c)) { int vsota = a+b+c; if(vsota<0) vsota = -vsota; return vsota/2.0; } Rezultat je polovica izračunane Rezultat je polovica izračunane vsote. Ker želimo kot rezultat realno število, se moramo izogniti celoštevilčnemu deljenju. Zato vsoto j j delimo z 2.0 (namesto z 2). Velikost podatkov sizeof Velikost podatkov ‐ • Velikost spremenljivk in drugih podatkov nam lik lji k i d ih d k pove koliko pomnilniškega prostora računalnika ("spomina") je potrebno za njihovo hrambo • Velikost podatkov je odvisna od načina p predstavitve teh podatkov v računalniku p • Velikost podatkov v programskem jeziku C izvemo z operatorjem (funkcijo ukazom) izvemo z operatorjem (funkcijo, ukazom) sizeof sizeof <izraz> sizeof (<podatkovni tip>) Velikost podatkov sizeof Velikost podatkov ‐ • Enostavni podatkovni tipi char c; int a; float x; double y y; 1 4 c a 4 8 • Velikost Velikost je enaka število zlogov, ki je enaka število zlogov ki ga zaseda podatek v pomnilniku x y Velikost podatkov sizeof Velikost podatkov ‐ • Polja int a[5],b[4][3]; • Podatki si sledijo od nižjih indeksov proti višjim in indeksov proti višjim in od nižjih dimenzij proti višjim išji • Velikost: <velikost tipa podatka> * <število elementov dimenzije 1> * <število elementov dimenzije 2> * … j a[0] a[1] a[2] a[3] a[4] b[0][0] b[0][1] b[0][2] b[1][0] b[1][1] b[1][2] b[2][0] b[2][1] b[2][2] b[3][0] b[3][1] b[3][2] Velikost podatkov sizeof Velikost podatkov ‐ • Strukture struct datum { int leto, mesec, dan; } d; • Podatki Podatki si v pomnilniku sledijo en za drugim v si v pomnilniku sledijo en za drugim v istem vrstnem redu kot so navedeni v d kl deklaraciji iji d.leto d d.mesec d.dan • Velikost Velikost je enaka vsoti velikosti posameznih je enaka vsoti velikosti posameznih komponent Velikost podatkov sizeof Velikost podatkov ‐ • Znakovni Znakovni nizi nizi Če je število elementov polja pri znakovnem nizu podano eksplicitno (neposredno), je d k l ( d ) velikost podatka enaka tej dimenziji Če znakovnemu nizu ne določimo dimenzije in ga inicializiramo s konstantnim nizom znakov ga inicializiramo s konstantnim nizom znakov (med dvojnim narekovaji), moramo upoštevati, da prevajalnik avtomatsko doda še št ti d j l ik t tk d d š en znak (oznako konca niza ‐ '\0') Zgled char niz1[100] niz1[100] = "ABC"; ABC ; char niz2[] = "ABC"; 0 niz1 ‘A’ ‘B’ ‘A’ ‘B’ ‘C’ ‘\0’ ‘C’ ‘\0’ 0 niz2 99 3 ‘A’ ‘B’ ‘C’ ‘\0’ … Velikost podatkov sizeof Velikost podatkov ‐ • Kaj izpiše naslednji segment programa (1)? p j j p predstavljen z p j Predpostavka je, da je tip int 32 biti. char niz1[] = "ABC"; char niz2[20] = "Pozdrav\n"; int a[10]; printf("%d %d %d %d\n",sizeof niz1,sizeof niz2, sizeof a, sizeof a[0]); Zgled niz1 nima neposredno podane dimenzije zato odloča velikost dimenzije, zato odloča velikost (število znakov) znakovne konstante (+ znak za konec) char niz1[] = "ABC"; 3+1=4 char niz2[20] = "Pozdrav\n"; int a[10]; printf("%d %d %d %d\n",sizeof niz1,sizeof niz2, sizeof a, sizeof a[0]); Zgled niz2 ima neposredno podano dimenzijo Konstantni niz ki mu dimenzijo. Konstantni niz, ki mu ga priredimo, na velikost ne vpliva. char niz1[] = "ABC"; char niz2[20] = "Pozdrav\n"; 20 int a[10]; printf("%d %d %d %d\n",sizeof niz1,sizeof niz2, sizeof a, sizeof a[0]); Zgled a je polje celih števil z 10 elementi Velikost je torej elementi. Velikost je torej desetkratnik velikosti celega števila. char niz1[] = "ABC"; char niz2[20] = "Pozdrav\n"; int a[10]; 10*4 40 10*4=40 printf("%d %d %d %d\n",sizeof niz1,sizeof niz2, sizeof a, sizeof a[0]); Zgled a[0] je prvi element polja celih števil elementi Velikost tega števil elementi. Velikost tega elementa je enaka velikosti celega števila. char niz1[] = "ABC"; char niz2[20] = "Pozdrav\n"; int a[10]; printf("%d %d %d %d\n",sizeof niz1,sizeof niz2, sizeof a, sizeof a[0]); 4 Zgled char niz1[] = "ABC"; char niz2[20] = "Pozdrav\n"; int a[10]; printf("%d %d %d %d\n",sizeof niz1,sizeof niz2, sizeof a, sizeof a[0]); 4 20 40 4 Podatkovne strukture Podatkovne strukture • Implementacija kompleksnejših nalog je brez p p p uporabe ustreznih podatkovnih tipov in podatkovnih struktur veliko težja. • Podatkovne strukture združujejo logično Podatkovne strukture združujejo logično povezane podatke v celoto in jih povežejo s podprogrami za delo z njimi l Zgled: • Naloga: p Sestavite ustrezne podatkovne strukture, ki bodo omogočale predstavitev podatkov ene igralne karte Izdelajte ustrezne podprograme igralne karte. Izdelajte ustrezne podprograme za branje in izpis podatkov ene karte in jih preizkusite s testnim programom preizkusite s testnim programom. Zgled: • A Analiza in (delna) razgradnja problema: li i (d l ) d j bl Igralne karte imajo štiri barve (srce, karo, pik in križ) ter 13 različnih vrednosti (dvojka trojka ter 13 različnih vrednosti (dvojka, trojka, …, desetka, desetka fant, dama, kraj in as). • Barvo bomo predstavili z naštevnim podatkovnim Barvo bomo predstavili z naštevnim podatkovnim tipom, vrednost pa z celim številom. Oboje bomo povezali v strukturo povezali v strukturo. • Branje in izpis vrednosti karte bo potekalo preko zaporedja znakov – prva črka bo oznaka barve, druga zaporedja znakov prva črka bo oznaka barve, druga črka (oz. drugi dve) pa bo predstavljala vrednost. Zgled • Programska koda: Karte1.c Zgled • Naloga: p p j j p j Dopolnite prejšnji primer s funkcijo, ki bo za pet kart ugotovila ali predstavljajo poker. Funkcijo preverite s testnim programom ki Funkcijo preverite s testnim programom, ki vrednosti petih kart prebere preko tipkovnice in izpiše rezultat in izpiše rezultat. Zgled • Analiza in (osnovna) razgradnja: li i ( ) d j Igralec ima "v roki" poker, če ima 4 karte iste vrednosti. • Več kart bomo predstavili s poljem katerega p p j g elementi so strukture, ki predstavlja karte. • Pri ugotavljanju ali gre za poker, bomo Pri ugotavljanju ali gre za poker bomo uporabili števce, ki bodo prešteli koliko kart posamezne vrednosti imamo "vv roki posamezne vrednosti imamo roki". Na Na koncu preverimo ali ima kateri od števcev vrednost 4 vrednost 4. Zgled • Programska koda: Karte2.c Uporaba programskih modulov Uporaba programskih modulov • P Pri izdelavi drugega programa s kartami smo morali ii d l id k i li prekopirati večino kode iz prvega. • Če želimo naknadno kaj spremeniti (npr. uporabiti Č ž li k d k j i i( bi i posebne grafične znake za izpis barve kart), moramo popravljati oba programa popravljati oba programa. • Veliko bolje je, če podatkovne tipe in podprograme povezane z kartami združimo v ločen programski povezane z kartami združimo v ločen programski modul in ga uporabimo za oba glavna programa (in za morebitne ostale programe s kartami) . morebitne ostale programe s kartami) . Zgled • Programska koda: KarteM.c, KarteM.h, Karte1M.c, Karte2M.c, Karte3M.c Nizi znakov Nizi znakov • Enodimenzionalno polje znakov char <ime spremenljivke>[<dimenzija>]; • Skoraj vsi podprogrami za delo z nizi znakov v C‐ju predpostavljajo, da se niz konča z znakom '\0' (koda 0) a b c d e f g \0 • V Vsak znak zaseda en zlog (byte – k k d l (b t 0..255) 0 255) • C pozna tudi konstantne nize znakov (v dvojnih narekovajih) Nizi znakov Nizi znakov • Polja znakov lahko ob dekraraciji inicializiramo s konstantnim nizom znakov: char niz1[10]; char niz2[10] = "abc"; /* inicializira prve 4 znake */ char niz3[] = "defgh"; /* velikost polja je 6 */ niz1 i 1 = niz2; i 2 /* napaka k */ niz3[0] = niz2[0]; printf("%s\n",niz3); Nizi znakov Nizi znakov • Nize znakov lahko navedemo tudi kot parametre podprogramov – prevajalnik ne preverja ali se dimenzije polj dejanskih in formalnih parametrov ujemajo. int fun1(char niz[]); int fun1(char niz[10]); Zgled • N Naloga: l Izdelajte podprogram, ki bo preveril ali se nek znak nahaja v podanem nizu znakov • Analiza in razgradnja: Znak bomo primerjali po vrsti s posameznimi znaki iz niza. Iskanje zaključimo ko bodisi najdemo znak ali pa zaključimo, naletimo na kodo konca niza (znak '\0'). • Predpostavili bomo bomo, da indeksi polja niza znakov tečejo od 0 naprej. Zgled • Psevdokod: // ZnakJeVNizu(znak,niz[0..n]) // ( , [ ]) // Začnemo pri prvem znaku set i=0 // postopek ponavljamo, dokler ne pridemo do konca niza // postopek ponavljamo, dokler ne pridemo do konca niza while niz[i]<>''\0' do if niz[i]=znak then // Znak niza je enak iskanemu return True // Znak je v nizu // j end if set i=i+1 // Premik na naslednji znak end while return False // Znaka ni v nizu Zgled • Programska koda: ZnakJeVNizu.c Najprej je potrebno v kodi popraviti eno • Najprej je potrebno v kodi popraviti eno logično napako! Zgled - nadgradnja • Vč Včasih ih jje ugodneje, d j čče poleg l ttega alili se znak nahaja v določenem nizu, ugotovimo še na kateri poziciji (indeksu) se nahaja. • Prejšnji j j p postopek p (p (program) g ) dopolnimo p tako, da namesto vrednosti True/False ača indeks de s mesta esta na a katerem ate e se znak a vrača niza ujema z iskanim. V primeru, če znaka ni v nizu, vrnemo neko posebno vrednost (npr. -1), ki je indeks ne more zavzeti. • Programska koda: KateriZnak.c KateriZnak c Zgled – štetje črk (1) • Naloga: l Izdelajte program, ki bo v podanem nizu znakov preštel koliko plusov in koliko minusov se v njem nahaja. • Analiza in razgradnja: ot ebuje o dva d a števca, šte ca, e enega ega za ap pluse use Potrebujemo in enega za minuse. Po vrsti pregledamo vse znake niza. Če naletimo na plus ali minus, povečamo ustrezni števec. Na koncu izpišemo vrednosti števcev. Zgled • Programska koda: StetjeCrk1.c Zgled – štetje črk (2) • Naloga: l Izdelajte program, ki bo v podanem nizu znakov preštel kolikokrat se pojavlja prvih pet črk angleške abecede 'a', 'b', 'c', 'd', 'e'. • Analiza in razgradnja: a esto da za a vsako sa o črko č ou uvedemo ede o ssvoj oj Namesto števec, raje uporabimo polje števcev. Pri računanju indeksa polja števcev upoštevamo dejstvo, da si kode podanih znakov sledijo ena za drugo. Zgled • 'b' = 'a'+1, 'c'='b'+1, … • Indeks polja dobimo tako tako, da od kode znaka niza odštejemo kodo znaka 'a'. – 'a'-'a' ' '' '=0 – 'b'-'a' = 1 – 'c'-'a' = 2 – 'e'-'a' e a =4 • Programska koda: StetjeCrk2.c Zgled – štetje črk (3) • N Naloga: l Izdelajte program, ki bo v podanem nizu znakov preštel kolikokrat se pojavljajo znaki a,b,c,+,-,*. • Analiza in razgradnja: Analiza in razgradnja: Tudi tu bomo uporabili števce. Vendar si tokrat znaki ne sledijo en za drugim drugim. Potrebujemo funkcijo, ki določa indeks števca za posamezni znak. Pomagali si bomo z prej izdelano funkcijo KateriZnakVNizu. Zgled – štetje črk (3) Zgled – Zgled • Programska koda: StetjeCrk3.c, StetjeCrk4.c Povezava med polji in kazalci na znake Povezava med polji in kazalci na znake • Podobno kot velja za vsa polja v C‐ju, obstaja d b k lj lj j b j tesna zveza med kazalci in polji • Imena polj so dejansko kazalci na prvi element p j polja => priredimo jih lahko drugemu kazalcu p j g • Kazalec lahko uporabimo tudi kod polje – kazalčna aritmetika kazalčna aritmetika • Same kazalce lahko povečujemo ali zmanjšujemo kar ustreza pomikanju po polju z jš j k t ik j lj indeksom. Povezava med polji in kazalci na znake Povezava med polji in kazalci na znake polje ≡ &polje[0] *polje ≡ polje[0] polje+n ≡ n+polje ≡ &polje[n] *(polje+n) (polje+n) ≡ *(n+polje) (n+polje) ≡ polje[n] char niz[] = "abcdef"; char *pa,*pb; *pa *pb; pa = niz; pa++; niz++; pb = niz; /* /* /* /* pa kaže na 'a' */ pa kaže na 'b' */ napaka */ pb kaže na 'a' */ printf("%d\n" pb pa); /* vrne razliko indeksov = 1 */ printf("%d\n",pb-pa); Zgled • Naloga: l Preoblikujte podprogram ZnakJeVNizu tako, da bo uporabljal kazalce. • Analiza in razgradnja: g j Gre dejansko za drugačno implementacijo podporama. podpo a a Vd drugih ug p programskih og a s je jezikih (ki ne izhajajo iz C-ja) takšne povezave običajno ni. • Programska koda: KateriZnakVNizu2.c Zgled – iskanje besed (1) Zgled – Zgled • Naloga: j p program, g , ki bo p po vrsti izpisal p vse Izdelajte besede nekega niza. Besede predstavlja vsako zaporedje znakov znakov, ki ni presledek ali ločilo. Zgled – iskanje besed (1) Zgled – Zgled • Analiza in razgradnja: Besede so nizi znakov med posameznimi presledki ali ločili. V nizu po vrsti iščemo znake, ki predstavljajo začetek besede. Ko smo tak znak našli, poiščemo konec besede in izpišemo vse znake od začetka do konca. Nato se premaknemo za tekočo besedo in postopek ponovimo. • Potrebujemo funkcijo, ki pove ali je podani znak ločilo in proceduro za izpis posamezne besede. Zgled – iskanje besed (1) Zgled – Zgled • Programska koda: Besede1.c, Besede2.c Zgled – iskanje besed (2) Zgled – Zgled • Ali so številke besede? Da in ne. Če Č pri rešitvi p problema upoštevati p želimo p "človeško" pojmovanje besed, moramo nekoliko obrniti pogoje pogoje. • Programska koda: Besede3.c Zgled – iskanje besed (3) Zgled – Zgled • Kaj pa "besede" v C-ju? Besede v C-ju so j imena spremenljivk p j in ukazov. dejansko Ime "besede" v C-ju se mora začeti s črko, ki ji sledi zaporedje črk in cifer. cifer • Programska koda: Besede4.c Zgled – iskanje besed (4) Zgled – Zgled • G Gremo še š en korak k k naprej.j Denimo, D i d da bi radi nekatere besede obravnavali drugače od ostalih (npr (npr. pri izpisu bi radi izpustili rezervirane besede C-ja). V ta namen potrebujemo funkcijo NizaStaEnaka, NizaStaEnaka ki preverja enakost dveh nizov. Ta funcija mora oap primerjati e jat črko č o po črko č od dveh e nizov, o , dokler ne naletimo na razliko ali pa ne pridemo do konca katerega p g od nizov. • Programska koda: Besede5.c, Besede6.c Standardne rezervirane besede Standardne rezervirane besede auto double int struct break else long switch case enum register typedef char extern return union const fl float short h unsigned i d continue for signed void default goto sizeof volatile do if static while Delo s tekstovnimi datotekami Delo s tekstovnimi datotekami • Tekstovne datoteke lahko obravnavamo kot p j j zaporedje vrstic, ki jih lahko beremo samo eno za drugo. FILE *fopen(char * filename, char *mode); int fclose(FILE *fp); ( p) int feof(FILE *fp); Delo s tekstovnimi datotekami • Nalogo, ki obdeluje ene niz znakov lahko preuredimo v nalogo g s enostavno p tekstovno datoteko tako, da obdelavo niza preselimo v ločen podprogram podprogram. Potem pa pa, ko beremo datoteko, za vsako vrstico kličemo ta podprogram podprogram. • Namesto g gets, uporabimo p fgets. g char *fgets( char *str, int n, FILE *fp ); Zgled • Programska koda: StetjeCrk5.c, StetjeCrk6.c
© Copyright 2024