Moduli 2: Osoittimet ja taulukot. Joel Huttunen

Samankaltaiset tiedostot
Osoittimet ja taulukot

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

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

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

Rakenteiset tietotyypit Moniulotteiset taulukot

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

Tietueet. Tietueiden määrittely

tietueet eri tyyppisiä tietoja saman muuttujan arvoiksi

Osoittimet ja taulukot

Loppukurssin järjestelyt C:n edistyneet piirteet

Loppukurssin järjestelyt

Osoitin ja viittaus C++:ssa

Perusteet. Pasi Sarolahti Aalto University School of Electrical Engineering. C-ohjelmointi Kevät Pasi Sarolahti

Moduli 4: Moniulotteiset taulukot & Bittioperaatiot

Perusteet. Pasi Sarolahti Aalto University School of Electrical Engineering. C-ohjelmointi Kevät Pasi Sarolahti

Tietorakenteet ja algoritmit

C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. Operaatioiden suoritusjärjestys

815338A Ohjelmointikielten periaatteet Harjoitus 5 Vastaukset

Tietorakenteet ja algoritmit

Java-kielen perusteet

Lyhyt kertaus osoittimista

AS C-ohjelmoinnin peruskurssi 2013: C-kieli käytännössä ja erot Pythoniin

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

Operaattoreiden ylikuormitus. Operaattoreiden kuormitus. Operaattoreiden kuormitus. Operaattoreista. Kuormituksesta

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

Taulukot. Jukka Harju, Jukka Juslin

1. Mitä seuraava ohjelma tulostaa? Vastaukseksi riittää yksi rivi joka esittää tulosteen. (6 p)

815338A Ohjelmointikielten periaatteet Harjoitus 3 vastaukset

Java-kielen perusteet

7. Oliot ja viitteet 7.1

Moduli 5: Kehittyneitä piirteitä

Sisältö. 2. Taulukot. Yleistä. Yleistä

Tietorakenteet ja algoritmit

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

Tietotyypit ja operaattorit

TIETORAKENTEET JA ALGORITMIT

ITKP102 Ohjelmointi 1 (6 op)

Yleistä. Nyt käsitellään vain taulukko (array), joka on saman tyyppisten muuttujien eli alkioiden (element) kokoelma.

Ohjelmointiharjoituksia Arduino-ympäristössä

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

Ohjelmointi 1 Taulukot ja merkkijonot

Sisältö. 22. Taulukot. Yleistä. Yleistä

Binäärioperaatiot Tiedostot ja I/O

5.6. C-kielen perusteet, osa 6/8, Taulukko , pva, kuvat jma

1.3Lohkorakenne muodostetaan käyttämällä a) puolipistettä b) aaltosulkeita c) BEGIN ja END lausekkeita d) sisennystä

C++11 lambdat: [](){} Matti Rintala

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

C-ohjelmointi, syksy 2006

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

C-kieli mahdollistaa hyvin tiiviin ja samalla sekavan tavan esittää asioita, kuitenkin hyvän ohjelman tulisi olla mahdollisimman helppolukuinen ja

Java-kielen perusteet

Harjoitustyö: virtuaalikone

Harjoitus 4 (viikko 47)

Tietorakenteet ja algoritmit

Johdatus ohjelmointiin / Lausekielinen ohjelmointi 1 & 2

if-lauseen yksinkertaisin muoto on sellainen, missä tietyt lauseet joko suoritetaan tai jätetään suorittamatta.

C-ohjelmointi: Osoittimet

Ohjeet. AS C-ohjelmoinnin peruskurssi Aalto-yliopiston sahkotekniikan korkeakoulu Tentti , Raimo Nikkila

Perusteet. Pasi Sarolahti Aalto University School of Electrical Engineering. C-ohjelmointi Kevät Pasi Sarolahti

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

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

Tietorakenteet ja algoritmit

815338A Ohjelmointikielten periaatteet Harjoitus 4 vastaukset

ITKP102 Ohjelmointi 1 (6 op)

Binäärioperaatiot Tiedostot ja I/O

13 Operaattoreiden ylimäärittelyjä

Luento 4 Aliohjelmien toteutus

ITKP102 Ohjelmointi 1 (6 op), arvosteluraportti

