27
STRUKTURE PODATAKA I ALGORITMI 1 Funkcije i struktura programa

04 Funkcije i Struktura Programa

Embed Size (px)

DESCRIPTION

04 Funkcije i Struktura Programa

Citation preview

  • STRUKTURE PODATAKA I ALGORITMI 1Funkcije i struktura programa

  • FUNKCIJERazbijaju velike raunarske zadatke u manje deloveSkrivaju detalje postupka od delova programa koji ne moraju da znaju o njimaine program jasnijim i jednostavnijim za menjanje

  • STRUKTURA PROGRAMAProgrami se najee sastoje od vie manjih funkcijaProgram se moe nalaziti u jednoj ili vie izvornih datotekaIzvorne datoteke se mogu kompajlirati odvojeno i od njih se moe formirati izvrni program

  • PROGRAM KOJI PRIKAZUJE SVAKI RED SA ULAZA KOJI SADRI ODREENI STRING (OBRAZAC)Traimo obrazac "ould" u tekstu:Ah Love! could you and I with Fate conspireTo grasp this sorry Scheme of Things entire,Would not we shatter it to bits -- and thenRe-mould it nearer to the Heart's Desire!Dobija se rezultat:Ah Love! could you and I with Fate conspireWould not we shatter it to bits -- and thenRe-mould it nearer to the Heart's Desire!Zadatak se moe razbiti na tri dela:while (postoji jos jedan red)if (taj red sadrzi obrazac)prikazati taj red

  • POSTOJI JOS JEDAN RED = GETLINE/* getline: get line into s, return length */int getline(char s[], int lim){int c, i;

    i = 0;while (--lim > 0 && (c=getchar()) != EOF && c != '\n')s[i++] = c;

    if (c == '\n')s[i++] = c;

    s[i] = '\0';

    return i;}

  • TAJ RED SADRZI OBRAZAC = STRINDEX/* strindex: return index of t in s, -1 if none */int strindex(char s[], char t[]){int i, j, k;

    for (i = 0; s[i] != '\0'; i++){for (j=i, k=0; t[k]!='\0' && s[j]==t[k]; j++, k++);

    if (k > 0 && t[k] == '\0')return i;}

    return -1;}

  • GLAVNI PROGRAM#include #define MAXLINE 1000 /* maximum input line length */

    int getline(char line[], int max)int strindex(char source[], char searchfor[]);

    char pattern[] = "ould"; /* pattern to search for */

    /* find all lines matching pattern */main(){char line[MAXLINE];int found = 0;

    while (getline(line, MAXLINE) > 0)if (strindex(line, pattern) >= 0){printf("%s", line);found++;}

    return found;}

  • DEFINICIJA FUNKCIJESvaka definicija funkcije ima obliktip_rezultata naziv_funkcije( deklaracije argumenata ){deklaracije i naredbe}Prazna funkcijaprazna() {}Ako tip rezultata nije naveden podrazumeva se intNaredba return se koristi za vraanje vrednosti pozivaocu. Vrednost moe biti bilo koji izraz. Tip izraza se pretvara u tip rezultata ako je neophodno.return izrazPozivalac moe ignorisati vraenu vrednost

  • EKSTERNE PROMENLJIVEInterne promenljive se definiu unutar funkcijaExterne promenljive se definiu van funkcija i samim tim su dostupne svim funkcijamaFunkcije su uvek eksterne zato to C ne dozvoljava definisanje funkcije unutar druge funkcijeEksterne promenljive su globalno dostupne i mogu se koristiti umesto argumenata ili vrednosti koja se vraaUkoliko funkcije razmenjuju veliki broj parametara, nekada je pogodnije da to ine preko eksternih promenljivih. Ipak, to nije preporuljivo jer naruava strukturu programa i moe dovesti do neeljenih efekataZa razliku od automatskih promenljivih koje se stvaraju prilikom ulaska u funkciju i unitavaju prilikom izlaska iz nje, eksterne promenljive su trajne

  • KALKULATOR SA INVERZNOM POLJSKOM NOTACIJOM(1 - 2) * (4 + 5)-infiksni zapis1 2 - 4 5 + *-postfiksni zapisImplementacijaSvaki operand se stavlja na stekKada se naie na operator, sa steka se uzimaju operandiPrimenjuje se operator, a rezultat se ponovo stavlja na stekPrimer: 1 2 - 4 5 + *1 i 2 se stavljaju na stekZatim se skidaju sa steka i zamenjuju njihovom razlikom -14 i 5 stavljaju na stekZatim se skidaju sa steka i zamenjuju njihovim zbirom 9Zatim se -1 i 9 skidaju sa steka i zamenjuju njihovim proizvodom -9Kada se stigne do kraja izraza, sa vrha steka se skida rezultat

  • PSEUDO KODwhile (sledei operator ili operand nije znak za kraj fajla)if (broj)stavi ga na stekelse if (operator)skini operande sa stekauradi operacijustavi rezultat na stekelse if (newline)skini i stampaj vrh stekaelsegreka

    A gde je STEK?

  • STRUKTURA PROGRAMA#include ...#define ...

    deklaracija funkcija za main

    main(){ ...}

    eksterne promenljive za push i pop

    void push( double f){...}

    double pop(void){...}

    int getop(char s[]){...}

    funkcije koje zove getop

  • #include #include /* za atof() */

    #define MAXOP 100 /* maksimalna velicina operanda ili operatora */#define NUMBER '0' /* signal da je pronadjen broj */

    int getop(char []);void push(double);double pop(void);

    /* reverzni Poljski kalkulator */main(){int type;double op2;char s[MAXOP];

    while ((type = getop(s)) != EOF){switch (type){case NUMBER:push(atof(s));break;case '+':push(pop() + pop());break;

  • case '*':push(pop() * pop());break;case '-':op2 = pop();push(pop() - op2);break;case '/':op2 = pop();if (op2 != 0.0)push(pop() / op2);elseprintf("Greska: deljenje nulom\n");break;case '\n':printf("\t%.8g\n", pop());break;default:printf("Greska: nepoznata komanda %s\n", s);break;}}

    return 0;}

  • #define MAXVAL 100 /* maksimalna visina steka */

    int sp = 0; /* sledeca slobodna pozicija na steku */double val[MAXVAL]; /* vrednosti na steku */

    /* push: stavlja f na stek */void push(double f){if (sp < MAXVAL)val[sp++] = f;elseprintf("Greska: stek je pun, nije moguce staviti %g\n", f);}

    /* pop: skida i vraca vrednost sa vrha steka */double pop(void){if (sp > 0)return val[--sp];else{printf("Greska: stek je prazan\n");return 0.0;}}

  • #include

    int getch(void);void ungetch(int);

    /* getop: get next character or numeric operand */int getop(char s[]){int i, c;

    while ((s[0] = c = getch()) == ' ' || c == '\t') ;

    s[1] = '\0';

    if (!isdigit(c) && c != '.')return c; /* nije broj */

    i = 0;if (isdigit(c)) /* procitaj celobrojni deo */while (isdigit(s[++i] = c = getch())) ;

    if (c == '.') /* procitaj decimalni deo */while (isdigit(s[++i] = c = getch())) ;

    s[i] = '\0';

    if (c != EOF) ungetch(c);

    return NUMBER;}

  • TA SU GETCH() I UNGETCH()?#define BUFSIZE 100

    char buf[BUFSIZE]; /* bafer za ungetch */int bufp = 0; /* sledeca slobodna pozicija u baferu */

    int getch(void) /* uzima karakter iz bafera ili sa ulaza */{return (bufp > 0) ? buf[--bufp] : getchar();}

    void ungetch(int c) /* vraca karakter u bafer */{if (bufp >= BUFSIZE)printf("ungetch: prekoracena velicina bafera\n");elsebuf[bufp++] = c;}

  • OPSEG VIDLJIVOSTIEksterne promenljive su vidljive samo iza definicijemain() { ... }

    int sp = 0;double val[MAXVAL];

    void push(double f) { ... }double pop(void) { ... }

    externDefinicija (samo na jednom mestu)int sp;double val[MAXVAL];Deklaracija (svuda gde se koriste promenljive)extern int sp;extern double val[];

  • VIE FAJLOVAu fajlu1:

    extern int sp;extern double val[];

    void push(double f) { ... }double pop(void) { ... }

    u fajlu2:int sp = 0;double val[MAXVAL];

  • HEADER FAJLOVI

  • STATIKE PROMENLJIVEPromenljive sp i val u stack.c i buf i bufp u getch.c su namenjene samo za te datotekeDeklaracija static ograniava domet promenljive ili funkcije samo na fajl u kome su deklarisanestatic char buf[BUFSIZE]; /* bafer za ungetch */static int bufp = 0; /* sledeca slobodna pozicija u baferu */

    int getch(void) { ... }void ungetch(int c) { ... }Samo ove dve funkcije e videti promenljive buf i bufpFunkcije u drugim fajlovima ne vide ove promenljiveU drugim fajlovima mogue je deklarisati promenljive sa istim imenimastatic se moe primeniti na interne (lokalne) promenljive. Tada njihov vek trajanja nije ogranien samo na telo funkcije. Iako im je opseg vidljivosti samo unutar funkcije, one postoje sve vreme izvrenja programa.

  • REGISTARSKE PROMENLJIVEDeklaracija register obavetava kompajler da e promenljiva koja sledi biti veoma esto korienaNamera je da registarske promenljive budu smetene u mainskim registrima, to vodi do manjih i brih programaKompajleri su slobodni da odlue da li e da proglase ove promenljive za registarskeMogu se promeniti samo na automatske promenljive i formalne parametre funkcijeregister int x;register char c;

    f(register unsigned m, register long n){register int i;...}

  • BLOKOVSKA STRUKTURAPromenljive se mogu deklarisati i unutar blokovaPromenljive deklarisane unutar bloka su vidljive samo u tom blokuNjihov opseg vidljivosti i ivotni vek su samo unutar tog blokaivotni vek statikih promenljivih deklarisanih unutar bloka traje sve vreme izvrenja programaPromenljive deklarisane unutar bloka zaklanjaju istoimene promenljive deklarisane van bloka (treba izbegavati)int i;if (n > 0){int i; /* deklaracija novog i */for (i = 0; i < n; i++)...}Automatske promenljive se inicijalizuju prilikom svakog ulaska u blok, dok se statike inicijalizuju samo pri prvom ulasku u blok

  • INICIJALIZACIJANe treba se oslanjati na to da e kompajler automatski inicijalizovati promenljiveint x = 1;char squota = '\'';long day = 1000L * 60L * 60L * 24L; /* milliseconds/day */Za eksterne i statike promenljive inicijalizator mora biti konstantan izrazZa automatske i registarske promenljive inicijalizator moe biti bilo koji izraz u kome uestvuju prethodno definisane vrednostiNizovi se inicijalizuju navoenjem vrednosti u velikim zagradamaint days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };Znakovni nizovi (stringovi) se mogu inicijalizovati pomou navodnikachar pattern = "ould";to je skraeni zapis odchar pattern[] = { 'o', 'u', 'l', 'd', '\0' };

  • REKURZIJAFunkcija direktno ili indirektno poziva samu sebe

    Primer: Prikazivanje cifara nekog broja u pravilnom redosledu#include

    /* printd: print n in decimal */void printd(int n){if (n < 0){putchar('-');n = -n;}

    if (n / 10)printd(n / 10);

    putchar(n % 10 + '0');}

    Glavni program

    fakt(5)

    120

    fakt(n=5)

    fakt=5*fakt(4)

    fakt=5*24=120

    fakt(n=4)

    fakt=4*fakt(3)

    fakt=4*6=24

    fakt(n=3)

    fakt=3*fakt(2)

    fakt=3*2=6

    fakt(n=2)

    fakt=2*fakt(1)

    fakt=2*1=2

    fakt(n=1)

    fakt=1

  • C PRETPROCESORUkljuivanje datoteka#include "imedatoteke"ili#include Zamena makroa#define naziv tekstzamene#define forever for(;;) /* infinite loop */Makroi sa argumentima#define max(A, B) ((A) > (B) ? (A) : (B)) /* maksimum od dva broja */x = max(p+q, r+s);zamenjuje se sax = ((p+q) > (r+s) ? (p+q) : (r+s));

    max(i++, j++) /* POGRESNO */#define square(x) x * x /* POGRESNO*/

  • Uslovno ukljuivanje datoteka#if, #else, #elif, #endif, #ifdef, #ifndefPrimer: Ukljuivanje datoteke hdr.h samo jednom#if !defined(HDR)#define HDR/* sadrzaj datotek hdr.h ide ovde */#endifPrimer: Ukljuivanje razliitih datoteka u zavisnosti od sistema#if SYSTEM == SYSV#define HDR "sysv.h"#elif SYSTEM == BSD#define HDR "bsd.h"#elif SYSTEM == MSDOS#define HDR "msdos.h"#else#define HDR "default.h"#endif#include HDR#ifdef i #ifndef#ifndef HDR#define HDR/* sadrzaj datotek hdr.h ide ovde */#endif