C-ohjelmointi, kevät 2006 Taulukot Binääritiedostot Luento

Slides:



Advertisements
Samankaltaiset esitykset
Tuloksellinen Java-ohjelmointi Luku 3 Luokkien käyttäminen
Advertisements

18. Abstraktit tietotyypit
Copyright  Hannu Laine Bittitason-operaatiot Hannu Laine.
Tietorakenteet ja algoritmit
Olio-ohjelmoinnin perusteet luento 3: Muuttujista ja funktioista Sami Jantunen LTY/Tietotekniikan osasto.
© Hannu Laine 1 Tietorakenteet ja algoritmit Funktio-osoittimet Funktio-osoittimen ja taulukko-osoittimen vertailu Funktio-osoittimen käyttötapoja.
Tietorakenteet ja algoritmit
11/9/2012 © Hannu Laine 1 Tietorakenteet ja algoritmit Elegantti toteutus funktiolle insert_to_list_end Alkion lisäys sisällön mukaan järjestettyyn listaan.
Taulukot Jukka Juslin © Jukka Juslin 2006.
Taulukot: Array Taulukko Javassa pitää aina perustaa (new)
Taulukoiden määrittely, käsittely ja kopiointi Vaihtoehdot taulukoille
Copyright  Hannu Laine Osoittimet ja taulukot Hannu Laine.
C-kieli ja dynaaminen muistin varaus
22. Taulukot.
Rakenteinen ohjelmointi
Komentoriviparametrit
Kertaus osoittimista Modulaarinen ohjelmointi
@ Leena Lahtinen OHJELMAN OSITTAMINEN LUOKKA ATTRIBUUTIT METODIT.
Ohjelman jakaminen useampaan tiedostoon Olio-ohjelmointi (C++) KYAMK, Jarkko Ansamäki 2001.
OLIO-OHJELMOINTI PERUSTEET PERUSTIETOTYYPIT
TyyppimuunnoksettMyn1 Tyyppimuunnokset Joskus kääntäjän on tehtävä itse päätöksiä, jos ohjelmoija ei ole ajatellut yksityiskohtia: int arvo1=10; long arvo2=25;
Vakio-osoitin ja osoitin vakioon tMyn1 Vakio-osoitin ja osoitin vakioon Tavallinen osoitin voi vaihtaa osoitettavaa keskusmuistialuetta. Tämä voidaan tehdä.
Toiston tekeminen Javalla  Mikä toistorakenne on?  while toistorakenne  do-while toistorakenne  for toistorakenne 1.
TAULUKKO YKSIULOTTEINEN TAULUKKO. TAULUKKO  Taulukon tarkoitus Ohjelmassa tarvitaan paljon samantyyppisiä samaan kohdealueeseen kuuluvia muuttujia Näitä.
Osoitin ja char- tietotyyppi tMyn1 Osoitin ja char-tietotyyppi Osoitinmuuttuja, joka on tyyppiä char* voidaan alustaa merkkijonolla: char* alku=”En toivo.
Sami Jantunen LTY/Tietotekniikan osasto
© Lammi-Niskala-Kossarev ADT:n toteutus Imperatiivinen paradigma Imperatiivinen paradigma toimenpiteet aktiivisia, tiedot passiivisia toimenpiteet.
13. Hyvä ohjelmointitapa (osa 1)
Virtuaaliset jäsenfunktiot tMyn1 Virtuaaliset jäsenfunktiot Virtuaalinen jäsenfunktio on esiteltävä monimuotoisessa kantaluokassa. Virtuaalisen jäsenfunktion.
© Jukka Harju, Jukka Juslin
1 Kertaus koetta varten oleellisista asioista Jukka Juslin.
Johdetun luokan olion alustus tMyn1 Johdetun luokan olion alustus määrätyillä arvoilla Kun ohjelmassa esiintyy johdetun luokan olion määrittely, järjestelmä.
C-ohjelmoinnin perusteet
Tietotyypit Tietotyyppi määrittää muuttujan sisältämän datan luonnetta, muistista tarvittavaa tilaa ja sitä, millaisia operaatioita siihen voidaan kohdistaa.
Lueteltu tyyppitMyn1 Lueteltu tyyppi Lueteltu tyyppi on tietotyyppi, jonka arvot luetellaan erikseen tyypin määrittelyn yhteydessä. Lueteltua tietotyyppiä.
Muuttujat ja vakiottMyn1 Muuttujat ja vakiot PHP-kielen syntaksi on lainattu suurimmaksi osaksi C- kielestä. PHP on erityisesti HTML-dokumenttien sisään.
4. Attribuutit 4.1. Sisällys Yleistä attribuuteista. Näkyvyys luokan sisällä ja ulkopuolelta. Attribuuttien arvojen käsittely aksessoreilla. 4.2.
@ Leena Lahtinen OHJELMAN OSITTAMINEN LUOKKA ATTRIBUUTIT METODIT.
Olioon kohdistuvia perustoimintoja tMyn1 Olioon kohdistuvia perustoimintoja Kopiointimuodostin (copy constructor) alustaa olion tietojäsenet saman luokan.
22. Taulukot.
Poikkeukset Yleistä Virheeseen varautuminen tarkoittaa sitä, että ohjelmoija huomioi koodia kirjoittaessaan ajonaikaisen virheen mahdollisuuden.
Johdatus ohjelmointiin – C kielen peruselementit Tutkijayliopettaja Manne Hannula Opetusharjoittelu (ohjaava opettaja Jukka Jauhiainen)
Visual Basic -ohjelmointi
Ohjelmointi työtä n. 16 h/vko onnistumista työtä n. 16 h/vko onnistumista #include int main(void) { std::cout
Johdetun luokan olion alustus tMyn1 Johdetun luokan olion alustus määrätyillä arvoilla Kun ohjelmassa esiintyy johdetun luokan olion määrittely, järjestelmä.
1 © Jukka Juslin Luokat, attribuutit ja metodit Yleistietoa: seuraavalla koulutusviikolla tarkempi käsittely.
Ohjelmointi 1. toinen luento1 Taulukot n Kiinteät taulukot: alkioiden määrä tiedetään Dim intCount(12) As Integer 0 indeksit saavat arvoja 0-12 (Option.
14. Poikkeukset Sisällys Johdanto poikkeuksiin. Poikkeusten käsittely: − Poikkeusten käsittely paikallisesti. − Poikkeusten heittäminen. Exception.
15. Ohjelmoinnin tekniikkaa
Osoittimen määrittely ja alustus tMyn1 Osoittimen määrittely ja alustus Osoitin (pointer) on muuttuja, joka voi sisältää keskusmuistiosoitteen. Osoitinmuuttujan.
For-toistolausetMyn1 for-toistolause for-lauseen rakenne on: for(aloituslauseke; lauseke; lopetuslauseke) lause; Puolipisteiden on oltava aina paikoillaan,
Ohjausrakenteet Määräävät ohjelmakoodin suoritusjärjestyksen Ehtolause if – else on muotoa if (lauseke) lause1 else lause2 Jos lauseke on tosi, niin suoritetaan.
Kuplalajittelu (bubble sort)
Hajakoodaus Talletetaan alkiot avain-indeksoituun taulukkoon Hajakoodausfunktio Menetelmä avain-indeksin laskemiseen avaimesta Törmäyksen selvitysstrategia.
Muuttujan osoite int a=1; 0xbfffea64 /* tulostetaan a:n osoite*/ printf(“%p\n”, &a); 0xbfffea68 /* tulostetaan a:n osoite + 1*/ printf(“%p\n”, &a+1); /*
Tiedosvirtat Puskuroiduissa virroissa lukeminen/kirjoittaminen tapahtuu lohko kerrallaan stdin – puskuroitu (näppäimistö) stdout – purkuroitu (näyttö)
Funktioesittelyt (declarations) Jos funktiota käytetään ennen sen määrittelyä (definition), se pitää esitellä (declare) - muuten sen tyypiksi oletetaan.
Merkit ja merkistöt C:n perusmerkistö (basic character set): a-z A-Z 0-9 ! " # % & ' ( ) * +, -. / : ; ? [ \ ] ^ _ { | } ~ sekä välilyönti, tabulaattori,
Tyyppiluokat II ­ konstruktoriluokat, funktionaaliset riippuvuudet ­
2. Taulukot.
Scala Collections.
3. Luokat, oliot ja metodit Java-kielessä (Lausekielinen ohjelmointi I ja II –kursseilla opitun kertausta.)
9. Aritmeettiset operaatiot
9. Aritmeettiset operaatiot
14. Hyvä ohjelmointitapa.
2. Taulukot.
4. Ohjelmointi konekielellä (TTK-91 ja Titokone)
4. Ohjelmointi konekielellä (TTK-91 ja Titokone)
3. TTK-91-käskykanta Symbolisen konekielen tavalliset käskyt
3. Attribuutit.
Esityksen transkriptio:

C-ohjelmointi, kevät 2006 Taulukot Binääritiedostot Luento 8 21.3.2006 Yksiulotteiset taulukot Moniulotteiset taulukot Dynaamiset taulukot Binääritiedostot Luento 8 21.3.2006 C-ohjelmointi Kevät 2006 Liisa Marttinen

Luennon sisältö Taulukoiden käsittelyä Binääritiedostot Yksiulotteiset taulukot Määrittely Vertailu Alustus Vakiotaulukko Taulukko parametrina Moniulotteiset taulukot Dynaamiset taulukot Binääritiedostot C-ohjelmointi Kevät 2006 Liisa Marttinen

Taulukot (arrays) (Müldnerin kirjan luku 10) Yksiulotteiset taulukot C:ssä taulukot ovat staattisia (koko tiedettävä ennen kääntämistä), mutta muuten samankaltaisia kuin Javassa. Alkaa aina nollasta määrittely: type arrayName[size]; int luvut[20]; char *nimet[5*10+1]; #define SIZE 10 int taulu1[SIZE]; const int koko =20; /* vain funktioissa */ /* int taulu2[koko]; tässä laiton */ int foo(){ int taulu2[koko]; Siirrettävyys: warning: ISO C90 forbids variable- size array 'taulu ‘ (ISO C99 sallii käytön, kuten myös gcc) C-ohjelmointi Kevät 2006 Liisa Marttinen

Mikä taulukko on? Taulukko on osoitin Vakioarvoinen osoitin muistilohko 0 1 2 3 4 5 ….. Taulukko on osoitin Vakioarvoinen eli osoittaa aina samaan paikkaan Osoittaa muistilohkoon, josta on varattu tilaa taulukon alkioille Muistilohkossa on tilaa taulukon koon ilmoittamalle määrälle taulukon tyypin kokoisia olioita Viittaukset eri alkioihin: luvut[0], luvut[1], luvut[2] …. luvut [19] char *nimet[5*10+1]; Tilaa 51 char-tyyppiselle osoittimelle nimet int luvut[20]; Tilaa 20 kokonaisluvulle luvut HUOM! Ajoaikana järjestelmä ei tarkista indeksien oikeellisuutta. Viittaus luvut[20] ei välttämättä aiheuta suoritusvirhettä, vaan ohjelma vain toimii, miten sattuu toimimaan! C-ohjelmointi Kevät 2006 Liisa Marttinen

Yleisiä virheitä määrittelyssä ja käytössä Taulukon koko ilmoitettava vakiona int lkm=5; int taulu[lkm]; /*virheellinen */ Taulukko on vakioarvoinen osoitin, jonka arvoa ei saa muuttaa int luvut[20]; char *p; ……… luvut = p; /*ei näin*/ p=luvut; /*ihan OK! Nyt p:kin osoittaa samaan */ Varo sivuvaikutuksia a[i] = i++; /* toiminta riippuu toteutuksesta! */ Kumpi tehdään ensin, kasvatus vai käyttö? ensin a[i] ja sitten vasta i++? vai ensin i++ ja sitten a[i]? luvut Luvut osoittaa aina tähän muistilohkoon! p 4 5 4 5 Kumpi?? C-ohjelmointi Kevät 2006 Liisa Marttinen

Taulukko-osoitin  tavallinen osoitin int luvut[20] Vakio Osoittaa aina samaan tietyn kokoiseen muistialueeseen sizeof(luvut) on 20 kokonaisluvun tarvitsema tavumäärä eli koko taulukon koko int *osoitin Muuttuja, joka voi osoittaa eri paikkoihin Mitään muistialuetta ei ole varattu sizeof(osoitin) on osoittimen tarvitsema tavumäärä C-ohjelmointi Kevät 2006 Liisa Marttinen

Kokojen tulostaminen #include <stdio.h> #include <stdlib.h> int main(int argc, char **argv) { int *taulu[20]; int *s; printf ("Taulukon 'taulu' koko: %d\n", sizeof(taulu) ); printf ("Osoittimen 's' koko: %d\n", sizeof(s)); printf ("Taulukon alkion koko: %d\n", sizeof(taulu[0])); printf ("Taulukon alkioiden lukumäärä: %d\n", sizeof(taulu)/sizeof(taulu[0])); return 0; } int *taulu[20]; int *s; printf ("Taulukon 'taulu' koko: %d\n", sizeof(taulu) ); /*=> 80 */ printf ("Osoittimen 's' koko: %d\n", sizeof(s)) /* => 4 */ printf ("Taulukon alkion koko: %d\n", sizeof(taulu[0])); /* => 4 */ printf ("Taulukon alkioiden lukumäärä: %d\n", sizeof(taulu)/sizeof(taulu[0]); /* =>20*/ C-ohjelmointi Kevät 2006 Liisa Marttinen

Taulukkojen vertailu: sama sisältö? x y #define SIZE 10 int x[SIZE]; int y[SIZE]; int *px,*py; for (px=x, py = y; px<x+SIZE; px++, py++) if (*px!=*py) …….. Toimii vain jos saman kokoisia! Entä jos eivät ole? for (px=x; px<x+SIZE; px++) if (*px!=*y[px-x]) …….. for (i=0; i<SIZE; i++ ) if(x[i] != y[i]) …. Entä vertailu X== Y?? Mitä tässä verrataan? C-ohjelmointi Kevät 2006 Liisa Marttinen

Taulukon alustaminen Taulukko alustetaan antamalla sen alkioiden arvot muodossa {a1, a2, …, an} Esim. int t[] = {1, 2, 3}; int t[3] = {1, 2, 3}; int t[3] = {1, 2}; int t[3] = {1, 2, 3, 4}; Taulukon nollaus: int taulu[10000]={0}; Alkioiden lukumäärä määrää taulukon koon! 1 2 3 1 2 3 1 2 Täytetään järjestyksessä. Loput nollia. Kolmen alkion taulukossa ei ole tilaa arvolle ’4’ => virhe!! 1 2 3 C-ohjelmointi Kevät 2006 Liisa Marttinen

Vakioksi määritelty taulukko const int days[] ={1, 2, 3, 4, 5, 6, 7} osoittimen days tyyppi: const int * const Merkkijonovakiot: char nimi[] = ”Pekka”; char *nimet[] = {”Maija”, ”Jussimatti”}; nimi Pekka\0 Maija\0 nimet Jussimatti\0 C-ohjelmointi Kevät 2006 Liisa Marttinen

Taulukon kopiointi for (i=0; i<SIZE; i++) x[i] = y[i]; Oltava saman kokoisia! Entä jos eivät ole? kokox=sizeof(x); kokoy = sizeof(y); if (kokox < kokoy) koko = kokox else koko = kokoy; for (i=0; i<koko; i++) x[i] = y[i]; koko = kokox < kokoy ? kokox: kokoy; C-ohjelmointi Kevät 2006 Liisa Marttinen

Taulukko parametrina funktion määrittelyssä voi käyttää: Funktion sisällä taulukkoparametreja käsitellään aina osoittimina => Taulukon kokoa ei voi kysyä näin! int miniT(double arr[], int size); int miniP(double *arr, int size); sizeof( arr) (= osoitinmuuttujan koko) C-ohjelmointi Kevät 2006 Liisa Marttinen

Esimerkki: maxmin palauttaa taulukon maksimi ja minimiarvon int maxmin (double arr[], int size, double *max, double*min) { double *p if (arr==NULL || size <= 0) return 0; for (*max=*min = arr[0], p = arr+1; p<arr + size; p++) { if(*max <*p) *max= *p; if (*min >*p) *min = *p; } return 1; Kutsu: maxmin(x, SIZE, &max, &min); Mitä tekee seuraava kutsu? maxmin(x+3, 5, &max, &min); C-ohjelmointi Kevät 2006 Liisa Marttinen

Paikalliset static-taulukot static char* opnimi(int n) { static char* operaattori [] = {”lvalue”, ”rvalue”, ”push”, ”+”, ”-”}; return operaattori[n]; } static => funktion yksityinen ja pysyvä taulukko char *setName (int i){ char name1[] = ”Maija”; char name2[] = ”Jussi”; if (i=0) return name1; return name2; } Paikalliselle muuttujalle varataan tilaa pinosta joka kutsukerralla erikseen. char *p = setName(1); Osoitin p jää osoittamaan siihen kohtaan pinoa, josta tällä kertaa varattiin tilat, mutta joka funktion suorituksen jälkeen vapautettiin. Varo roikkumaan jääviä osoittimia! C-ohjelmointi Kevät 2006 Liisa Marttinen

Mielivaltaisen pitkän rivin lukeminen Varataan tarpeeksi suuri muistilohko ja toivotaan sen riittävän. Varataan esim. 80 merkin muistilohko ja aina tarvittaessa kasvatetaan riville varatun muistilohkon pituutta (dynaaminen taulukko) Käytetään rekursiivista funktiota: aina kun varattu (esim. 80 merkin) muistialue on täynnä ja rivi yhä jatkuu, niin funktio kutsuu itse itseään. Edellisen kutsun muistialue jää talteen pinoon ja uusi suorituskerta varaa uuden muistialueen pinosta. C-ohjelmointi Kevät 2006 Liisa Marttinen

Esimerkki: mielivaltaisen pituisen rivin lukeminen rekursiivisesti #define KOKO 80 int luerivi(File *in, char **tulos){ char puskuri[KOKO]; int c, i, base; /*luettu merkki, indeksimuuttuja, apumuuttuja */ static int luettu = 0; /* tämän rivipätkän koko */ for (i=0; i< KOKO; i++) { c = fgetc(in); if (c==EOF) { … } /*virhetilanne */ if (c== ’\n’) break; /*rivi loppui*/ puskuri[i] = c; luettu += i; if (c!=’EOF’ && c!=’\n’){ /*vielä luettavaa */ if (luerivi(in, tulos) == 0) { luettu=0; return 0} } else { /* kaikki luettu */ if ((*tulos = malloc((luettu+1) *sizeof(char))) == NULL) { luettu= 0; return 0;} (*tulos)[koko]=’\0’; /* NULL-merkki viimeiseksi */ } base = luettu -i; memcpy(*tulos +base, puskuri, i) luettu -=i; return 1; Luetaan korkeintaan 80 merkkiä puskuriin. Joka kutsukerralla eri puskuri, joka jää talteen pinoon. Rekursiivinen kutsu Kukin kutsukerta kopioi lukemansa puskurin oikeaan paikkaan yhteistä muistitilaa. Tämä suoritetaan vain kerran: kun viimeinen pätkä riviä on luettu! Vertaa rekursiivinen kertoman laskeminen tito-kurssilla!

Esimerkki jatkuu: - pinon käyttö - muistilohkon täyttö pino puskuri 1. Kutsu 2. kutsu 3. Kutsu 4.Kutsu (tässä rivi loppui) Esimerkki jatkuu: - pinon käyttö - muistilohkon täyttö luettu=80 puskuri i =80 luettu=160 puskuri i =80 luettu=240 puskuri i =60 luettu=300 *tulos Kun rivin pituus on 300 merkkiä Kaikilla kutsukerroilla: base = luettu -i; memcpy(*tulos +base, puskuri, i)

Moniulotteinen taulukko C:n moniulotteiset taulukot ovat yksiulotteisia taulukoita, joiden alkiot ovat taulukoita int t[3][2] = { {1,2},{11,12}, {21,22}}; 0 1 for (i=0; i<3; i++) { for (j = 0; j<2; j++) printf (”t[%d][%d] = %d\”,i,j t[i][j]); putchar(’\n’); } 1 2 2 12 21 22 t[0][0] = 1 t[0][1] = 2 t[1][0] = 11 t[1][1] = 12 t[2][0] = 21 t[2][1] = 22 C-ohjelmointi Kevät 2006 Liisa Marttinen

static char paivat [2][13] ={ {0, 31, 28, 31, 30, 31,30,31, 30, 31,30, 31}, {0, 31, 29, 31, 30, 31,30,31, 30, 31,30, 31} }; lkm = paivat[karkaus][2]; Kun karkaus ==0, niin lkm = 28, kun karkaus ==1, niin lkm = 29 C-ohjelmointi Kevät 2006 Liisa Marttinen

Dynaaminen taulukko void* malloc (size_t koko); void* calloc (size_t koko); void free( void* pt); void* realloc(void* pt, size_t koko); void on geneerinen osoitintyyppi ”a pointer to something, but we don’t know yet to what kind of thing” Käytetään dynaamista muistin varaamista (malloc, calloc) Kun taulukolle varattu muistilohko on täynnä eikä siihen enää mahdu alkioita, Yritetään kasvattaa jo varattua muistilohkoa varaamalla lisää muistia heti sen sen perästä. Jos tämä ei onnistu, niin varataan jostain muualta muistista suurempi muistilohko, jonne kopioidaan pieneksi käyneen muistilohkon tiedot, ja vapautetaan tämän varaama muistitila. Voidaan käyttää funktiota realloc tai laatia itse funktio, joka varaa tarvittaessa muistia (malloc, calloc), suorittaa kopioinnin ja vapauttaa (free) turhaksi käyneen muistilohkon. Kopioidut arvot C-ohjelmointi Kevät 2006 Liisa Marttinen

malloc-funktio (void. malloc (size_t sz);) calloc-funktio (void malloc-funktio (void* malloc (size_t sz);) calloc-funktio (void* calloc(size_t n, size_t sz);) (char*) malloc(4*sizeof(char)); calloc(4, sizeof(char)); char* if((p = malloc(4* sizeof(char))) == NULL) .. Muistia ei ole alustettu, se sisältää mitä, siihen on sattunut jäämään. char* 0 0 0 0 if((p = calloc(4, sizeof(char))) == NULL) .. Muisti on nollattu. C-ohjelmointi Kevät 2006 Liisa Marttinen

Muistin vapauttaminen: free (void free( void* pt); ) Vapauttaa osoittimen osoittaman muistilohkon Mistä se tietää lohkon koon? Lohkoa varattaessa (malloc, calloc) sen koko on talletettu muistiin juuri ennen lohkon alkua Vain calloc:lla ja malloc:lla varattujen alueiden vapauttamisen Vapauta kukin alue vain yhden kerran! ’dangling pointer’: Jää osoittamaan poistettuun muistialueeseen. pt Lohkon koko C-ohjelmointi Kevät 2006 Liisa Marttinen

Taulukon koon muuttaminen: realloc (void. realloc(void Taulukon koon muuttaminen: realloc (void* realloc(void* pt, size_t sz);) malloc- tai calloc-funktiolla varatun muistilohkon, esim. taulukon, kokoa voidaan sekä suurentaa että pienentää. 32 15 27 36 49 65 89 108 Lohkon koko lptr Pienentäminen: lptr = realloc(lptr, 3*sizeof(long)); 16 15 27 36 Lohkon koko lptr vapaa muistialue 16 65 89 108 sen koko C-ohjelmointi Kevät 2006 Liisa Marttinen

Varatun muistilohkon koon kasvattaminen realloc-funktiolla (1) Käyttöjärjestelmä pitää kirjaa malloc:lla ja calloc:lla varattujen alueiden koosta ja tietää myös, mitkä alueet ovat vapaana 16 15 27 36 Lohkon koko lptr vapaa muistialue 16 65 89 108 sen koko lptr=realloc(lptr, 2*sizeof(long)); vapaa muistialue Lohkon koko lptr 24 15 27 36 16 65 8 108 sen koko C-ohjelmointi Kevät 2006 Liisa Marttinen

Varatun muistilohkon koon kasvattaminen realloc-funktiolla (1) realloc onnistuu aina, kun vain jossain on vapaata muistia tarvittava määrä! Jos kasvatettavan lohkon perässä ei ole riittävästi vapaata tilaa, niin varataan muistista riittävän suuri vapaa tila, kopioidaan sinne taulukon alkiot ja vapautetaan taulukolle alun perin varattu tila. Lohkon koko lptr vapaa muistialue 16 15 27 36 16 65 89 108 sen koko kopioidaan 15 27 36 ????????? ??????? ??????? ????????? ???? 44 lptr=realloc(lptr, 10*sizeof(long)); Kopiointi on ’kallis’ operaatio ja sitä tulisi välttää! Ongelmana vielä muut osoittimet: nehän osoittavat vanhaan lohkoon! Varataan uusi lohko ja vapautetaan vanha lohko: 32 15 27 36 16 65 89 108 C-ohjelmointi Kevät 2006 Liisa Marttinen

Dynaamisen taulukon käyttö Lajittelussa Eri pituisten merkkijonojen (sanojen tai nimien) tallettaminen taulukkoon printf(” Montako alkiota lajitellaan?\n”); scanf(”%i”, &n); if ((alkiot = malloc(n * sizeof(float))) == NULL) mallocerror(); read_file(alkiot, n); /*luetaan alkiot*/ sort_data(alkiot, n); scanf(”%20”, buf); /*sanan lukeminen*/ len = strlen(buf); /*sanan pituus */ if ((sanat[i] =malloc((len+1) * sizeof(char))) == NULL) mallocerror();; strcpy (sanat[i], buf); alkiot sanat C\0 Java\0 Pascal\0 Ada\0 C-ohjelmointi Kevät 2006 Liisa Marttinen

Monimutkaisia määritelmiä? [] –merkeillä korkeampi presedenssi kuin *-merkillä double *f[2]; double (*f2[2])() double (*f3())[] double *(f4[])() VIRHE! Ei voi olla funktiotaulukkoa! Vain osoitteita funktioihin. f double-muuttujia Funktioita, jotka palauttavat double-arvon f2 f3 on funktio, joka palauttaa osoittimen double-taulukkoon. C-ohjelmointi Kevät 2006 Liisa Marttinen

Binääritiedostot Tiedon tiiviiseen tallettamiseen Ei rivirakennetta => ei voida käsitellä standardeilla välineillä Eivät suoraan ihmisen luettavissa Usein eivät ole siirrettäviä koneesta toiseen fopen(”tied1”, ”wb”); fopen(”tied2”, ”rb”); C-ohjelmointi Kevät 2006 Liisa Marttinen

Operaatioita binääritiedostoille #include <stdio.h> hajasaantitiedostoja (random access) Kun tiedosto on avattu, kahva osoittaa sen hetkiseen käsittelykohtaan Operaatioita long ftell(FILE *f) palauttaa käsittelykohdan int fseek(FILE *f, long offset, int mode) siirtää käsittelykohtaa siirtymän (offset) verran mode kertoo mistä kohtaa siirto alkaa: SEEK_SET tiedoston alusta SEEK_CUR nykykohdasta SEEK_END lopusta rewind(FILE *f) kelaa tiedoston alkuun C-ohjelmointi Kevät 2006 Liisa Marttinen

Esimerkki: Annetun tiedoston koon selvittäminen long fileSize (const char *filename) { FILE *f; long size; if ((f = fopen(filename, ”rb”))== NULL) return -1L; if (fseek(f, 0L, SEEK_END) == 0) { /* OK!*/ size = ftell(f); if (flose(f)==EOF) return -1L; return size; } flose(f); return -1L; C-ohjelmointi Kevät 2006 Liisa Marttinen

Binäärinen lukeminen ja kirjoittaminen = oliolohkojen kirjoittaminen ja lukeminen #include <stdio.h> size_t fread (void *buf, size-t elsize, size_t count, FILE *in); lukee tiedostosta in count:n ilmoittaman määrän oliolohkoja muistilohkoon, johon buf osoittaa. Oliolohkon koon ilmoittaa elsize. Palauttaa luettujen objektien määrän. Virhetilanteessa palauttaa nollan. size_t fwrite (void *buf, size-t elsize, size_t count, FILE *out); Kirjoittaa tiedostoon out count:n ilmoittaman määrän oliolohkoja buf:n osoittamasta muistilohkosta. Oliolohkon koon ilmoittaa elsize. Olettavat, että tiedosto on jo avattu oikeaa toimintaa (lukemista tai kirjoittamista) varten. C-ohjelmointi Kevät 2006 Liisa Marttinen

Tekstitiedostosta binääritiedostoon ja binääritiedostosta tekstitiedostoon Teksti => binääri while (fscanf(in, ”%lf”, &d) ==1) if (fwrite (&d, sizeof(double), 1, out) !=1) Binääri => teksti while(fread(&d, sizeof(double), 1, in) ==1) { i++; if (i== Max) { putchar(’\n’); i = 0; } fprintf(out, ”%f\t”, d); ……….. C-ohjelmointi Kevät 2006 Liisa Marttinen

Ensi kerralla Modulaarinen ohjelmointi Kirjastofunktioiden käyttö Kertausta Mitä asioita tarpeen kerrata? osoittimia C-ohjelmointi Kevät 2006 Liisa Marttinen