Tiedostot. Tiedostot. Tiedostot. Tiedostot. Tiedostot. Tiedostot

Dynaaminen muisti Rakenteiset tietotyypit

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

ITKP102 Ohjelmointi 1 (6 op)

Olio-ohjelmointi Javalla

Koottu lause; { ja } -merkkien väliin kirjoitetut lauseet muodostavat lohkon, jonka sisällä lauseet suoritetaan peräkkäin.

Jakso 4 Aliohjelmien toteutus

Aliohjelmatyypit (2) Jakso 4 Aliohjelmien toteutus

IDL - proseduurit. ATK tähtitieteessä. IDL - proseduurit

ATK tähtitieteessä. Osa 3 - IDL proseduurit ja rakenteet. 18. syyskuuta 2014

Olio-ohjelmointi Syntaksikokoelma

Ohjelmoinnin peruskurssien laaja oppimäärä

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

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

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

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

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

812347A Olio-ohjelmointi, 2015 syksy 2. vsk. X Poikkeusten käsittelystä

Tietorakenteet ja algoritmit

Ohjelmointikieli TIE Principles of Programming Languages Syksy 2017 Ryhmä 19

1. Esittelyt ja vakiot 1.1 Esittelyt (declarations) Ennen nimen, tunnuksen (identifier) käyttöä se on

1.3 Lohkorakenne muodostetaan käyttämällä a) puolipistettä b) aaltosulkeita c) BEGIN ja END lausekkeita d) sisennystä

Osoittimet. Mikä on osoitin?

List-luokan soveltamista. Listaan lisääminen Listan läpikäynti Listasta etsiminen Listan sisällön muuttaminen Listasta poistaminen Listan kopioiminen

Modulaarisessa ohjelmoinnissa jaetaan ohjelma osiin (moduuleihin), jotka ovat yksinkertaisia ja lyhyitä.

Jakso 4 Aliohjelmien toteutus

815338A Ohjelmointikielten periaatteet Harjoitus 2 vastaukset

Muuttujat ja kontrolli. Ville Sundberg

Metodien tekeminen Javalla

Listarakenne (ArrayList-luokka)

Metodit. Metodien määrittely. Metodin parametrit ja paluuarvo. Metodien suorittaminen eli kutsuminen. Metodien kuormittaminen

Transkriptio:

: Osoittimet ja taulukot 26.1.2016

Moduli 1 yhteenvetoa laskuharjoituksista (PS: palautteen saa jättää myös suomeksi jos haluaa) Ongelmia ympäristön asennuksessa Hoitakaa kuntoon ajoissa, niin loppukurssilla on mukavampaa Oikean tulostusformaatin arvaaminen hankalaa Floatin ja Doublen formaatissa on eroa %f vai %lf Puolipisteen unohtaminen Ohjelmatiedoston löytäminen oli haastavaa Koko ohjelma ei ole yhdessä tiedostossa. Tehtävä osuus löytyy usein source.c tiedostosta 2

Tiedotteita Ensimmäisen kierroksen sulkeutuu perjantaina! Pistetilanne löytyy verkosta Myrkystä tietoa pisteistä ja arvostelusta Kakkoskierros on auennut (deadline 12.2.) Laskareihin voi tulla kysymään jo kakkoskierroksen tehtävistä, mutta ykköskierros on etusijalla 3

Osoittimet Osoitin (pointteri): viittaus muistiosoitteeseen Osoitinmuuttujan arvo on muistiosoite C-kielen voi ymmärtää erivärisinä numeroina Erittäin alhaisen abstraktiotason ominaisuus Keskeinen osa a Käsitteenä usein hankala 4

Osoittimien käyttötarkoitukset Laiteläheinen ohjelmointi Mahdollistaa tiedon tehokkaan käsittelyn Taulukot Dynaamisen muistin käsittely Monimutkaiset tietorakenteet Referenssitietotyypin toiminnallisuus Simuloitu pass-by-reference (Ohjelman rikkominen lähes äärettömän monella eri tavalla) 5

