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

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

Osoitin ja viittaus C++:ssa

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

Tietueet. Tietueiden määrittely

Java-kielen perusteet

Java-kielen perusteet

815338A Ohjelmointikielten periaatteet Harjoitus 3 vastaukset

Osoittimet. Mikä on osoitin?

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

Osoittimet ja taulukot

815338A Ohjelmointikielten periaatteet Harjoitus 4 vastaukset

C-ohjelmointi, syksy 2006

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

Rakenteiset tietotyypit Moniulotteiset taulukot

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

815338A Ohjelmointikielten periaatteet Harjoitus 5 Vastaukset

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

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

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

Taulukot. Taulukon määrittely ja käyttö. Taulukko metodin parametrina. Taulukon sisällön kopiointi toiseen taulukkoon. Taulukon lajittelu

Moduli 2: Osoittimet ja taulukot. Joel Huttunen

Moduli 4: Moniulotteiset taulukot & Bittioperaatiot

Ohjelmointitaito (ict1td002, 12 op) Kevät Java-ohjelmoinnin alkeita. Tietokoneohjelma. Raine Kauppinen

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

Ohjausrakenteet. Valinta:

Tietotyypit ja operaattorit

tietueet eri tyyppisiä tietoja saman muuttujan arvoiksi

Lyhyt kertaus osoittimista

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

Ohjelmoinnin perusteet Y Python

// // whiledemov1.c // #include <stdio.h> int main(void){ int luku1 = -1; int luku2 = -1;

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

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

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

Ohjelmointiharjoituksia Arduino-ympäristössä

Tiedosto on yhteenkuuluvien tietojen joukko, joka tavallisimmin sijaitsee kiintolevyllä, muistitikulla tai jollakin muulla fyysisellä tietovälineellä.

Dynaaminen muisti Rakenteiset tietotyypit

Sisällys. 6. Muuttujat ja Java. Muuttujien nimeäminen. Muuttujien nimeäminen. salinovi tai syntymapaiva

6. Muuttujat ja Java 6.1

Sisällys. 6. Muuttujat ja Java. Muuttujien nimeäminen. Muuttujien nimeäminen. Muuttujien nimeäminen. Muuttujan tyypin määritys. Javan tietotyypit:

Ohjelmointi 1 Taulukot ja merkkijonot

Luennon sisältö Tyypit int, char, float, double signed, unsigned short, long Vakiot const Rakenteet if, for, while, switch, do-while Syöttö ja tulostu

Harjoitustyö: virtuaalikone

Ohjelmointitaito (ict1td002, 12 op) Kevät Java-ohjelmoinnin alkeita. Tietokoneohjelma. Raine Kauppinen

Taulukot. Jukka Harju, Jukka Juslin

Algoritmit 1. Demot Timo Männikkö

Sisällys. 6. Muuttujat ja Java. Muuttujien nimeäminen. Muuttujien nimeäminen. salinovi tai syntymapaiva

6. Muuttujat ja Java 6.1

Tiedostot. Tiedostot. Tiedostot. Tiedostot. Tiedostot. Tiedostot

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

2. Lisää Java-ohjelmoinnin alkeita. Muuttuja ja viittausmuuttuja (1/4) Muuttuja ja viittausmuuttuja (2/4)

Loppukurssin järjestelyt

Loppukurssin järjestelyt C:n edistyneet piirteet

7. Näytölle tulostaminen 7.1

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

C-ohjelmointi: Osoittimet

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

815338A Ohjelmointikielten periaatteet Harjoitus 2 vastaukset

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

Ohjelmoinnin peruskurssi Y1

Osoittimet ja taulukot

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

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

Ohjelmassa henkilön etunimi ja sukunimi luetaan kahteen muuttujaan seuraavasti:

Luennon sisältö. C-kurssi kevät Tasokokeen kohta 1: Taulukon järjestäminen. Tasokokeen kohta 2. Tasokokeen kohta 2. Tasokokeen kohta 3

C-kurssi kevät Luennon sisältö

811120P Diskreetit rakenteet

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

Johdatus ohjelmointiin / Lausekielinen ohjelmointi 1 & 2

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

Tähtitieteen käytännön menetelmiä Kevät 2009 Luento 4: Ohjelmointi, skriptaus ja Python

