Tietorakenteet ja C-kieli
description
Transcript of Tietorakenteet ja C-kieli
Tietorakenteet ja C-kieliTietorakenteet ja C-kieliTkT Jarno Mielikäinen
e-mail: [email protected]: ke 11-12
LuennotLuennot
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
HarjoituksetHarjoitukset
EI pakolliset, mikroluokassa 6325 ti 16-18, 18:00-19:30, ke 12-14
to 8.30-10, 10-12, 12-14, pe 10-12Olennainen osa oppimistaKokeile, jos et osaa, kysyRatkaisut annetaan, jos et ymmärrä, kysyJos löydät vaihtoehtoisen/paremman
ratkaisun, kerro
HarjoitustyötHarjoitustyöt
1. harjoitustyö 3. periodin lopussa2. harjoitustyö 4. periodin lopussa
TentitTentit
1. välikoe 5.3 klo 162. välikoe 7.5 klo 16Tentti 14.5 klo 16
n Alpha 21164A533MHz,C-kieli,
kuutiollinen algoritmi
TRS-80,2.03 MHz
Basic,lineaarinenalgoritmi
10 0.6 s 200 ms
100 0.6 ms 2.0 s
1000 0.6 s 20 s
10000 10 min 3.2 min
100000 7 päivää 32 min
1000000 19 vuotta 5.4 h
Kurssin tavoitteet: C-kieliKurssin tavoitteet: C-kieli
C-kielisten ohjelmien luku ja kirjoitustaidot
Ymmärrät kaikki C:n rakenteetOsoittimien (pointterien) käyttötaitoYleiskatsaus kirjastofunktioihinTietoinen C:n sudenkuopista
Kurssin tavoitteet: Kurssin tavoitteet: tietorakenteettietorakenteet
Yleisempien tietorakenteiden tuntemus:taulukot, pinot, jonot, listat, puut, keot ja graafit
Tietorakenteen valinta käytettävien operaatioiden perusteella (lisääminen, poistaminen, jne.)
Kurssin tavoitteet: algoritmitKurssin tavoitteet: algoritmit
Johdattelua algoritmien kompleksisuus analyysiin
LajittelualgoritmejaHakualgoritmeja
Miksi C-kieli?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 historiaC-kielen historia
Kernigan & Ritchie (K&R), 1972ISO/IEC 9899-1990 (C89, ANSI C)ISO/IEC 9899-1999 (C99)Tällä kurssilla käsitellään C89:ä
#include <stdio.h>
int main(void){ printf(”Tervetuloa kurssille!\n”); return 0; /* paluuarvo == 0 OK */}
Pääohjelma
C-OhjelmaC-Ohjelma
”Loppu”
”Alku”
Kertoo kääntäjälle syöttö- ja tulostusfunktioista (printf + muut)
MerkkijonovakiotMerkkijonovakiot
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
MuuttujatMuuttujat
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
MuistimääritteetMuistimääritteet
Määrite Tarkoitus
auto Muutujat ovat oletusarvoisesti tällaisia
const Muuttujan arvo on vakio
register Vihje kääntäjälle viittauksien nopeuttamiseksi
extern Muuttujan määritelmä löytyy muualta
static Muuttuja on olemassa ohjelman suorituksen ajan
typedef Tyyppimäärittely
volatile Arvo voi muuttua ulkoisista syistä
C-kielen varatut sanatC-kielen varatut sanat
auto double int struct
break else long switch
case enum register typedef
char extern return union
const float short unsigned
continue for signed void
default goto sizeof volatile
do if static while
KokonaislukutietotyypitKokonaislukutietotyypitTyyppi Tulkinta Tavutchar Yksittäinen merkki 1signed char etumerkillinen merkki 1unsigned char etumerkitön merkki 1short int lyhyt kokonaisluku väh. 2unsigned short etumerkitön kokonaisluku väh. 2int kokonaisluku väh. 2unsigned int etumerkitön kokonaisluku väh. 2long int pitkä kokonaisluku väh. 4unsigned long etumerkitön pitkä
kokonaislukuväh. 4
GNU Compiler Collection(GCC)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
LiukulukutyypitLiukulukutyypit
Tyyppi Tulkinta
float liukuluku
double kaksoistarkkuudenliukuluku
long double vielä tarkempiliukuluku
VakiotVakiot
. tai E:n sisältävät luvut ovat tyyppiä double
F numeron perässä määrittää floatinTyypille long double lisää LMuutoin luku on tyyppiä intKokonaisluvuille L määrittää
tyypin long int
-1.2325E+34
c:n E+X tarkoittaa 10+X
-1.23F25E+34F
-1.23L25E+34L
1232534
123L2534L
Liukulukuja ei vertailla näinLiukulukuja 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 vertailuaLiukulukujen vertailua
#include <stdio.h>#define EPSILON 0.0001int 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);}
abs() on itseisarvofunktio
EPSILON korvataan 0.0001:lläennen varsinaista käännöstä
C:n operaattoritC:n operaattorit
VertailuoperaattoritAritmeettiset operaattoritBittitason operaattoritSijoitusoperaattoritsizeof operaattoriEhtolausekeTyyppimuunnos
VertailuoperaatoreitaVertailuoperaatoreita
suurempi kuin >suurempi tai yhtäsuuri kuin >=pienempi kuin <pienempi tai yhtäsuuri kuin <=yhtäsuuri ==erisuuri !=looginen ja &&looginen tai ||kääntää totuusarvon !
VertailuaVertailua
#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 EvaluationShort-Circuit EvaluationEnsimmäinen epätosi &&-operaatorin
yhdistämä lauseke päättää evaluoinnin
int a=0, b=1, c=2; if((b=a) && (b=c+2)) printf("Ihme\n");
b saa arvoksi 0:n ei 2+2=4koska (b=a) on epätosi eli nolla
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
Aritmeettiset operaattoritAritmeettiset operaattorit
yhteenlasku +vähennyslasku -kertolasku *jakolasku /jakojäännös (kokonaisluvuille) %
int x=23,y=2; float z;z=x/y; /* z == 11 */
Jakolasku suoritetaan tyypille int, jonka jälkeentulos sijoitetaan tyyppiin float
Tapahtuu implisiittinen tyyppimuunnos
TyyppimuunnoksetTyyppimuunnokset
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 tyyppimuunnosEksplisiittinen 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++ ja -- operaattorit
++ lisää muuttujan arvoa yhdellä-- vähentää yhdenoperaattori 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ätLukujä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
Bittien käsittely operaattoritBittien käsittely operaattoritA 01011111
B 11110101
Biteittäin suoritettava ja (AND) A & B 01010101
Biteittäin suoritettava tai (OR) A | B 11111111
Biteittäin suoritettava poissulkeva tai (XOR)
A ^ B 10101010
Siirto vasemmalle biteittäin A << 1 10111110
Siirto oikealle biteittäin B >> 2 00110111
Yhden komplementti (kääntää bitit) ~A 10100000
Bittioperaatioiden käytöstäBittioperaatioiden käytöstä |-operaatiota käytetään
bittien päälle laittamiseen
^ -operaatiota käytetään bittien tilan vaihtamiseen
&-operaatiolla voidaan nollata halutut bitit
luku 11110000
maski 00110011luku^maski 11000011
luku 11110000
maski 00110011luku|maski 11110011
luku 11110000
maski 00110011luku&maski 00110000
Bittien käsittelyä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);
Bittitason ja (AND)
Looginen ja operaatio
Etuliitteellä 0x merkitään heksadesimaalilukuja
Bittien käsittelyä IIBittien käsittelyä II
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 tai (OR)
Bittitason poissulkeva tai (XOR)
Yhden komplementti (kääntää bitit)
Bittien tulostusBittien 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");}
SijoitusoperaattoritSijoitusoperaattorit
+= -= *= /= %=
&= |= ^= <<= >>=
Seuraaville sijoitusoperaattoreille
(lauseke1) = (lauseke1) operaattori (lauseke2)tiivistetty muoto onlauseke1 operaattori=lauseke2
X*=(Y+Z);
X=X*(Y+Z);
Sijoitusoperaattorin ’=’ lisäksi löytyy joukko tiivistettyjäsijoitusoperaattoreita
sizeof operaattori ja ehtolausekesizeof operaattori ja ehtolauseke
sizeof operaattori antaa muuttujan viemän tilan tavuina, kaksi muotoa:sizeof(tyyppi)
sizeof muutuja lauseke1 ? lauseke2 : lauseke3
jos laukeke1 on tosi koko lausekkeen arvoon lauseke2 muutoin lauseke3
Z=(X>Y)?X:Y;
if(X>Y) Z=X; else Z =Y;
Tärkeysjärjestys/assosiatiivisuus Tärkeysjärjestys/assosiatiivisuus taulukkotaulukko
Operaattori Assosiatiivisuus
() [] -> . vasemmalta oikealle
~ ++ -- - (tietotyyppi) * & sizeof oikealta vasemmalle
* / % vasemmalta oikealle
+ - vasemmalta oikealle
<< >> vasemmalta oikealle
< <= > >= vasemmalta oikealle
== != vasemmalta oikealle
& vasemmalta oikealle
^ vasemmalta oikealle
| vasemmalta oikealle
&& vasemmalta oikealle
|| vasemmalta oikealle
?: oikealta vasemmalle
= += -= *= /= %= &= |= ^= <<= >>= oikealta vasemmalle
, vasemmalta oikealle
Operaattoreiden Operaattoreiden tärkeysjärjestystä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 vasemmaltaoikealle
(2*5)%3 == 1
Itsemääritellyt tietotyypitItsemääritellyt tietotyypit
Määrite Tarkoitus
enum Määrittelee nimettyjä kokonaisluku vakioita
struct Joukko tietotyyppejä
union Joukko vaihtoehtoisia tietotyyppejä
enum luku {nolla, yksi, kaksi}; enum luku l=yksi;
Tietueet (structure)Tietueet (structure) struct paivays{ int paiva; int kuukausi; int vuosi; }; struct paivays paiva1={15, 1, 2004}, paiva2;
Ei voi sisältää struct paivaystyyppistä muuttujaa
Tietoalkioiden ryhmittelyynUseiden arvojen palauttamiseen funktiostaLinkitettyjen listojen rakentamiseen
UnionUnion
union U{ double d; char c[2]; int i; }
d (8 tavua)
c (2)
i (4 tavua)
Kaksi lähdekooditiedostoaKaksi 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; }
Toisessa lähdekooditiedostossa määritellyn funktion esittely
Funktion paluuarvo muuttaa pääohjelman muuttujan arvoa
printf():n parametri %d tai %i tulostaa kokonaisluvun
Funktion lisaa() määrittelyFunktion lisaa() määrittelyint lisaa(int i) { static int j = 1; return i + (j++); }
Muuttuja j on staattinen eli olemassa koko ohjelman
suorituksen ajan. Ensimmäisellä kutsukerralla funktio
alustaa muuttujan j arvoon ’1’.
j:tä kasvatetaan yhdellä paluuarvonmääräämisen jälkeen