Sisältö. C-ohjelmointi Luento 6: tietueet ja joukot Tiina Niklander. Tietueet (struct) Määrittely Rakenne Käyttö

Samankaltaiset tiedostot
struct info { typedef struct InfoT { char firstname[20]; char firstname[20]; char lastname[20]; char lastname[20]; int age; int age;

ltö C-ohjelmointi Luento 6: tietueet ja joukot Tietueet (struct( struct) Lueteltu tyyppi (enum( enum) Union Linkitetty lista

Sisältö. Tietue - Määrittely. Tietueet (struct) Tietue - Rakenne. Tietue - Käyttö. C-ohjelmointi Luento 6: tietueet ja joukot

ltö Tietue - Rakenne C-ohjelmointi Luento 6: tietueet ja joukot muistialue. viittausten yksinkertaistamiseksi kenttien

Lyhyt kertaus osoittimista

TIETORAKENTEET JA ALGORITMIT

Tietueet. Tietueiden määrittely

Rakenteiset tietotyypit Moniulotteiset taulukot

A TIETORAKENTEET JA ALGORITMIT

1.1 Pino (stack) Koodiluonnos. Graafinen esitys ...

Tietorakenteet ja algoritmit

Sisältö. C-ohjelmointi Luento 5: Osoittimet. Keko (heap) Pino (stack) Muistinhallinta Java vs C. Prosessin rakenne

Tietorakenteet ja algoritmit

tietueet eri tyyppisiä tietoja saman muuttujan arvoiksi

Kaksiloppuinen jono D on abstrakti tietotyyppi, jolla on ainakin seuraavat 4 perusmetodia... PushFront(x): lisää tietoalkion x jonon eteen

Pino S on abstrakti tietotyyppi, jolla on ainakin perusmetodit:

Ohjelmoinnin peruskurssien laaja oppimäärä

811312A Tietorakenteet ja algoritmit II Perustietorakenteet

Tietorakenteet ja algoritmit

Tietorakenteet ja algoritmit

18. Abstraktit tietotyypit 18.1

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Sisällys. 18. Abstraktit tietotyypit. Johdanto. Johdanto

Muistin käyttö. Muistin käyttö. Muistin käyttö. Muistin käyttö. Muistin käyttö. Muistin käyttö. Muistin käyttö C-ohjelmassa

Tietorakenteet ja algoritmit

815338A Ohjelmointikielten periaatteet Harjoitus 5 Vastaukset

Algoritmit 1. Luento 4 Ke Timo Männikkö

C-ohjelmointi: Osoittimet

Loppukurssin järjestelyt C:n edistyneet piirteet

Listarakenne (ArrayList-luokka)

Kääreluokat (oppikirjan luku 9.4) (Wrapper-classes)

815338A Ohjelmointikielten periaatteet Harjoitus 3 vastaukset

Olion elinikä. Olion luominen. Olion tuhoutuminen. Olion tuhoutuminen. Kissa rontti = null; rontti = new Kissa();

Merkkijono määritellään kuten muutkin taulukot, mutta tilaa on varattava yksi ylimääräinen paikka lopetusmerkille:

Sisällys. 7. Oliot ja viitteet. Olion luominen. Olio Java-kielessä

7. Oliot ja viitteet 7.1

Algoritmit 1. Luento 6 Ke Timo Männikkö

Ohjelmoinnin perusteet Y Python

Algoritmit 2. Luento 2 To Timo Männikkö

Ohjelmointi 2. Jussi Pohjolainen. TAMK» Tieto- ja viestintäteknologia , Jussi Pohjolainen TAMPEREEN AMMATTIKORKEAKOULU

Loppukurssin järjestelyt

C-ohjelmointi, syksy 2006

C-ohjelmointi, syksy Yksiulotteiset taulukot Moniulotteiset taulukot Dynaamiset taulukot. Binääritiedostot. Luento

Ohjelmoinnin peruskurssien laaja oppimäärä

Luennon sisältö. Taulukot (arrays) (Müldnerin kirjan luku 10) Yksiulotteiset taulukot. Mikä taulukko on? Taulukko-osoitin. tavallinen osoitin

Olio-ohjelmointi Syntaksikokoelma

Osoitin ja viittaus C++:ssa

Ohjelmassa muuttujalla on nimi ja arvo. Kääntäjä ja linkkeri varaavat muistilohkon, jonne muuttujan arvo talletetaan.

ITKP102 Ohjelmointi 1 (6 op)

3. Binääripuu, Java-toteutus

Muuttujien roolit Kiintoarvo cin >> r;

Jakso 4 Aliohjelmien toteutus

Aliohjelmatyypit (2) Jakso 4 Aliohjelmien toteutus

JAVA-PERUSTEET. JAVA-OHJELMOINTI 3op A JAVAN PERUSTEET LYHYT KERTAUS JAVAN OMINAISUUKSISTA JAVAN OMINAISUUKSIA. Java vs. C++?

Dynaaminen muisti. Pasi Sarolahti Aalto University School of Electrical Engineering. C-ohjelmointi Kevät 2017.

useampi ns. avain (tai vertailuavain) esim. opiskelijaa kuvaavassa alkiossa vaikkapa opintopistemäärä tai opiskelijanumero

Luento 4 Aliohjelmien toteutus

Algoritmit 1. Demot Timo Männikkö

Tieto- ja tallennusrakenteet

Java-kielen perusteet

11. oppitunti III. Viittaukset. Osa. Mikä on viittaus?

ITKP102 Ohjelmointi 1 (6 op)

TIE448 Kääntäjätekniikka, syksy Antti-Juhani Kaijanaho. 27. lokakuuta 2009

Rakenne. C-ohjelmointi: Tietorakenteita ja tyyppejä. Tyyppimuunnoksia aritmeettisten tyyppien välillä. Tyyppimuunnokset. & (bitti and) Bittioperaatiot

Dynaaminen muisti Rakenteiset tietotyypit

C-kielessä taulukko on joukko peräkkäisiä muistipaikkoja, jotka kaikki pystyvät tallettamaan samaa tyyppiä olevaa tietoa.

Metodien tekeminen Javalla

Harjoitus 4 (viikko 47)

Jakso 4 Aliohjelmien toteutus

Algoritmit 2. Luento 2 Ke Timo Männikkö

Taulukot. Jukka Harju, Jukka Juslin

2. Olio-ohjelmoinista lyhyesti 2.1

C-ohjelmointi Luento 5: Osoittimet Tiina Niklander

Linkitetystä listasta perittyä omaa listaa käytetään muun muassa viestiin liittyvien vastausten säilömiseen.

2. Perustietorakenteet

C-ohjelmointi Luento 5: Osoittimet

Algoritmit 2. Luento 7 Ti Timo Männikkö

Java kahdessa tunnissa. Jyry Suvilehto

Luokassa määriteltävät jäsenet ovat pääasiassa tietojäseniä tai aliohjelmajäseniä. Luokan määrittelyyn liittyvät varatut sanat:

4. Olio-ohjelmoinista lyhyesti 4.1

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

TIEA341 Funktio-ohjelmointi 1, kevät 2008

Olio-ohjelmointi Javalla

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssien laaja oppimäärä

Java-kielen perusteet

Algoritmit 1. Demot Timo Männikkö

Tietorakenteet. JAVA-OHJELMOINTI Osa 5: Tietorakenteita. Sisällys. Merkkijonot (String) Luokka String. Metodeja (public)

Kompositio. Mikä komposition on? Kompositio vs. yhteyssuhde Kompositio Javalla Konstruktorit set-ja get-metodit tostring-metodi Pääohjelma

Tiedostot. Tiedostot. Tiedostot. Tiedostot. Tiedostot. Tiedostot

Tietorakenteet ja algoritmit

#include <stdio.h> // io-toiminnot. //#define KM_MAILISSA int main( ){

Java-kielen perusteet

Modulaarinen ohjelmointi Kertaus osoittimista

Osoittimet ja taulukot

Aliohjelmatyypit (2) Jakso 4 Aliohjelmien toteutus

Sisällys. 1. Omat operaatiot. Yleistä operaatioista. Yleistä operaatioista

Osa VII. Mitä mallit ovat ja kuinka niitä käytetään Miksi mallit tarjoavat paremman vaihtoehdon makroille Kuinka luokkamalleja luodaan

Transkriptio:

C-ohjelmointi Luento 6: tietueet ja joukot 21.2.2006 Tiina Niklander Tietueet (struct) Määrittely Rakenne Käyttö Lueteltu tyyppi (enum) Joukot (union) Määrittely Rakenne Käyttö Linkitetty lista Sisältö 1

Tietueet (struct) Tietueessa voi olla vain datakenttiä (vrt. luokka) Tietueen kentät voivat olla keskenään erilaisia. Kenttiä ei voi piilottaa, vaan ne kaikki näkyvät (vrt. public). Ajatellaan hetkinen Javan luokkatoteutusta Pikkuvarasto (A.Wiklan Java-kurssi). Tällä luokalla on metodi vievarastoon. Metodikutsu x.vievarastoon(y) koskettaa kahta oliota: This, tässä x ja y, joka välitettiin parametrina C:ssä voi vastaavaa toimintaa jäljitellä, mutta tuo this on välitettävä funktiolle parametrina, joten C:ssä vastaava funktio olisi muotoa vievarastoon(x,y); Tietue - Määrittely struct info char firstname[20]; char lastname[20]; int age; ; struct info i1, i2; typedef struct InfoT char firstname[20]; char lastname[20]; int age; InfoT; InfoT p1; Suositeltavin tapa Tietueen kenttiin viitataan muodolla nimi.kenttänimi: p1.age = 18; printf("%s\n", i2.firstname); struct info char firstname[20]; char lastname[20]; int age; k1, k2; 2

Tietue - Rakenne Tietueelle varataan yhtenäinen muistialue. Kuitenkin muistialueen koko voi olla eri kuin kenttien yhteenlasketut koot, koska viittausten yksinkertaistamiseksi kenttien välejä saatetaan jättää käyttämättä. Esim: sizeof(infot)?>=? 40*sizeof(char)+sizeof(int) Tietue - Käyttö InfoT i1, i2; Tietueen sijoittaminen toiselle i1 = i2 kopioi tietueen sisällön bitti kerrallaan täsmälleen samanlaisena, mutta ei seuraa kentissä mahdollisesti olevia osoittimia. Tietueita EI voi verrata suoraan: i1 == i2 vaan vertailu on tehtävä itse: strcmp(i1.firstname, i2.firstname) == 0 && strcmp(i1.lastname, i2.lastname) == 0 && i1.age == i2.age 3

Sisäkkäiset tietueet Tietueen kenttinä voi olla myös tietueita e1: info: firstname: lastname: age: salary: e1.info.age = 21; e1.salary = 125.6; typedef struct char firstname[20]; char lastname[20]; int age; InfoT; typedef struct InfoT info; double salary; EmployeeT; EmployeeT e1; Osoitin tietueeseen Tietueita käsitellään usein osoitinmuuttujan kautta: (*p).x tai p->x typedef struct pair double x; double y; PairT,, *PairTP* PairTP; PairT x; PairTP p; PairT w; PairTP q; PairTP p = &w; if((q = malloc(sizeof(pairt))) == NULL) if((q = malloc(sizeof(struct pair))) == NULL) w.x = 2; p->x = 1; (*p).x = 1; *p.x = 1; q->y = 3.5; 4

Tietueet ja funktiot: tietue viiteparametrina void constructorp(pairtp this, double x, double y) this->x = x; this->y = y; Funktio saa osoittimen Kutsujan aiemmin varaaman tietueen PairT w; muistialueeseen. PairTP p; constructorp(&w,, 1, 2); if((p = malloc(sizeof(pairt))) == NULL) error; constructorp(p,, 1, 2); Tietueet ja funktiot: tietue paluuarvona Funktio voi palauttaa kokonaisen tietueen. Silloin kutsujan on tehtävä palautetusta tietueesta kopio, koska alkuperäinen vapautuu pinosta funktiosta palattua. PairT constructorfunc(double x, double y) PairT p; p.x = x; p.y = y; Pinossa palautettu return p; tietue on kopioitava heti talteen. PairT w = constructorfunc(1, 2.2); /* kopio */ 5

Tietueet ja funktiot: osoitin paluuarvona Funktio varaa tilan tietueelle, jolloin kutsujan vastuulle jää vapauttaa tuo varattu tila. PairTP constructor(double x, double y) /* client responsible for deallocation */ PairTP p; if((p = malloc(sizeof(pairt))) == NULL) return NULL; p->x = x; Funktio varaa tilan tietueelle p->y = y; Ja palauttaa osoittimen siihen return p; Kutsuja vapauttaa tilan myöhemmin. PairTP p1 = constructor(1, 2); free(p1); Tietueet ja funktiot: osoitin paluuarvona Käyttö toisen funktion parametrina: int compare(const PairTP p, const PairTP q) return p->x p == q->x q && p->y p == q->y; q PairTP p2 = constructor(1, 3); PairTP p3 = constructor(2, 6); int i = compare(p3, p2); free(p2); free (p3); Vältä muistivuotoa! i = compare(p1, constructor(3.5, 7)); Tässä kadotetaan osoitin tietueeseen, joten muisti jää vapauttamatta 6

Muistilohko tietueista Muistilohkon käsittely ei riipu lohkon alkioiden tyypistä. Tietueen omiin alkioihin viittaus kuten itsenäisissäkin tietueissa. PairTP rectangle; PairTP aux; double x, y; rectangle pair pair pair pair if((rectangle= = malloc(4*sizeof(pairt sizeof(pairt)))== )))==NULL) NULL)error; for(aux = rectangle; aux < rectangle + 4; aux++) printf("enter two double values:"); if(scanf("%lf%lf", ", &x, &y)!= 2) /* error */ break; constructorp(aux,, x, y); Osoitinlohko tietueisiin Mahdolliset viittaustavat: prectangle[1][0].x prectangle[1]->x (prectangle+1)->x prectangle int i; PairTP *prectangle; for(i = 0; i < 4; i++) printf("enter two double values:"); if(scanf("%lf%lf", ", &x, &y)!= 2) error; if((prectangle[i] ] = constructor(x,, y)) == NULL) error; for(i = 0; i < 4; i++) printf("vertex %d = (%f %f)% f)\n", i, prectangle[i][0].x, prectangle[i][0].y); pair 1 x y pair pair 7