Ohjelmoinnin perusteet Y Python

13 Operaattoreiden ylimäärittelyjä

Muuttujien roolit Kiintoarvo cin >> r;

Alkuarvot ja tyyppimuunnokset (1/5) Alkuarvot ja tyyppimuunnokset (2/5) Alkuarvot ja tyyppimuunnokset (3/5)

Table of Contents. T Olio-ohjelmointi C/C++ perusteita Jukka Jauhiainen OAMK Tekniikan yksikkö 2010, 2011

ITKP102 Ohjelmointi 1 (6 op)

Algoritmit 1. Demot Timo Männikkö

Ohjelmoinnin perusteet Y Python

Chapel. TIE Ryhmä 91. Joonas Eloranta Lari Valtonen

C-kurssi syksy ltö. Luennon sisält. Luento 2: tyypit, rakenteet, makrot Tyypit. signed, unsigned short,, long Vakiot const Rakenteet

Luennon sisält. ltö. C-kurssi syksy ääreet: int ja char. Yksinkertaiset tyypit. Kokonaisluvut. Merkit

ITKP102 Ohjelmointi 1 (6 op)

Ohjelmoinnin peruskurssi Y1

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

1. luento. Ohjelmointi (C) T0004 Syksy luento. 1. luento. 1. luento. 1. luento. kurssin sisältö ja tavoitteet työmuodot.

Tietuetyypin määrittely toteutetaan C-kielessä struct-rakenteena seuraavalla tavalla:

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

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

ITKP102 Ohjelmointi 1 (6 op)

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

Kirjoita oma versio funktioista strcpy ja strcat, jotka saavat parametrinaan kaksi merkkiosoitinta.

Jakso 4 Aliohjelmien toteutus

Pythonin alkeet Syksy 2010 Pythonin perusteet: Ohjelmointi, skriptaus ja Python

Omat tietotyypit. Mikä on olio?

Ohjelmoinnin perusteet Y Python

Luento 3 (verkkoluento 3) Ttk-91 konekielinen ohjelmointi. Ohjelman esitysmuoto Konekielinen ohjelmointi ttk-91:llä (Titokone, TitoTrainer)

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

TAITAJA 2007 ELEKTRONIIKKAFINAALI KILPAILIJAN TEHTÄVÄT. Kilpailijan nimi / Nro:

Ohjelmoinnin perusteet Y Python

Transkriptio:

Osoittimet Ohjelmassa muuttujalla on nimi ja arvo. Kääntäjä ja linkkeri varaavat muistilohkon, jonne muuttujan arvo talletetaan. Muistilohkon koko riippuu muuttujan tyypistä, eli kuinka suuria arvoja muuttujan tulee kyetä tallettamaan. C-kielessä muuttujalle varattava tila on toteutuskohtainen. Esimerkiksi PC-koneissa int-tyypin muuttujalle varataan vähintään 2 tavua eli 16 bittiä (1 tavu eli byte on 8 bittiä), nykyisin int varaa 4 tavua (eli 32 bittiä). 378

Esimerkiksi määritellään kokonaislukumuuttuja nimeltä luku int luku; Sanan int perusteella kääntäjä varaa muistia 4 tavua ja muistin sisältö tulkitaan kokonaislukutyyppisenä. Samalla kääntäjä tallettaa symbolitauluun nimen luku ja lukumuuttujalle varatun muistipaikan osoitteen. Kun myöhemmin kirjoitetaan luku = 2; 379

Ohjelman suorituksen aikana oletetaan, että arvo 2 talletetaan luvulle varattuun muistipaikkaan. Muuttujaan luku voidaan liittää kaksi "arvoa". 1. Muuttujaan luku talletettu arvo 2 ja 2. Muistipaikan osoitteen "arvo" (muuttujan luku osoite voisi olla esim:bfff fda0), jonne arvo 2 on talletettu 380

Osoitinmuuttujat Usein tulee tilanteita, joissa tarvitaan muuttujia, jotka voivat sisältää muistipaikkojen osoitteita. Tällaista muistiosoitetta tallettavaa muuttujaa kutsutaan osoitinmuuttujaksi (osoitin, pointteri). C-kielessä osoitinmuuttuja määritellään lisäämällä muuttujan määrittelyssä tietotyypin ja nimen väliin tähti '*'. Muuttujan tyyppi ilmaisee minkä tyyppisen tiedon osoite voidaan tallettaa kyseisen osoitinmuuttujan arvoksi. 381