Osoittimen määrittely char a = 10; char *d = &a; Syntaksi: tietotyyppi *muuttuja Ylläolevat määritelmät kaksi eri tietotyyppiä Osoitinmuuttujan arvot ovat muistiosoitteita Osoittimen viitetietotyyppi oltava oikein, jotta tiedon käsittely toimii oikealla tavalla char *d voisi olla myös char* d & - operaattorilla saadaan annetun objektin osoite &a: palauta muuttujan a osoite &:n unohtaminen edellä tuottaisi kääntäjän varoituksen 6

Yksinkertainen esimerkki int main(void) { char a = 10; char b = 12; int c = 123456; char *d = &a; char *e; } Osoittimeen e viittaaminen johtaisi virheeseen (ja tod. näk. ohjelman kaatumiseen) 7

Yksinkertainen esimerkki int main(void) { char a = 10; char b = 12; int c = 123456; char *d = &a; char *e; e = d; } Annetaan e:lle arvo 8

Yksinkertainen esimerkki int main(void) { char a = 10; char b = 12; int c = 123456; char *d = &a; char *e; e = d; printf("*e: %d e: %p\n", *e, e); } *d = 13; printf("*d: %d d: %p *e: %d a: %d\n", *d, d, *e, a); *e: 10 e: 0x1000 *d: 13 d: 0x1000 *e: 13 a: 13 9

Viittausoperaattori *muuttuja: viite osoittamaan osoittamaan muistipaikkaan Voi käyttää lausekkeissa kuten muitakin muuttujia Sijoitus aiheuttaa kohteen arvon muuttumisen Eräänlainen vastakohta & - osoiteoperaattorille muuttuja voi olla myös lauseke: *(a + 2) on ok Eri operaatio kuin osoitinmuuttujan määrittäminen Jos osoitin viittaa virheelliseen osoitteeseen, ja sitä yritetään käyttää, ohjelma todennäköisesti kaatuu Useimmiten Segmentation fault Joskus vain outo toiminta 10

Yksinkertainen esimerkki void main() { char a = 10; char b = 12; int c = 123456; char *d = &a; char *e; e = d; *d = 13; d = 14; } Osoitin d viittaa virheelliseen muistiosoitteeseen d:hen viittaus todennäköisesti kaataa ohjelman 11

Binky pointer fun 12

NULL NULL on osoitinmuuttujan nolla-arvo Käytännössä määritelty: #define NULL ((void*)0) NULL ei osoita mihinkään kelvolliseen muistipaikkaan Käytetään virhearvona tai erikoisarvona Esimerkiksi listan loppu voidaan määritellä käyttämällä NULLia 13

Korkeamman asteen osoitinmuuttujat Osoitinmuuttujia voidaan myös ketjuttaa Esimerkiksi int **p; Tällöin p osoittaa int* -tyyppiseen muuttujaan Tarvitaan moniulotteisissa taulukoissa ja monimutkaisemmissa tietotyypeissä Lisää aiheesta 3. kierroksella! 14

Constin käyttö const TYPE *ptr tai TYPE const *ptr Osoitinmuuttujan kohde, eli *ptr on const Osoittinmuuttujan arvo, eli ptr ei ole const Yleisin constin käyttö TYPE * const ptr Osoitinmuuttujan arvo, eli ptr on const Osoittinmuuttujan kohde, eli *ptr ei ole const TYPE voisi esimerkiksi olla: int, char, char*, jne. Constin käyttö on tärkeää, koska on muistialueita joihin kirjoittaminen on virhe! 15

Osoittimien arvojen muuttaminen Osoittimia voidaan liikuttaa eteen ja taaksepäin: Myös --, ++ ja muut operaatiot toimivat! Laskujärjestys on tärkeä! *p++; on eri asia kuin (*p)++; Osoittimien välistä etäisyyttä voidaan laskea Kohteen tyyppiä ei tarvitse huomioida etäisyydessä Osoittimia voidaan verrata keskenään Verrataan ainoastaan muistiosoitteita Tämä on yleinen virhe merkkijonojen tarkastelussa! 16

Välitehtävä Mitä tämä tulostaa? #include <stdio.h> int main(void) { int a = 5, d = 0; int *b = &a; int *c = &d; *c = *b; *b = 1; } printf(" a: %d\t b: %d\t c: %d\t d: %d\n", a, *b, *c, d); 17