Lueteltu tyyppi (enum) Luetellun tyypin määrittelemät järjestetyt vakiot vastaavat järjestyksessä kokonaislukuja 0,1,2 jne. Numeroinnin voi myös aloittaa haluamastaan arvosta typedef enum opcodes lvalue, rvalue, push, plus OpcodesT; enum opcodes e; OpcodesT f; int i = (int)rvalue( int)rvalue; ; /*i=1*/ enum opcodes lvalue = 1, rvalue, push, plus ; enum opcodes e = lvalue; if(e == push) int i = (int)rvalue( int)rvalue;/*i=2*/ Lueteltu tyyppi funktion paluuarvona Lueteltua tyyppiä voi käyttää virhetiedon käsittelyssä Virheilmoitustekstit kootaan taulukkoon, jota indeksoidaan luetellun tyypin alkioita vastaavilla kokonaislukuarvoilla typedef enum FOPEN, FCLOSE, FOK FoperT; #define TOINT(f) ) ((int)(f int)(f)) )) char *Messages[] = "File can not be opened", "File can not be closed", "Successful operation", "This can not happen" ; FoperT process(); printf("result of calling process() is %s\n",% Messages[TOINT(process())]; ())]; 8

Joukot (union) Tietue Alkiot peräkkäin eli kaikki käytettävissä Joukko Alkiot päällekkäin eli vaihtoehtoisia struct intanddouble int i; double d; ; int double int double union intordouble int i; double d; ; intanddouble intordouble Käyttö yleensä tietueen osana Tietueessa kenttä (tag), joka kertoo miten joukko pitää tulkita Käytetään paljon tietoliikenneprotokollissa säästämässä tilaa Kenttiin viitataan samalla pistenotaatiolla kuin tietueidenkin kenttiin Joukko - Käyttö typedef enum integer, real TagTypeT; typedef struct TagTypeT tag; union int i; double d; value; TaggedValueT; TaggedValueT v; if(v.tag == integer) v.value.i ; else v.value.d ; 9