Esimerkiksi int * ptr; ptr on muuttujan nimi (aivan kuten luku on kokonaislukumuuttujan nimi ). Merkki '*' ilmoittaa kääntäjälle, että tarkoitus on luoda osoitinmuuttuja, jolle varataan tilaa sen verran kuin muistiosoitteen arvon tallettaminen vaatii. Sana int ilmoittaa, että muuttujaan ptr on tarkoitus tallettaa kokonaisluvun osoite, eli muuttuja voi osoittaa kokonaislukuun. 382

Kun kirjoitetaan int luku; luku- muuttujalle ei anneta vielä arvoa. Samoin muuttujalla ptr ei ole arvoa. Muuttujalle ptr voi antaa alkuarvoksi arvon NULL, joka ilmaisee, että muuttuja ptr ei osoita minnekkään. Joissakin kääntäjissä NULL on #define -lauseella määritelty 0:ksi, mutta kaikki kääntäjät eivät tee näin. 383

Kun muuttujaan ptr halutaan tallettaa kokonaislukumuuttujan luku osoite, käytetään &-operaattoria ptr = &luku; &-operaattori palauttaa muuttujan luku osoitteen ja tallettaa osoitteen muuttujan ptr sisällöksi, jolloin ptr "osoittaa muuttujaan luku ". 384

Kun osoitinmuuttujan avulla halutaan osoittaa jonkun muistipaikan sisältöön, käytetään osoitinoperaattoria '*'. *ptr = 7; Arvo 7 kopioidaan muuttujan ptr osoittamaan muistipaikkaan. Jos ptr osoittaa muuttujaan luku, niin silloin muuttuja luku saa arvon 7. Tähtioperaattorin avulla viitataan muuttujan (esim. ptr) osoittaman muistipaikan sisältöön, eikä viittausmuuttujan itsensä sisältöön (ns. epäsuora osoitus). 385

Esimerkkiohjelma, joka esittelee osoittimen käyttöä #include <stdio.h> int main ( void ) { int j = 1, k = 2; int *ptr; ptr = &k; printf("\nmuuttujan j arvo on %d ja osoite on %p\n", j, &j); printf("muuttujan k arvo on %d ja osoite on %p\n", k, &k); printf("muuttujan ptr arvo on %p ja osoite on %p\n", ptr, &ptr); printf("muuttujan ptr osoittaman luvun arvo on %d\n", *ptr); return ( 0); } 386

OSOITE 0x100001070 0x100001074 0x100001078 SISÄLTÖ 1 2 0x100001074 NIMI j k ptr 387

Kääntäjän täytyy tietää kuinka monta tavua täytyy tallettaa ptr:n osoittamamaan muistipaikkaan. Jos ptr on määritelty osoittamaan int-tyyppiä, kopioidaan 4 tavua. Vastaavasti double-tyypin kohdalla kopioidaan double tyypin koon määräämä tavumäärä. Tyypin koon saa selville sizeof -operaattorilla: sizeof(int) palauttaa 4 388

Osoitintyypin koon voi myös laskea esimerkiksi: sizeof(int *) palauttaa arvon 4 sizeof(double *) palauttaa arvon 4 sizeof(char *) palalauttaa myös arvon 4 389

Kun määritellään osoittimen osoittama tyyppi, voi kääntäjä tulkita ohjelmakoodia eri tavoin. Jos jossakin kohdassa keskusmuistiin on talletettu 10 kokonaislukua taulukkoon. 10 kokonaisluvun tallettamiseen tarvitaan tilaa: sizeof(int) * 10 eli 4 * 10 eli 40 tavua. 390

int * ptr = NULL; int lukuja[10]; lukuja[0] = 1; ptr = lukuja /* tai ptr = &lukuja[0] */ Jos taulukko lukuja alkaa osoitteesta 100 ja kokonaislukuosoitin ptr asetetaan osoittamaan luvuista ensimmäiseen, joka sijaitsee osoitteessa 100,niin mitä tapahtuu kun kirjoitetaan: ptr +1; 391

