450 likes | 645 Views
Tietorakenteet ja C-kieli. TkT Jarno Mielikäinen. e-mail: Jarno.Mielikainen@lut.fi Vastaanotto: ke 11-12. Luennot. Noudattavat Lasse Lensun luentomonistetta, josta tulee korjattu versio lähiaikoina Mahdollisista eroavaisuuksista kerrotaan kurssin kotisivuilla To 16-17:45 Pe 12-13
E N D
Tietorakenteet ja C-kieli TkT Jarno Mielikäinen e-mail: Jarno.Mielikainen@lut.fi Vastaanotto: ke 11-12
Luennot • Noudattavat Lasse Lensun luentomonistetta, josta tulee korjattu versio lähiaikoina • Mahdollisista eroavaisuuksista kerrotaan kurssin kotisivuilla • To 16-17:45 • Pe 12-13 • Luentoviikot 1-4: C-kieli • Luentoviikot 5-7: tietorakenteita • Loput: algoritmeja
Harjoitukset • EI pakolliset, mikroluokassa 6325 • ti 16-18, 18:00-19:30, ke 12-14to 8.30-10, 10-12, 12-14, pe 10-12 • Olennainen osa oppimista • Kokeile, jos et osaa, kysy • Ratkaisut annetaan, jos et ymmärrä, kysy • Jos löydät vaihtoehtoisen/paremman ratkaisun, kerro
Harjoitustyöt • 1. harjoitustyö 3. periodin lopussa • 2. harjoitustyö 4. periodin lopussa
Tentit • 1. välikoe 5.3 klo 16 • 2. välikoe 7.5 klo 16 • Tentti 14.5 klo 16
Kurssin tavoitteet: C-kieli • C-kielisten ohjelmien luku ja kirjoitustaidot • Ymmärrät kaikki C:n rakenteet • Osoittimien (pointterien) käyttötaito • Yleiskatsaus kirjastofunktioihin • Tietoinen C:n sudenkuopista
Kurssin tavoitteet: tietorakenteet • Yleisempien tietorakenteiden tuntemus:taulukot, pinot, jonot, listat, puut, keot ja graafit • Tietorakenteen valinta käytettävien operaatioiden perusteella (lisääminen, poistaminen, jne.)
Kurssin tavoitteet: algoritmit • Johdattelua algoritmien kompleksisuus analyysiin • Lajittelualgoritmeja • Hakualgoritmeja
Miksi C-kieli? • C-kielen data-tyypit ja operaatiot vastaavat laitteistotason tarjoamia • Ohjelmat ovat hyvin siirrettävissä toisiin laitteisto- ja käyttöjärjestelmäympäristöihin • Yleisesti käytössä • Linux, Apache, gcc, jne. • MISRA C, http://www.misra.org.uk/ • NVIDIA:n Cg, DX9:n HLSL, OpenGL 2.0:n shader kielet, BrookGPU
C-kielen historia • Kernigan & Ritchie (K&R), 1972 • ISO/IEC 9899-1990 (C89, ANSI C) • ISO/IEC 9899-1999 (C99) • Tällä kurssilla käsitellään C89:ä
C-Ohjelma Kertoo kääntäjälle syöttö- ja tulostusfunktioista (printf + muut) Pääohjelma ”Alku” ”Loppu” #include <stdio.h> int main(void) { printf(”Tervetuloa kurssille!\n”); return 0; /* paluuarvo == 0 OK */ }
Merkkijonovakiot • Ympäröidään lainausmerkeillä • Vie muistitilaa merkkien lukumäärän verran + 1, jonka vie merkkijonon päättävä merkki ’\0’ • Voidaan jatkaa toiselle riville”merkki””jono”tai”merkki\jono” • Kenoviivalla voidaan myös jatkaa mitä tahaansa tekstiä toiselle riville
Muuttujat • Muuttujat on määriteltävä ennen käyttöä, välittömästi ’{’:n jälkeen • Muuttujan nimi alkaa kirjaimella(a-z, A-Z) • Seuraavat merkit voivat olla kirjaimia tai ’_’ tai numeroita (0-9) • Muuttujanimen maksimipituus 31 merkkiä • Nimet ’A’ ja ’a’ eivät ole samat
GNU Compiler Collection(GCC) • GCC, http://gcc.gnu.org/, on käytössä ainakin koulun Unix koneissa • Käyttö:gcc –ansi –Wall –okohde lahde.cmissä kohde on ajettavan ohjelman nimi jalahde.c lähdetiedoston nimi • käännetty ohjelma ajetaan:./kohde
Vakiot c:n E+X tarkoittaa 10+X -1.23 25E+34 • . tai E:n sisältävät luvut ovat tyyppiä double • F numeron perässä määrittää floatin • Tyypille long double lisää L • Muutoin luku on tyyppiä int • Kokonaisluvuille L määrittäätyypin long int -1.23F 25E+34F -1.23L 25E+34L 123 2534 123L 2534L
Liukulukuja ei vertailla näin #include <stdio.h> int main(void) { float a=1.345,b=1.123,c; c=a+b; if (c == 2.468) printf("Yhtäsuuret\n"); else printf("Erisuuret! c:n arvo on %13.10f, tai%f\n",c,c); } Yhtäsuuruuden testaamiseen käytetään == operaattoria % leveys . tarkkuus f, määrittää tulostuskentän leveyden ja liukuluvun tarkkuuden
Liukulukujen vertailua #include <stdio.h> #define EPSILON 0.0001 int main(void) { float a=1.345,b=1.123,c; c=a+b; if (abs(c-2.468)<EPSILON) printf("Yhtäsuuret\n"); else printf("Erisuuret! c:n arvo on %13.10f, tai%f\n",c,c); } EPSILON korvataan 0.0001:llä ennen varsinaista käännöstä abs() on itseisarvofunktio
C:n operaattorit • Vertailuoperaattorit • Aritmeettiset operaattorit • Bittitason operaattorit • Sijoitusoperaattorit • sizeof operaattori • Ehtolauseke • Tyyppimuunnos
Vertailua #include <stdio.h> int main(void){ int a=3; const int alaraja=3; const int ylaraja=7; if(a<ylaraja && a>=alaraja) printf("%i <=a<%i\n", alaraja, ylaraja); } luodaan kokonaislukuvakiot alaraja <= a < ylaraja
Short-Circuit Evaluation • Ensimmäinen epätosi &&-operaatorin yhdistämä lauseke päättää evaluoinnin b saa arvoksi 0:n ei 2+2=4 koska (b=a) on epätosi eli nolla int a=0, b=1, c=2; if((b=a) && (b=c+2)) printf("Ihme\n"); • Ensimmäinen tosi ||-operaatorin yhdistämä lauseke päättää evaluoinnin int b=1, c=2; if(!((b=c) || (b=c+2))) printf("Ihme\n"); b saa arvoksi 2:n ei 2+2=4 koska (b=c) on tosi eli ei-nolla
Jakolasku suoritetaan tyypille int, jonka jälkeen tulos sijoitetaan tyyppiin float int x=23,y=2; float z; z=x/y; /* z == 11 */ Tapahtuu implisiittinen tyyppimuunnos Aritmeettiset operaattorit
Tyyppimuunnokset • Lausekkeessa olevat eri tyyppiset tietotyypit muutetaan samaksi ennen lausekkeen arvon laskentaa • Implisiittisessä tyyppimuunnoksessa”alempi” korotetaan ”ylemmäksi”esim. int -> float int x=23; float y=2, z; z=x/y; /* z == 11.5 */
Eksplisiittinen tyyppimuunnos • Muoto: (tyyppi) lauseke int x=23,y=2; float z; z=(float)x/y; /* z == 11.5 */ • Ekspliittisen tyyppi-muunnoksen käyttö selkeyttää koodia int a=2; float b, c=4; b=(float)a+c; /* b = a+c */
++ ja -- operaattorit • ++ lisää muuttujan arvoa yhdellä • -- vähentää yhden • operaattori muuttujan nimen edessä (++a): ensin muutetaan arvoa ja sitten lasketaan lausekkeen arvo • operaattori nimen perässä (a--): ensin lasketaan lausekkeen arvo ja sitten muutetaan arvoa int x=1,y=2; x=y++; /* x==2, y==3 */ x=--y; /* x==2, y==2 */
Lukujärjestelmät • Kymmenjärjestelmä:13.5610 = 1*101+3*100+ 5*10-1+ 6*10-2 • Binääriluvut:011011112=0*27+1*26+1*25+0*24+1*23+1*22+1*21+1*20=11110 • Sama heksadesimaalimuodossa:0110 1111 6 F6F16 A=1010, B=1110, C=1210 D=1310, E=1410, F=1510
Bittioperaatioiden käytöstä • |-operaatiota käytetään bittien päälle laittamiseen • ^ -operaatiota käytetään bittien tilan vaihtamiseen • &-operaatiolla voidaan nollata halutut bitit
Etuliitteellä 0x merkitään heksadesimaalilukuja Bittitason ja (AND) Looginen ja operaatio Bittien käsittelyä #include <stdio.h> tulosta_bitit(char str[], unsigned char c); int main(void){ unsigned char a=0x5F, b=0xF5; tulosta_bitit("a", a); tulosta_bitit("b", b); tulosta_bitit("a & b", a & b); tulosta_bitit("a && b", a && b);
Bittien käsittelyä II Bittitason tai (OR) tulosta_bitit("a | b", a | b); tulosta_bitit("a ^ b", a ^ b); tulosta_bitit("a << 1", a << 1); tulosta_bitit("a >> 2", a >> 2); tulosta_bitit("~a", ~a); return 0; } Bittitason poissulkeva tai (XOR) Yhden komplementti (kääntää bitit)
Bittien tulostus tulosta_bitit(char str[], unsigned char c){ int bitti; printf("%s:\t", str); for(bitti = 7; bitti >= 0; bitti--) { if((c & (1 << bitti )) != 0 ) printf( "1" ); else printf( "0" ); } printf("\n"); }
X*=(Y+Z); X=X*(Y+Z); Sijoitusoperaattorit Sijoitusoperaattorin ’=’ lisäksi löytyy joukko tiivistettyjä sijoitusoperaattoreita Seuraaville sijoitusoperaattoreille (lauseke1) = (lauseke1) operaattori (lauseke2) tiivistetty muoto on lauseke1 operaattori=lauseke2
sizeof operaattori ja ehtolauseke • sizeof operaattori antaa muuttujan viemän tilan tavuina, kaksi muotoa:sizeof(tyyppi) sizeof muutuja • lauseke1 ? lauseke2 : lauseke3jos laukeke1 on tosi koko lausekkeen arvoon lauseke2 muutoin lauseke3 Z=(X>Y)?X:Y; if(X>Y) Z=X; else Z =Y;
Operaattoreiden tärkeysjärjestys • a=c==4;a=(c==4) • Sulkujen käyttö selkeyttää järjestystä • a=b+=c;a=(b+=c); • 2*5%3(2*5)%3 == tärkeämpi kuin = = ja += yhtätärkeitä assosiatiivisuus oikealta vasemmalle * ja % yhtätärkeitä assosiatiivisuus vasemmalta oikealle (2*5)%3 == 1
Itsemääritellyt tietotyypit enum luku {nolla, yksi, kaksi}; enum luku l=yksi;
Tietueet (structure) struct paivays{ int paiva; int kuukausi; int vuosi; }; struct paivays paiva1={15, 1, 2004}, paiva2; Ei voi sisältää struct paivays tyyppistä muuttujaa • Tietoalkioiden ryhmittelyyn • Useiden arvojen palauttamiseen funktiosta • Linkitettyjen listojen rakentamiseen
Union • union U{ double d; char c[2]; int i; } d (8 tavua) c (2) i (4 tavua)
Toisessa lähdekooditiedostossa määritellyn funktion esittely Funktion paluuarvo muuttaa pääohjelman muuttujan arvoa printf():n parametri %d tai %i tulostaa kokonaisluvun Kaksi lähdekooditiedostoa #include <stdio.h> extern int lisaa(int); int main(void){ int a = 0; a = lisaa(a); printf("a = %i\n", a); a = lisaa(a); printf("a = %d\n", a); return 0; }
Muuttuja j on staattinen eli olemassa koko ohjelman suorituksen ajan. Ensimmäisellä kutsukerralla funktio alustaa muuttujan j arvoon ’1’. j:tä kasvatetaan yhdellä paluuarvon määräämisen jälkeen Funktion lisaa() määrittely int lisaa(int i) { static int j = 1; return i + (j++); }