Tauko Linkitetyt tietorakenteet Abstraktit tietorakenteet Käsitelty Tietorakenteiden kurssilla Kannattaa kerrata kaikki rakenteet sieltä Pino : operaatiot push, pop ja empty Jono: operaatiot enqueue, dequeue ja empty Linkitetty lista rakenteesta päätettävä Yhteen suuntaan vai kahteen suuntaan Rengas vai ei Tunnussolmu vai ei Järjestetty vai järjestämätön Alkiot erilaisia vai sallitaan myös samanlaiset alkiot 10

Linkitetty lista - Määrittely Tunnussolmullinen yhteensuuntaan linkitetty NULL arvoa käytetään aina listan lopun osoittamiseen Huomaa seuraavaan alkioon osoittavan kentän määrittely! typedef double DataType; typedef struct elem DataType value; struct elem *;,, *P* P; typedef struct P first; ListT,, *ListTP* ListTP; ListTP p; p first ListT value 2 value 3.5 NULL Linkitetty lista Tunnussolmun luonti ja poisto Listan luonti Tehdään vain tunnussolmu ja asetetaan linkit Listan poistaminen Alkioiden poistoon oma funktio Tässä vain tunnussolmun tilan vapautus ListTP construct(void) ) ListTP p; if((p = malloc(sizeof(listt))) == NULL) return NULL; p->first = NULL; return p; void destruct(listtp *this) clear(*this); /* alkiot pois */ free(*this); *this = NULL; 11