Kääntäjä "tietää", että muuttuja ptr on osoitin ja muuttuja osoittaa int -tyyppisen arvon osoitteeseen (osoite 100, jossa on tallessa jokin kokonaisluku). Kääntäjä lisää muuttujaan ptr arvon 4 (arvon 1 sijasta), jolloin osoitin osoittaa seuraavaan kokonaislukuun osoitteessa 104 eli osoitin siirtyy osoittamaan 4 tavua eteenpäin. 392

&lukuja[0] tai lukuja muistipaikan osoite 100 0000 0000 0 0000 0000 0000 0000 0000 0001 104 1 8 bitiä eli yksi tavu taulukon indeksit lukuja[0] ja lukuja[1] sisältö: kokonaisluku 1 binäärilukuna 393

Jos osoitin viittaisi tyyppiin double, lisättäisiin osoitinta arvolla 8 (koska double tyyppi varaa 8 tavua, 64 bittiä). Kääntäjä ei noudata samaa "aritmetiikkaa" kuin ihmiset, vaan tietotyypistä riippuen osoitinmuuttuja + 1 voi olla osoitinmuuttuja + 2 tai osoitinmuuttuja + 4, jne. Laskutoimitus ptr + 1 voidaan korvata ++ ptr ja ptr ++ operaatioilla, ptr ++:ssa osoitinta käytetään ensin ja vasta sitten kasvatetaan. Osoittimen kasvattaminen kasvattaa osoittimen arvoa sizeof(tyyppi) verran, jossa "tyyppi" on jokin C-kielen tietotyypeistä int, double, char jne. 394

Kymmenen kokonaisluvun lohko keskusmuistissa muodostaa taulukon, joten taulukoilla ja osoittimilla on seuraavanlainen yhteys int lukuja[] = {1, 2, 43, 9, 10, -1, 3, 99, -123, 0}; Taulukko lukuja sisältää 10 kokonaislukua, joihin viitataan tavallisesti indeksin avulla lukuja [0]... lukuja [9]. Taulukkoa voidaan käsitellä myös osoittimen avulla: int *ptr; ptr = &lukuja[0]; /* osoitin taulukon 1. alkioon */ 395

Seuraavassa koodissa tulostetaan taulukko sekä indeksien avulla että osoittimen avulla. #include <stdio.h> int main ( void ) { int lukuja[] = {1, 2, 43, 9, 10, -1, 3, 99, -123, 0}; int *ptr; int i; ptr = &lukuja[0]; /* ptr osoittaa taulukkoon lukuja */ printf("\n\n"); 396

for ( i = 0; i < 10; i++) { printf("lukuja[%2d] = %5d ", i, lukuja[i] ); /* <--A */ printf("ptr + %2d = %5d\n", i, *(ptr + i)); /* <--B */ } } return ( 0 ); 397

398

Joka paikassa jossa voidaan käyttää &muuttuja[0] voidaan sen sijasta käyttää muuttuja, joten koodi ptr = &lukuja[0]; voidaan kirjoittaa ptr = lukuja; Taulukon nimi on taulukon ensimmäisen alkion osoite! 399

Ei kuitenkaan voi kirjoittaa lukuja = ptr; ptr on muuttuja, mutta taulukko lukuja on ohjelman suoritusaikana vakio, eli taulukon ensimmäisen paikan osoitetta ei voi muuttaa sen jälkeen kun lukuja[] on määritelty. 400

Moniulotteiset taulukot ja osoittimet C-kielessä luodaan moniulotteinen taulukko kirjoittamalla taulukon määrittelyssä sama määrä sulkupareja kuin taulukolle halutaan ulottuvuuksia. Esimerkiksi kaksiulotteinen taulukko luodaan int lukuja [10][10]; Todellisuudessa taulukon alkioille varataan tilaa perättäisiin muistipaikkoihin. 401