Osoitinmuuttujat funktiossa void count(int *nro) { // nro on pointterin arvo // *nro on pointterin osoittaman paikan arvo if (nro!= NULL) { printf("%d\n", *nro); *nro += 1; } } int main(void) { int a = 1; count(&a); count(&a); } 18

Taulukko Taulukko on saman tyylisiä muuttujia peräkkäisissä muistipaikoissa C-kielessä ei mekanismia taulukon koon selvittämiseen Tiedettävä/sovittava muilla tavoin Mikään ei estä taulukon käyttöä yli kokorajojen Aiheuttaa virheen joka voi olla vaikea havaita Taulukolla läheinen suhde osoitinmuuttujaan Taulukkoon voidaan viitata osoitinmuuttujalla sen ensimmäiseen alkioon 19

Osoitinaritmetiikka esimerkki short arr[4]; short *ref = arr; arr 0x1000 0x1002 0x1004 0x1006 0x1000 ref 20

Osoitinaritmetiikka esimerkki *ref = 1; ref++; (samalla johdatusta taulukoihin) arr 1 0x1000 0x1002 0x1004 0x1006 0x1002 ref 21

Osoitinaritmetiikka esimerkki *ref = 10; ref = ref + 2; (samalla johdatusta taulukoihin) arr 1 10 0x1000 0x1002 0x1004 0x1006 0x1006 ref -- Tämän jälkeen ref++ viittaisi taulukon yli (paikkaan 0x1008) -- Kääntäjä ei huomaa virhettä -- Ohjelma ei välttämättä kaadu -- Viittaus silti väärään muistipaikkaan -- Joskus vaikea havaita, monet tietoturva-aukot perustuvat tämäntyyppisiin virheisiin 22

Taulukkoesimerkki short apples = 10; short slots[4]; short oranges = 20; int i; for (i = 0; i < 4; i++) { /* Here we initialize the array */ slots[i] = i + 1; } for (i = 0; i < 4; i++) { /* Output the values in array */ printf("array element %d is %d\n", i, *(slots + i)); } 23

Taulukon käyttäminen [ ] operaattori Muoto: muuttuja[indeksi] Toimii kuten yksittäinen muuttuja Indeksi voi olla vakioarvo tai toinen muuttuja tai lauseke Indeksointi alkaa 0:sta Mikään ei estä viittaamasta taulukon yli tai alle (taulu[-1]) Vaihtoehtoisesti myös *(muttuja + indeksi) toimii Indeksioperaattoria voi käyttää myös kun taulukkoon viitataan osoittimella 24

Taulukon käyttö funktiossa Taulukko voidaan välittää osoittimena sen ensimmäiseen arvoon Taulukon pituutta ei voi nähdä osoittimen perusteella Mutta voidaan esim. kertoa funktion parametrina Staattisen taulun koon voi määrittää, mutta se ei ole täysin virhevarmaa Taulukko ei voi olla funktion paluuarvona Mutta funktio voi muokata annettua taulukkoa osoittimen kautta 25

Taulukko ja funktio -- esimerkki void show_table(short *a, size_t n) { int i; for (i = 0; i < n; i++) { printf("%d ", a[i]); } printf("\n"); } int main(void) { short table[] = { 1, 4, 6, 8}; printf("size: %lu\n", sizeof(table)); /* print array size for fun */ } /* below is one way to get the number of elements */ show_table(table, sizeof(table)/sizeof(short)); // in this case the above would be equivalent to: show_table(table, 4); 26

Taulukon pituuden välittäminen Taulukon pituutta ei voi nähdä pelkästä osoittimesta Vaihtoehtoja Pituus tunnettu / sovittu (sovelluksesta riippuen) Pituus kerrotaan muuttujalla tai funktion parametrissa Ed. esimerkki Tietty arvo lopettaa taulukon Kuten merkkijonoissa Annetaan osoitin taulukon loppuun Pituus kerrotaan ensimmäisessä alkiossa Em. Vaihtoehtojen soveltuvuus riippuu käyttötarpeesta

Muuta huomioitavaa taulukoista Taulukkoa ei voi kopioida suoralla sijoitusoperaatiolla Kopioitava alkio kerrallaan Taulukkoja ei voi vertailla suoraan Vaan esim. alkio kerrallaan 28

Taulukko esimerkki double avg(int *arr, size_t size) { if (arr == NULL) return 0; int sum = 0; for (int i=0; i < size; i++) sum += arr[i]; } return sum / (double)size; int main(void) { int array1[10] = {0}; int array2[] = {1, 1, 1, 1, 2, 2, 2, 2}; int array3 = 13; } double result1 = avg(array1, 10); double result2 = avg(array2 + 4, 4); double result3 = avg(&array2[2], 4); double result4 = avg(&array3, 1); Result1: 0 Result2: 2 Result3: 1,5 Result4: 13 29

Taulukko tehtävä Mitä eri tapoja on selvittää taulukon pituus? 30

Merkkijonot 31

Merkkijono Merkkijono C-kielessä on char tyyppinen taulukko Merkkijonon loppu merkitään arvolla \0 Nolla-arvolle varattava tila taulukossa C:ssä merkkijono-taulukoilla on erityisasema Merkkijono voidaan määrittellä lainausmerkeissä normaalin taulukkosyntaksin ohella Useita kirjastofunktioita merkkijonojen käsittelyyn printf ja scanf - formatointi käyttäen %s muotoilumäärettä Merkkijono toimii kuten mikä tahansa taulukko Indeksointi, osoitinaritmetiikka, jne 32

Merkkijonon määrittely Merkkijono voidaan määritellä kuten mikä tahansa taulukko, tai käyttäen merkkijono notaatiota Jälkimmäisessa \0 on näkymätön ja lisätään automaattisesti char *string_a = "This is first string"; char string_b[] = "Another string"; char string_c[] = { 'O','n','e',' ','m','o','r','e','\0' }; string_a on vakiomuotoinen merkkijono Ei voi muuttaa Kuten kaikissa taulukoissa, alustava merkkijono määrää taulukon pituuden kun sitä ei ole erikseen annettu \0 merkki annettava jos käytetään taulukko-notaatiota 33

Merkkijonon määrittely char *string_a = "This is first string"; char string_b[] = "Another string"; char string_c[] = { 'O','n','e',' ','m','o','r','e','\0' }; 34

Yleisiä virheitä sizeof ja strlen sekoittaminen strlen: merkkijonon pituus merkkeinä olettaa char-taulukon joka päättyy nollamerkkiin (ajonaikainen) sizeof: muuttujan tarvitsema tila, osoittimille aina samaa kohdetyypistä riippumatta (käännösaikainen) 0-merkin unohtaminen merkkijonon lopusta Merkkijonon (tai muun taulukon) sijoittaminen = - operaattorilla Tarvitaan esim. strcpy() - funktio Merkkijonon vertailu loogisilla operaattoreilla Tarvitaan esim. strcmp() - funktio 35

Yleisiä virheitä Lainausmerkkien sekoittaminen: x on merkki (char) x, jonka arvo on 120 (ASCII) x on merkkijono, joka on tyyppiä (char *) Muistin varaaminen Merkkijono tarvitsee myös lopetusmerkille tilaa Esim. strlen(string) + 1 Harhaanjohtava väritys aiheuttanut kysymyksiä C++:n keywordit värjäytyvät editorissa (string, new, jne.) 36

Merkkijonojen käsittelyyn funktioita Funktio strcpy(s1, s2) strcat(s1, s2) strlen(s1) Toiminnallisuus Kopioi merkkijonon s2 paikkaan s1 Lisää merkkijonon s2 merkkijonon s1 perään Palauttaa merkkijonon pituuden strcmp(s1, s2) Palauttaa 0, jos s1 on sama kuin s2. strchr(s1, ch) Palauttaa pointterin ensimmäisen merkin ch esiintymiseen strstr(s1, s2) Palauttaa pointterin ensimmäiseen s2- merkkijonon esiintymiseen merkkijonossa s1 37

Esimerkki merkkijonoista int countslash(const char *str) { int count = 0; while ((str = strchr(str, '/'))!= NULL) { count++; str++; } return count; } int countslash(const char *str) { int count = 0; for (; *str!= 0; ++str) { if (*str == '/') count++; } return count; } 38

Ensi viikolla Debuggerin käyttö Auttaa virheiden etsinnässä! Jatkoa osoittimista Moniulotteiset taulukot 39