Linkitetty lista - Käyttö Kaikkien listaa käsittelevien toimintojen täytyy säilyttää seuraavat invariantit: Tyhjälle listalle pätee p->first onnull. Epätyhjälle listalle pätee, että viimeisen alkionkentän arvo onnull. p first ListT p NULL first ListT value 2 value 3.5 NULL Linkitetty lista - Käyttö Operaatioita: Listan läpikäynti p first ListT value 2 Aina linkien kulkusuuntaan Listaan lisääminen Alkuun, loppuun, keskelle Listasta poistaminen Alusta, lopusta, keskeltä value 3.5 NULL 12

Listan läpikäynti p first ListT value 2 value 3.5 aux void printall(const ListTP this) P aux; for(aux=this =this->first; aux!=null; aux=aux aux->) printf("%f\n", ", aux->value); NULL /* pidetään aux edellisessä alkiossa */ If ((p->first!= NULL) && (p->first->!=null)) for(aux = p->first; aux->!= NULL; aux = aux->)... Lisäys listan alkuun p first ListT value 2 value 3.5 int insertfront(listtp this, DataType d) P aux; if((aux = malloc(sizeof())) == NULL) return 0; aux-> = this->first; /* save state */ aux->value = d; this->first = aux; return 1; value 2 NULL 13

Viimeisen alkion p poisto listasta first ListT value 2 value 3.5 int deletelast(listtp this, DataType *value) P aux; NULL if(this->first == NULL) /* empty list */ return 0; if(this->first >first-> > == NULL) /* single */ *value = this->first >first->value; >value; free(this->first); this->first = NULL; return 1; for(aux = this->first; aux-> >->!= NULL; aux = aux->) ; /* aux viimeistä edelliseen */ *value = aux-> >->value; >value; free(aux->); aux-> = NULL; return 1; Koko listan tuhoaminen Tuhotaan alkio kerrallaan edetään lista alusta loppuun int deletefirst(listtp this) P aux = this->first; if(aux == NULL) /* empty list */ return 0; this->first = aux->; free(aux); return 1; void clear(listtp this) while(deletefirst(this)) ; this->first = NULL; 14

ModuuliList Tehdään oma käännösyksikkö (moduuli), joka sisältää listan määrittelyt ja käsittelyfunktiot Tässä tehtävällä moduulilla on seuraavat piirteet Moduuli pystyy käsittelemään useita eri listoja Moduuli käsittelee void-tyypistä dataa, joten eri listoihin voi sijoittaa eri tyyppistä tietoa Listan sisäinen toteutus ei näy käyttäjälle Listan käyttäjä vastaa datan rakenteesta ja käsittelystä Tyypin määrittelyt: ListItem ja List Funktiot: CreateList, CreateItem, AddTail, AddHead, ListLength, DeleteList, PrintList, EmptyList Lähde: Jan Lindströmin verkkomoniste Moduulin tarjoama rajapinta: list.h #ifndef MY_LIST_LIBRARY #define MY_LIST_LIBRARY /* Määritellään listatyypit */ typedef struct listitem struct listitem *Next; /* Seuraava alkio listassa */ struct listitem *Prev; /* Edellinen alkio listassa */ void *Data; /* Tietoalkio */ unsigned long Size; /* Tietoalkion koko */ ListItem; typedef struct ListItem *Head; /* Listan alku */ ListItem *Tail; /* Listan loppu */ unsigned long Items; /* Listan alkioiden lkm */ List; 15

List.h jatkuu /* Listakirjaston tukemat funktiot */ extern List *CreateList(void); /* Luo uusi lista */ extern ListItem *CreateItem(void *Data, unsigned long Size); /* Luo lista-alkio */ extern int AddTail(List *,ListItem *); /* Lisää listan loppuun */ extern int AddHead(List *,ListItem *); /* Lisää listan alkuun */ extern unsigned long ListLength(List *); /* Laske listan pituus */ extern void DeleteList(List *); /* Tuhoa lista */ extern void PrintList(List *); /* Tulosta listan sisältö */ extern int EmptyList(List *); /* Tarkista onko lista tyhjä */ #endif List.c : CreateList /* Varataan muistia uudelle listalle ja alustetaan kentät */ List *CreateList(void) List *uusi; if(!(uusi = (List *)malloc(sizeof(list)))) return NULL; uusi->head = NULL; uusi->tail = NULL; uusi->items = 0; return uusi; 16

List.c: CreateItem /* Varataan muistia uudelle listan alkiolle ja alustetaan kentät */ ListItem *CreateItem(void *Data,unsigned long size) ListItem *uusi; /* Jos järkevää dataa ei ole annettu poistu */ if (Data == NULL) return NULL; if(!(uusi = (ListItem *)malloc(sizeof(listitem)))) return NULL; if(!(uusi->data = (void *)malloc(size))) return NULL; uusi->next = NULL; uusi->prev = NULL; memcpy(uusi->data,data,size); uusi->size = size; return uusi; List.c: AddTail /* Lisätään alkio listan loppuun */ extern int AddTail(List *lista,listitem *item) if (lista == NULL item == NULL ) return 1; if ( lista->head == NULL) lista->head = lista->tail = item; else lista->tail->next = item; item->prev = lista->tail; lista->tail = item; lista->items++; return 0; 17

List.c: AddHead /* Lisätään alkio listan alkuun */ extern int AddHead(List *lista,listitem *item) if (lista == NULL item == NULL ) return 1; if ( lista->head == NULL) lista->head = lista->tail = item; else lista->head->prev = item; item->next = lista->head; lista->head = item; lista->items++; return 0; List.c: ListLength ja EmptyList /* 'Lasketaan' listan pituus */ unsigned long ListLength(List *lista) if ( lista == NULL ) return 0; else return lista->items; /* Tarkista onko lista tyhjä */ int EmptyList(List *lista) if ( lista == NULL) return 1; else if (lista->head == NULL ) return 1; else 18

List.c:DeleteList /* Tuhotaan koko lista */ void DeleteList(List *lista) ListItem *tmp; if ( lista == NULL ) return; tmp = lista->head; while(tmp!= NULL) tmp = lista->head->next; free(lista->head->data); free(lista->head); lista->head = tmp; free(lista); List.c: PrintList /* Tulostetaan koko lista */ void PrintList(List *lista) ListItem *tmp = lista->head; printf(" "); while(tmp!= NULL) printf("%s ",(char *)tmp->data); tmp = tmp->next; printf(" -\n"); Tässä oletetaan, että listassa on merkkijonoja. Parempi ratkaisu olisi käyttää funktioparametria data-alkioiden käsittelyyn. Käyttäjä joutuisi silloin itse ohjelmoimaan alkioiden käsittelyn, mutta listan käyttöalue kasvaisi. 19

Harjoitustyö Käytettävät piirteet: Linkitetty tietorakenne osoittimilla (pino, lista, puu, hajautustaulu, ) Tiedosto (tekstitiedosto tai binääritiedosto) Komentoriviparametrit (jos ei muuta järkevää, niin ainakin h opastus) Funktioita parametreineen mielekkäästi Käännyttävä laitoksen Linux-ympäristössä gcc:n parametreilla ansi pedantic ja Wall ilman varoituksia Vähintään kaksi käännösyksikköä ja make Koodi dokumentoitava järkevästi Erillinen lyhyt rakennedokumentti ja käyttöohje Aiheet 1. Yksinkertainen laskin 2. Sanalaskuri 3. Kaupan kassan simulointi 4. Lennon varausjärjestelmä 5. Työntekijärekisteri 6. Ravintolan simulointi 7. Sukupuu 8. Kokkaavan ystävän apu 20

Aiheen valinta Aihe olisi syytä valita mahdollisimman pian pe 17.3. mennessä Valinnan voi kertoa sähköpostilla: Liisa.Marttinen@cs.helsinki.fi Tai 2. periodin ensimmäisellä viikolla luennolla tai laskareissa. Omista (varsinkin simulointityyppisistä) aiheista voi neuvotella Liisan tai Tiinan kanssa 21