= Uvod v programski jezik C = V naslednjih poglavjih bom poizkušal na čim bolj enostaven način razložiti osnove programskega jezika C, ki so obvezno potrebne za izdelavo nekega konkretnega programa. [[BR]] == Prvi program == Da bomo premagali strah glede programiranja s programskim jezikom C oziroma, da si bomo potešili željo po svojem prvem programu, napišimo enostaven program, ki nam bo izpisal naslednje besedilo: ''Moj prvi program''. {{{ #!c #include int main() { printf("Moj prvi program\n"); return 0; } }}} [[BR]] == Sintaksa jezika == Kot vsi drugi programski jeziki ima tudi C značilno sintakso jezika, ki se jo moramo strogo držati. To pomeni, da moramo upoštevati pravilni vrstni red in izbrane kombinacije besed ter simbolov tako, da tvorimo sintaktično pravilne izraze. Če sintaksa zapisanega programa ni pravilna, nam bo prevajalnik javil napako. Najpogostejši operatorji in izrazi: * OPERATORJI * Relacijski {{{ #!c a==b //a je enak b a!=b //a ni enak b a<=b //a je manjši ali enak b a>b //a je večji kot b }}} * Logični {{{ #!c (ab) { max=a; } else { max=b; } }}} V ''if'' stavke lahko dodamo še dodatne pogoje. To storimo z ukazom ''else if(pogoj)''. {{{ #!c if(a>b) { max=a; } else if(c>a) { max=c; } else { max=b; } }}} [[BR]] '''For zanka''' {{{ #!c for(i=0; i<10; i++) { printf("text\n"); } }}} Pri tem ''\n'' pomeni prehod v novo vrsto (New Line) [[BR]] '''Switch stavek''' {{{ #!c switch(i) { case 1: printf("text 1") break; case 2: printf("text 2") break; case 3: printf("text 3") break; } }}} Lahko uporabimo še dodatni ukaz ''default'', pri katerem se izvršijo stavki, kadar ni bil izbran določen ''case''. {{{ #!c switch(i) { case 1: printf("text 1") break; case 2: printf("text 2") break; default: printf("text") } }}} [[BR]] '''While zanka''' {{{ #!c i=0; while(i<10) { printf("text\n"); i=i+1; } }}} [[BR]] '''Do - while zanka''' {{{ #!c i=0; do { printf("text\n"); i=i+1; } while(i<10); }}} Pri ''do - while'' zanki se stavki izvedejo vsaj enkrat! [[BR]] V praksi pa se pogosto uporablja kombinacija teh stavkov. {{{ #!c //Generiranje elementov matrike H for(i=0; i<4; i++) { for(j=0; j<4; j++) { if(i==j) { H[i*4+j]=0.5; } else { H[i*4+j]=2.0; } } } }}} [[BR]] == Formatiran izpis == Vrednosti spremenljivk in konstant lahko izpisujemo z različnimi formati. Najbolj pogosto uporabljeni formatni stavki so: * ''%f'' - realna števila * ''%d'' - cela števila * ''%g'' - realna števila, format odvisen od velikosti [[BR]] Format izpisa neke vrednosti lahko poljubno določimo. To storimo tako, da formatni stavek dopolnimo z ukazom, ki nam pove koliko mest naj izpis zavzame pred decimalko in koliko za njo. Za primer vzemimo, da želimo imeti pet mest pred decimalko in dva za njo. Formatni stavek se glasi ''%5.2f''. [[BR]] Primeri formatiranega izpisa {{{ #!c #include int main() { float a=5.12; //Realno število int b=-5; //Celo število printf("Vrednost a je enaka %f\n", a); printf("Vrednost a je enaka %4.2f\n", a); //Nastavimo željen format izpisa printf("Vrednost a je enaka %g\n", a); //Format bo odvisen od velikosti printf("Vrednost b je enaka %d\n", b); return 0; } }}} Program izpiše naslednje: {{{ Vrednost a je enaka 5.120000 Vrednost a je enaka 5.12 Vrednost a je enaka 5.12 Vrednost b je enaka -5 }}} [[BR]] == Polja, vektorji, matrike == Polja, vektorje in matrike definiramo z deklaracijo, enako kot to velja za spemenljivke. {{{ #!c float M[4]; //Enodimenzionalno polje - vektor oziroma matrika vsebuje 4 elemente z realnimi vrednostmi }}} Prvi element ima vedno indeks 0! Za primer določimo vrednosti posameznim elementom: {{{ #!c float M[4]; M[0]=2.0; M[1]=1.0; M[2]=4.0; M[3]=1.0; }}} Vrednosti posameznih elementov pa lahko definiramo že pri deklaraciji. To storimo na naslednji način: {{{ #!c float M[4]={2.0, 1.0, 4.0, 1.0}; }}} Za izpis 1. elementa bomo torej zapisali: {{{ #!c printf("Vrednost 1. elementa znaša %f", M[0]); }}} V pomnilniku je to polje zloženo tako, kot kaže slika 1, kjer vsak element polja zavzame 4 byte pomnilnika. [[Image(Pomnilnik.PNG)]] Slika 1: Stanje pomnilnika [[BR]] Pri tem nas verjetno zmoti to, da lahko matriko definiramo kot vektor. Takšen način definiranja matrike je dokaj pogost, pri tem pa z elementi operiramo na sledeči način (gre za enodimenzionalno polje): Za primer imamo matriko ''N'' velikosti 2×3 z elementi: {{{ 1.0 2.0 3.0 4.0 5.0 6.0 }}} Sledi: {{{ #!c float N[2*3]={1.0, 2.0, 3.0, 4.0, 5.0, 6.0}; //Matriko zapišemo kot vektor v eni vrstici. Pišemo lahko tudi N[6]=... //Primer izpisa elementa, ki se nahaja v drugi vrstici prvega stolpca. V tem primeru gre za četrti element matrike oziroma vektorja N printf("Element v drugi vrstici prvega stolpca je %f", N[1*3+0]); //Primer izpisa elementa, ki se nahaja v prvi vrstici tretjega stolpca. printf("Element v prvi vrstici tretjega stolpca je %f", N[0*3+2]); }}} Poljubni element matrike zapišemo v splošni obliki kot: {{{ N[indeks vrstice * število stolpcev + indeks stolpca] }}} S tem, ko pomnožimo indeks vrstice s številom stolpcev, si lahko predstavljamo, da preskočimo vse elemente v prejšnih vrsticah. Če temu produktu prištejemo še indeks stolpca, pridemo ravno do tistega elementa, ki ga želimo. Enostaven primer generiranja elementov matrike nam kaže primer, ki smo ga spoznali pri kombiniranju kontrolnih stavkov. [[BR]] Poleg omenjenega načina definiranja matrik obstaja še drug način, pri katerem uporabimo večdimenzionalna polja. Primer definiranja matrike: {{{ #!c float N[2][3]={{1.0, 2.0, 3.0}, {4.0, 5.0, 6.0}}; //Primer izpisa elementa, ki se nahaja v prvi vrstici tretjega stolpca. printf("Element v prvi vrstici tretjega stolpca je %f", N[0][2]); }}} Pri tem ne smemo pozabiti, da se indeksi vrstic in stolpcev vedno začnejo z 0. [[BR]] == Branje datotek == Velikokrat se zgodi, da dobimo vhodne podatke, s katerimi bo program operiral, zapisane v datoteki. Primer datoteke s podatki, z imenom ''datoteka.dat'': {{{ 2 4 00 02 12 08 14 05 07 11 }}} Da bo naš program prebral to datoteko in shranil podatke pod spremenljivke, uporabljamo naslednjno kombinacijo ukazov: {{{ #!c int i; int n, d; float M[4], N[4]; FILE *f; //Povemo, da gre za podatkovo strukturo f=fopen("datoteka.dat","r"); //"r" pomeni, da bo datoteka samo za branje fscanf(f, "%d %d", &n, &d); //Prebere iz datoteke in shrani prva dva podatka pod spremenljivke n in d for(i=0; i<4; i++) { fscanf(f, "%f", &M[i]); //Prebere in shrani naslednje štiri podatke } for(i=0; i<4; i++) { fscanf(f, "%f", &N[i]); } fclose(f); }}} Zaporedje branja podatkov poteka vedno po vrsticah! (Lahko si predstavljamo, kot da so podatki zapisani v eni vrstici) == Dinamična alokacija pomnilnika == == Reševanje sistema linearnih enačb ==