Taulukon paikkaan lukuja [i][j] voidaan viitata osoittimen avulla usealla eri tavalla *(lukuja [i] + j ) (*(lukuja + i)[j] *((*(lukuja + i)) + j); *(&lukuja[0][0] + 10i + j) Sulkuja tarvitaan koska hakasulut [] on voimakkaampi operaattori kuin epäsuoruusoperaattori *. Kun moniulotteinen taulukko välitetään funktiolle, on funktion otsikossa kerrottava muiden dimensioiden paitsi ensimmäisen koot, jotta kääntäjä voi käsitellä muistia oikein. 402

Osoittimet ja merkkijonot C-kielessä merkkijonot ovat merkkitaulukoita, merkkijonon päättyminen ilmaistaan NUL-merkillä '\0'. char mjono[40]; /* yksi char vie tilaa yhden tavun 8 bit */ mjono[0] ='C'; mjono[1] = '-'; mjono[2] = 'k'; mjono[3] = 'i'; mjono[4] = 'e'; mjono[5] = 'l'; mjono[6] = 'i'; mjono[7] = '\0'; 403

Kääntäjä varaa merkkijonolle muistilohkon, kooltaan 40 tavua ja tallettaa lohkoon merkit C-kieli\0. 404

#include <stdio.h> char stra[80] ="Demonstraatiomerkkijono"; char strb[80]; int main ( void ) { char *pa; /* osoitin char-tyyppiin */ char *pb; /* osoitin char-tyyppiin */ puts (stra); /* tulosta stra-merkkijono */ pa = stra; /* pa osoittaa merkkijonoon stra */ puts ( pa ); /* näyttää minne pa osoittaa */ pb = strb; /* pb osoittaa merkkijonoon strb */ putchar('\n'); /* rivinvaihto */ while ( *pa!= '\0') { *pb++ = *pa++; } } *pb = '\0'; puts(strb); /* tulostetaan strb */ return ( 0 ); 405

Merkkijonot stra ja strb ovat globaaleja, jolloin ne strb alustetaan oletusarvoisesti '\0'-merkillä. Ohjelmassa funktiolla puts(stra) tulostetaan merkkijono kuvaruudulle, koska funktiolle välitetään stra[0]:n osoite. Sama asia voidaan tehdä myös funktiokutsulla puts( pa ), koska pa sisältää stra[0]:n osoitteen. while -toistorakenteessa toistetaan käskyä *pb++ = *pa++; niin kauan kuin pa:n osoittama merkki ei ole '\0'. 406

Käskyssä: *pb++ = *pa++; 1. Kopioidaan pa:n osoittama merkki pb:n osoittamaan paikkaan 2. jonka jälkeen pa:ta kasvatetaan osoittamaan seuraavaan merkkiin ja 3. pb:tä kasvatetaan osoittamaan seuraavan paikkaan Silmukassa ei kopioidaan '\0'-merkkiä ja se on lisättävä loppuun erikseen. 407

Seuraavassa esimerkkiohjelmassa toteutetaan oma merkkijonon kopiointifunktio omastrcpy, jolla korvataan C-kielen standardiversio. 408

char *omastrcpy ( char *kopio, char *kopioitava ) { char *p = kopio; while( *kopioitava!= '\0' ) { *p++ = *kopioitava++; } *p = '\0'; } return ( kopio ); 409

Funktio palauttaa viittauksen kopio-merkkijonoon, kuten alkuperäinenkin strcpy()-funktio. Ohjelmaa voidaan käyttää int main ( void ) {... omastrcpy ( strb, stra ); puts ( strb ); return ( 0 ); } 410

C-kielessä merkkijonovakio voidaan määritellä osoittimen avulla seuraavasti char *mjono = "Tämä on merkkijono"; 411

Mutta tämä aiheuttaa virhetilanteen: #include <stdio.h> int main( void ) { char * merkkijono; printf("\nanna merkkijono > "); scanf("%s", merkkijono); } printf("\nsyötit merkkijono \2%s\n\n", merkkijono); return 0; 412

413

Taulukkoon voidaan viitata usealla eri tavalla int taulu [10] = { 1, 2, 3, 4,5 }; int *pi; int i = 3; pi = &taulu[0]; taulu[i] = 11; /* tallettaa luvun 4 päälle luvun 11 */ *(pi + i) = 22; /* tallettaa luvun 11 päälle luvun 22 */ *(i + pi) = 33; /* tallettaa luvun 22 päälle luvun 33 */ i[taulu] = 44; /* tallettaa luvun 33 päälle luvun 44 */ 414