public static <returtype> navn_til_prosedyre(<parameter liste>) { // implementasjon av prosedyren

Like dokumenter
public static <returtype> navn_til_prosedyre(<parameter liste>) { // implementasjon av prosedyren

OPPGAVE 1 OBLIGATORISKE OPPGAVER (OBLIG 1) (1) Uten å selv implementere og kjøre koden under, hva skriver koden ut til konsollen?

Objekter og referanser

Programmeringsspråket C

Programmeringsspråket C

Programmeringsspråket C

Forkurs INF1010. Dag 1. Andreas Færøvig Olsen Tuva Kristine Thoresen

Innhold uke 4. INF 1000 høsten 2011 Uke 4: 13. september. Deklarasjon av peker og opprettelse av arrayobjektet. Representasjon av array i Java

INF1000 EKSTRATILBUD. Stoff fra uke 1-5 (6) 3. oktober 2012 Siri Moe Jensen

OPPGAVESETT 7 OBJEKTER OG REFERANSER

INF1000 (Uke 5) Mer om løkker, arrayer og metoder

Feilmeldinger, brukerinput og kontrollflyt

INF 1000 høsten 2011 Uke september

2 Om statiske variable/konstanter og statiske metoder.

INF1000 undervisningen INF 1000 høsten 2011 Uke september

Fra Python til Java. En introduksjon til programmeringsspråkenes verden. Dag Langmyhr

Introduksjon til objektorientert. programmering. Hva skjedde ~1967? Lokale (og globale) helter. Grunnkurs i objektorientert.

2 Om statiske variable/konstanter og statiske metoder.

INF1000: noen avsluttende ord

Repetisjon: Statiske språk uten rekursive metoder (C1 og C2) Dagens tema Kjøresystemer (Ghezzi&Jazayeri 2.6, 2.7)

Del 1 En oversikt over C-programmering

Dagens tema Kjøresystemer (Ghezzi&Jazayeri 2.6, 2.7)

IN1010. Fra Python til Java. En introduksjon til programmeringsspråkenes verden Dag Langmyhr

Minnehåndtering i operativsystemer

IN våren 2019 Onsdag 16. januar

IN våren 2018 Tirsdag 16. januar

Dagens tema. C-programmering. Nøkkelen til å forstå C-programmering ligger i å forstå hvordan minnet brukes.

Minnehåndtering i operativsystemer

Ark 1 av 18. programmeringsspråkenes. Velkommen til IN 211. verden. IN 211 Programmeringsspråk

Praktisk informasjon. I dag. Repetisjon: While-løkker. INF1000 (Uke 5) Mer om løkker, arrayer og metoder

IN1010. Fra Python til Java. En introduksjon til programmeringsspråkenes verden Dag Langmyhr

156C. Algoritmer og maskinspråk. IT1101 Informatikk basisfag. Maskinspråk: det maskinen forstår. Assembler / assemblerspråk

Oversikt. INF1000 Uke 2. Repetisjon - Program. Repetisjon - Introduksjon

Oversikt. INF1000 Uke 1 time 2. Repetisjon - Introduksjon. Repetisjon - Program

Kapittel 1 En oversikt over C-språket

Programmering i C++ Løsningsforslag Eksamen høsten 2005

INF1000 Metoder. Marit Nybakken 16. februar 2004

Introduksjon til objektorientert programmering

Kort om meg. INF1000 Uke 2. Oversikt. Repetisjon - Introduksjon

INF våren 2017

i=0 Repetisjon: arrayer Forelesning inf Java 4 Repetisjon: nesting av løkker Repetisjon: nesting av løkker 0*0 0*2 0*3 0*1 0*4

Forelesning inf Java 4

INF1000: Forelesning 7

Uke 8 Eksamenseksempler + Ilan Villanger om studiestrategier. 11. okt Siri Moe Jensen Inst. for informatikk, UiO

Forkurs INF1010. Dag 2. Andreas Færøvig Olsen Gard Inge Rosvold Institutt for Informatikk, 14.

Feilmeldinger, kontrollflyt og void-metoder

INF225 høsten 2003 Prosjekt del 4: kodegenerering

Praktisk informasjon. Repetisjon: While-løkker. I dag. INF1000 (Uke 5) Mer om løkker, arrayer og metoder. Oblig 2 er lagt ut

UNIVERSITETET I OSLO

Løsningsforslag ukeoppg. 6: 28. sep - 4. okt (INF Høst 2011)

Forelesning inf Java 5

INF1000: Forelesning 7. Konstruktører Static

Forelesning inf Java 5

Av Stein Gjessing, Institutt for informatikk, Universitetet i Oslo

Data. Dette refereres til som objektets tilstander. Funksjonalitet. Dette refereres til som objektets metoder.

Informasjon Eksamen i IN1000 høsten 2017

INF1010 våren januar. Objektorientering i Java

Semantikk. Dagens tema Kjøresystemer (Ghezzi&Jazayeri 2.6, 2.7) Semantikk. Semantikk. En måte å svare på: gi semantikken til språket!

UNIVERSITETET I OSLO

Løsningsforslag ukeoppg. 2: 31. aug - 6. sep (INF Høst 2011)

LITT OM OPPLEGGET. INF1000 EKSTRATILBUD Stoff fra uke September 2012 Siri Moe Jensen EKSEMPLER

Rekursjon som programmeringsteknikk

Velkommen til. INF våren 2016

Kapittel 1: Datamaskiner og programmeringsspråk

Forklaring til programmet AbstraktKontoTest.java med tilhørende filer Konto.java, KredittKonto.java, SpareKonto.java

EKSAMEN. Dato: 9. mai 2016 Eksamenstid: 09:00 13:00

Del 4 Noen spesielle C-elementer

Dagens tema Kapittel 8: Objekter og klasser

INF Uke 10. Ukesoppgaver oktober 2012

Hva er verdien til variabelen j etter at følgende kode er utført? int i, j; i = 5; j = 10; while ( i < j ) { i = i + 2; j = j - 1; }

INF1010 våren 2008 Uke 4, 22. januar Arv og subklasser

INF1000 (Uke 15) Eksamen V 04

INF1000 (Uke 15) Eksamen V 04

Kapittel 8: Programutvikling

UNIVERSITETET I OSLO

UNIVERSITETET I OSLO

Dagens tema. Hva er kompilering? Anta at vi lager dette lille programmet doble.rusc (kalt kildekoden): Hva er kompilering?

UNIVERSITETET I OSLO

løsningsforslag-uke5.txt

Blokker og metoder INF1000 (Uke 6) Metoder

UNIVERSITETET I OSLO

UNIVERSITETET I OSLO

Runtimesystemer Kap 7 - I

INF1000 (Uke 4) Mer om forgreninger, While-løkker

UNIVERSITETET I OSLO

IN1010 våren januar. Objektorientering i Java

Oppsummering. Kort gjennomgang av klasser etc ved å løse halvparten av eksamen Klasser. Datastrukturer. Interface Subklasser Klasseparametre

I dag INF1000 (Uke 4) Mer om forgreninger, While-løkker. Tre måter å lese fra terminal. Tre måter å lese fra terminal.

LC191D Videregående programmering Høgskolen i Sør-Trøndelag, Avdeling for informatikk og e-læring. Else Lervik, januar 2012.

Endret litt som ukeoppgave i INF1010 våren 2004

Kort repetisjon av doble (nestede) løkker Mer om 1D-arrayer Introduksjon til 2D-arrayer Metoder

Runtime-omgivelser Kap 7 - I

Kapittel 1: Datamaskiner og programmeringsspråk

Velkommen til INF1060. Introduksjon til operativsystemer og datakommunikasjon

I dag INF1000 (Uke 4) Mer om forgreninger, While-løkker. Tre måter å lese fra terminal. Repetisjon. Mer om forgrening While-løkker

Generiske mekanismer i statisk typede programmeringsspråk

Runtimesystemer Kap 7 - I

Oppgave 1 JK-flip-flop (Total vekt 20%)

INF1000 : Forelesning 4

Beskrivelse av programmeringsspråket Compila15 INF Kompilatorteknikk Våren 2015

Transkript:

Prosedyrer Hensikten med en prosedyre Hensikten med en prosedyre er, logisk sett, å representere en jobb eller en funksjonalitet i et eller flere programmer. Bruk av entall er viktig: vi har generelt en prosedyre for en funksjonalitet (ikke en prosedyre for flere funksjonaliteter). For eksempel, alle funksjonaliteter i programmer som Microsoft Word (funksjonalitet relatert til knapper, input fra bruker, tegning av grafikk etc.) har minst en prosedyre relatert til seg. Prosedyre-basert programmering er en løsning for å håndtere kompleksitet i programutvikling. Komplekse eller store programmer er utfordrende å utvikle og vedlikeholde fordi man må gjøre endringer i store deler av koden hele tiden. Det er snakk om endringer som forbedringer, endring i kodestruktur, og korrigering av feil. Løsningen for å håndtere slik kompleksitet er alltid å dele programmet opp i mindre biter. I prosedyre-basert programmering, er disse bitene representert som prosedyrer. Prosedyrer i Java: syntaks Prosedyrer opprettes i Java ved følgende syntaks: public static <returtype> navn_til_prosedyre(<parameter liste>) { // implementasjon av prosedyren return <variabel eller verdi>; // retur-verdien til prosedyren Eksempler: // I Java, må alle prosedyrer bli deklarert inne i en klasse. // Klasser er relatert til objekt-orientert programmering, noe // som blir introdusert senere i faget public class Eksempel { // Prosedyre som returnerer en int verdi public static int a() { return 5; // Prosedyre som inverterer en input boolsk verdi public static boolean b(boolean input) { return!input; // Parameterlisten angis med komma mellom hver variabel public static int sum(int a, int b) { return a + b;

// Void-prosedyrer returnerer ingen verdier public static void skriv_melding() { System.out.println("Hello Procedure World!"); // Man trenger ikke return instruksjonen for void // return er et ubetinget hopp: den hopper ut av prosedyren public static void ret_demo(boolean verdi) { if(verdi) { System.out.println("Verdien er true!"); return; // hopp ut av prosedyren else { System.out.println("Verdien er false!"); return; // trenger ikke verdi fordi typen er void // Pga return-hopp, så er det umulig å nå instruksjonene // etter denne if-else konstruksjonen. // Main-prosedyren er en 'spesiell' prosedyre som angir // starten av programmet public static void main(string[] args) { int i = a(); boolean bool = b(true); int i2 = sum(i,5); skriv_melding(); ret_demo(bool); // slutt på klassen Håndteringen av prosedyrer i datamaskinen Datamaskinen støtter ikke prosedyrer direkte. Prosedyrer oppnås hovedsakelig av kompilatoren som konverterer prosedyrer til maskinkode. Kompilatoren utfører mesteparten av minnehåndteringen som er beskrevet under. Vi har så langt i faget sett på to minnesegmenter til et program: instruksjonssegmentet og datasegmentet. Instruksjonssegmentet inneholder alle instruksjonene til programmet, mens datasegmentet inneholder verdien til alle variablene til programmet. Prosedyrer og data assosiert med prosedyrer er relatert til datasegmentet. For denne diskusjonen er det hensiktsmessig å dele opp datasegmentet i to deler: global og stabel (eng: stack). Stabelsegmentet inneholder verdier til alle variabler som har blitt deklarert i prosedyrer. Det globale segmentet inneholder verdier til alle variablene som har blitt deklarert utenfor prosedyrene til programmet.

public class Eksempel { // Dette er en variabel som er deklarert utenfor prosedyrene // til programmet. Verdien (5) til variabelen global_variabel // ligger nå i det globale datasegmentet. public static int global_variabel = 5; // Main er en prosedyre. Alle variablene som blir deklarert // inne i en slik prosedyre blir plassert på stabelen. public static void main(string[] args) { int stabel_variabel = 5; Variabler plassert i det globale datasegmentet er tilgjengelige i alle prosedyrer, dermed navnet 'global'. Disse variablene kalles ofte globale variabler. Slike globale variabler er alltid tilgjengelige og blir opprettet når programmet starter opp. Det vil si at antall variabler som er plassert i det globale datasegmentet er konstant, noe som fører til at størrelsen til dette datasegmentet, i antall bytes, også er konstant. Siden størrelsen til segmentet er konstant og verken kan utvides eller forminskes, refereres et slik segment til som et statisk segment (må ikke forveksles med nøkkelordet static i Java). En variabel plassert på stabelen er utelukkende tilgjengelig i prosedyren den er deklarert i. En slik variabel eksisterer også utelukkende på minne hvis prosedyren 'kjører'. Hvis prosedyren ikke kjører, så finnes ikke variabelen på minne. Dette fører til at stabelsegmentet kontinuerlig endres i størrelse: når en prosedyre 'starter', vil alle variablene relatert til prosedyren legges til stabelsegmentet. Når prosedyren er ferdig å kjøre, blir variablene slettet fra stabelsegmentet. Det vil si, desto flere prosedyrer som er aktive i programmet, desto mer minne bruker programmet. Et slikt datasegment som kontinuerlig endres i størrelse, refereres til som et dynamisk segment. Dataene relatert til en prosedyre kalles et 'stack frame' (jeg bruker det engelske uttrykket for nøyaktighetens skyld). Et stack frame inneholder følgende data: Parameterlisten Lokale variabler Returadresse Eksempel på neste side.

// Data på stack frame til p: // - verdiene til a, b, c (parametere) // - verdiene til d og e (lokale variabler) public static void p(int a, short b, byte c) { char d = 'd'; int e = a + b + c + d; public static void main(string[] args) { p(5,6,7); // Faktiske verdier til stack framen til p: // - 5, 6, 7 (parametere) // - 'd', a+b+c+d (lokale variabler) // - adressen til neste instruksjon (instruksjonen under) System.out.println("I'm back"); // instruksjonen over skal utføres etter at p er ferdig utført. Enver prosedyre trenger å vite returadressen for at programmet kan manipulere programtelleren slik at man hopper tilbake til den kallende prosedyren. I dette eksempelet, må prosedyren p vite at den kom fra main-prosedyren (det er i main p(5,6,7) kalles), slik at neste instruksjon i main kan utføres. Når datamaskinen utfører kjøringen til et program, utfører den alltid en prosedyre, der vi starter med main-prosedyren. Hvis main kaller på en prosedyre, som p i eksempelet, blir stack framen til p lagt til stabelsegmentet. Etter at p er ferdig utført, blir stack framen slettet fra stabelsegmentet. Det eneste som overlever en prosedyre er returverdien til prosedyren. Håndteringen av stabelsegmentet gjøres via datastrukturen stabel (eng: stack). Dette er en enkel form for datastruktur som kan sammenlignes med en stabel av tallerkener (f.eks. i kantinen): du legger til og fjerner tallerkener fra stabelen utelukkende fra toppen (antatt at du ikke løfter opp tallerkenene for deretter å plassere nye tallerkener på bunnen). I denne analogien, er et stack frame en tallerken og stabelen av tallerkener er de aktive prosedyrene til programmet. Merk at main-prosedyren vil alltid ligge på bunnen av stabelen. Eksempel: 1: public static void a(int b, int c) { 2: int d = b + c; 3: System.out.println(d); 4: 5: public static void main(string[] args) { 6: int b = 5; 7: int c = 6; 8: a(b,c); 9: System.out.println("Done!"); 10: I dette eksempelet, vil stabelen se slik ut ved linje 7 (ved å bruke fargekodene relatert til hver prosedyre):

Verdien til args "Done!" (dette er også en variabel) Returadresse (ikke viktig for main) Ved linje 7, er det dermed en aktiv prosedyre i programmet: main. Det vil si at stabelen inneholder et stack frame stack framen til main. Ved linje 8 kaller vi på prosedyren a. Da blir stabelen utvidet slik: 5+6 (variabel d) 9 (returadresse) Verdien til args "Done!" (dette er også en variabel) Returadresse (ikke viktig for main) Merknader: Verdier blir kopiert fra en prosedyre til en annen. Vi ser at stabelen inneholder to verdier av 5 og 6. Noen språk, som C, tilbyr alternative kopieringsmodus, som kopiering via peker. Dette konseptet introduseres i neste forelesning. En prosedyre kan bare aksessere data på stack framen som ligger øverst på stabelen. Det vil si at prosedyren a ikke har tilgang til verdiene i de røde cellene i tabellen. Når en prosedyre starter, vil den bare angi verdier til variabler som den vet verdien til. Verdien til variabelen d i prosedyren a er dermed udefinert før den utfører instruksjon 2. Det vil si at instruksjonene 6 og 7 faktisk ikke utføres fordi verdiene til b (5) og c (6) blir angitt direkte av programmerer og kan bli tildelt før main prosedyren starter sine instruksjoner. Ulike praktiske konsekvenser av oppførselen til stabelen introduseres i oppgavesett 4. Prosedyren a kan også kalle på andre prosedyrer, noe som vil videre utvide stabelen. Eksempel på neste side. Eksempelet viser at stabelen utvides når nye prosedyrer kalles på. Hvert program har et begrenset området på minne allokert til seg for stabelen. Hvis stabelen går utover denne begrensningen, vil operativsystemet avslutte programmet (programmet vil krasje hvis man ikke eksplisitt håndterer dette). Dette kalles stabeloverflyt (eng: stack overflow).

1: public static void a(int b, int c) { 2: int d = sum(b,c); 3: System.out.println(d); 4: 5: public static int sum(int a, int b) { 6: return a + b; 8: 9: public static void main(string[] args) { 10: int b = 5; 11: int c = 6; 12: a(b,c); 13: System.out.println("Done!"); 14: Stabelen ved instruksjon 2, dvs. etter at prosedyren sum blir opprettet på stabelen: 5 (variabel a) 6 (variabel b) 5+6 (returverdien) 3 (returadresse) sum(a,b) (variabel d) 13 (returadresse) Verdien til args "Done!" (dette er også en variabel) Returadresse (ikke viktig for main) Scopes Over, så vi at en prosedyre bare kan aksessere variabler som ligger i den øverste stack framen og globale variabler (som alle prosedyrer kan aksessere). Høy-nivå programmeringsspråk, som Java, tilbyr en videre begrensing for aksessering: scopes. I Java, angis et scope med krøllparentesene {. Regelen er slik at variabler som deklareres i et scope, ikke er tilgjengelig utenfor scopet. Eksempel: public static void p() { // scope 1 int a = 4; // tilgjengelig i scope 1, 2, og 3 { // scope 2 int b = 4; // tilgjengelig i scope 2 og 3 while(b > 0) { // scope 3 int c = 1; // tilgjengelig i scope 3 b -= c; // slutt på scope 3 // slutt på scope 2 // slutt på scope 1

Merk at denne begrensningen, og slike 'scopes' generelt, håndteres av kompilatoren til språket og ikke av datamaskinen. Det er dermed kompilatoren sin jobb å oppdage om programmereren har brutt regelen relatert til scope, som å bruke en variabel som ikke er en del av det nåværende scopet. Dette betyr at håndteringen av stabelen er den samme selv om en prosedyre bruker flere scopes. Eksempel: public static void p1() { int a = 0; int b = 2; for (int i = 0; i < 1000; i++) { a += b; public static void p2() { int a = 0; for (int i = 0; i < 1000; i++) { int b = 2; a += b; Ut ifra koden over, kan man kanskje tro at variabelen b blir opprettet 1000 ganger i prosedyren p2. Dette er ikke tilfellet. Alle lokale variabler, selv om de blir deklarert i en løkke, blir opprettet til stack framen til prosedyren på samme måte, dvs. før prosedyren starter å utføre sine instruksjoner. Stack framene til p1 og p2 er dermed like store, i antall bytes, fordi de har like mange variabler relatert til seg (og variablene er av samme type).