Gå til innhold

Hjelp til å forstå kodesnutt


Anbefalte innlegg

Hei,

 

Newbie spørsmål inc :)

 

Jeg holder for tiden på med et nybegynner-kurs i programmering, språket er java. I den forbindelse har jeg eksamen i morgen, dermed sitter jeg nå og løser gamle eksamensoppgaver.

 

I en av de gamle oppgavene ligger følgende kodesnutt:

 

public class DecDemo
{
   public static void main(String args[]){
       double d = 12.3;
       Decrementer dec = new Decrementer();
       dec.decrement(d);
       System.out.println(d);
   }
}

public class Decrementer
{
   public void decrement(double decMe){
       decMe = decMe - 1.0;
   }
}

 

Min oppgave er da å finne ut hva som skrives ut i linje seks. Jeg gikk mest sannsynlig rett i fella og endte opp med 11.3, som viste seg å være feil. Svaret skal bli at "d" fortsatt er 12.3, også etter koden er kjørt. Jeg regner med at det har noe med at decMe-variabelen ikke lagres noe sted, og dermed dør ut?

 

Kan noen gi meg en god forklaring på dette? Tusen takk! :)

 

edit:

 

Legger til en til i samme slengen, nå som jeg er så godt i gang!

 

public void oppgA(){
       int x = 100;
       int y = x/4;
       while(y < 80){
           y = (x--) - y + 10;
       }
       x -= y;     
       System.out.println(x);
   }

 

Samme opplegg der, hva er x. Det er et eller annet inne i den while løkka jeg ikke helt får med meg. Når det står (x--), betyr det da at selve variabelen endrer seg? Trodde egentlig bare det betydde at man skulle tenke (99 - 25 + 10) ved første gjennomkjøring. Men da har tydeligvis x-variabelen endret seg (for godt), dermed blir "y" 99/4 (som er 24,etellerannet).

 

Care to explain?

Endret av NiRaM
Lenke til kommentar
Videoannonse
Annonse

Ser ut til at den teller ned med 1.

 

Det ser sånn ut ja, men det blir feil. Når jeg kjører koden forblir den uendret, altså 12.3. Lure-oppgave tydeligvis :tease:

 

edit: Sett litt mer på den første oppgaven nå. Slik jeg forstår det endres decMe-variabelen til 11.3, men den dør bare ut når metoden decrement er kjørt. Dermed forblir "d" 12.3. Hvis jeg skulle printet ut "d" med den nye verdien måtte jeg vel lagt til følgende kodelinje på slutten av decrement:

 

System.out.println(decMe);

Riktig?

Endret av NiRaM
Lenke til kommentar

public class DecDemo
{
   public static void main(String args[]){
       double d = 12.3;
       Decrementer dec = new Decrementer();
       dec.decrement(d);
       System.out.println(d);
   }
}

public class Decrementer
{
   public void decrement(double decMe){
       decMe = decMe - 1.0;
   }
}

 

public void oppgA(){
       int x = 100;
       int y = x/4;
       while(y < 80){
           y = (x--) - y + 10;
       }
       x -= y; 	
       System.out.println(x);
   }

 

På den første koden så blir 12.3 gitt med til decrement metoden, og i den metoden blir variabelen 11.3, men denne verdien blir aldri gitt tilbake til main så i main er fremdeles d 12.3

 

På den andre koden så blir kjøringen slik som dette:

 

x = 100

y = 100/4 = 25

 

25 < 80 (SANT)

y = 100(her blir verdien i x brukt FØR den blir trukket med 1, så etter denne kjøringen er x 99) - 25 + 10 = 85

 

85 < 80 (USANT)

 

x -= y = 99 - 85 = 14

 

14

Lenke til kommentar

Takk for fint svar! Det er tydelig at det stemmer, men jeg forstår fremdeles ikke alt..

 

Jeg forstår liksom ikke hvorfor verdien i X blir brukt FØR den blir trukket, når det står x--. Det blir ulogisk for mitt hode, men så er jeg fremdeles relativt fersk innen programmering også. Får sjå litt mer på det :)

Endret av NiRaM
Lenke til kommentar

x-- betyr at verdien i variabelen x blir brukt FØR den blir trukket med 1 forde -- er på høyre side, altså etter

--x betyr at verdien i variabelen x blir trukket med 1 FØR den blir brukt forde -- er på venstre side, altså før

 

Aha! Det forklarer en del! :D

 

Et siste spørsmål da... Med tanke på at x-- står inne i while-løkka, finnes det noen god forklaring på hvorfor x-variabelen blir 99 også etter løkka er kjørt? Sånn jeg tenker er det bare noe som skjer lokalt inne i løkka, før x stiller seg tilbake til 100.. Jeg skjønner at x-- betyr at man bruker verdien 100 først, før x blir 99. Er det fordi x-variabelen blir deklarert utenfor løkka da?

 

Vanskelig å forklare, men håper dere forstår :/

Endret av NiRaM
Lenke til kommentar

Det har med scope å gjøre. Er litt vanskelig å forklare. Men greia er det at x er deklarert(angitt) øverst i metoden og kan da brukes av alt i den metoden. Så har ikke så mye å si at editeringen av x forgår i while løkka, den kunne likegodt blitt editert utenfor while løkka

Lenke til kommentar

Kanskje jeg bare forvirrer TS nå, men dersom double d = 12.3 og funksjonen i Decrement hadde brukt Double (stor D) så hadde oppførselen vært slik du antok den burde gjort i starten.

Tror ikke det. Double er immuterbar, alle operasjoner på den returnerer en ny Double.

Ah selvsagt. Jeg lurer på hvor hodet mitt var.

Endret av GeirGrusom
Lenke til kommentar

Nå ble jeg vel egentlig litt mer forvirra ja, men velger å se bort fra det ettersom det så ut til å ikke stemme. Men regner med du tenkte i retning av wrapper classes (om jeg husker rett).

 

Et lite spørsmål til sånn på tampen, mens jeg ennå har huet i eksamenslesings-modus:

 

Hva er en anonym variabel? Står som spm på ene eksamensoppgava her.

Anonymt objekt tror jeg at jeg har noenlunde peil på, men finner ikke noe om anonym variabel..

Lenke til kommentar

Kan aldri huske å ha hørt om begrepet «anonyme variabler» før. Et søk i javaspesifikasjonene gir ikke noe treff. Ville sjekket lysark / pensumbok fra faget.

 

Etter litt googeling fant jeg en blogg som beskriver anonyme variabler med disse to eksemplene.

int sum(int a, int b) {
int result = a + b;
return result;
}

 

vs

 

int sum(int a, int b) {
return a + b;
}

 

 

Jeg kunne gått med på å kalle det anonyme variable dersom man tenker på en interne representasjonen av koden i from av «Administrativ Normal Form», men det blir litt søkt (spesielt mtp at det er java).

 

 

Lenke til kommentar

Ja. Det er tydlig vis det at man skriver et uttrykket «direkte inn» der man skal bruke det, uten å «mellomlagre» det i en navngitt variabel først.

 

Ikke nødvendigvis, resultatet blir lagt på stacken i JVM men ingen lokal eller non-lokal variabel blir tilegnet denne verdien, så den blir liggendene på stacken og kan bli plukket opp av noe som forventer en verdi, men dette må ikke skje.

 

Det er mange operasjoner i Java som resulterer i verdier, men det er ikke alle vi trenger å bry oss om.

For å se på forskjellen mellom post-crement og pre-crement kan det være greit å se på kode:

 



class test
{
   static int bias = 10;
   public static void main(String[] args)
   {
int en = prePluss(3,7);      
System.out.println(en); // 21
en = postPluss(en, bias);
System.out.println(en); //43
   }
   static int prePluss(int a, int b)
   {
return a + b + ++bias;
   }
   static int postPluss(int a, int b)
   {
return a + b + bias++;
   }
}
///...
static int prePluss(int, int);
 Code:
  0:   iload_0 //putt int a 3 (a) på stacken, => 3 
  1:   iload_1 //putt int b 7 (b) på stacken, => 7,3 
  2:   iadd //popp to ganger og legg sammen, => 10
  3:   getstatic       #5; //Field bias:I //hent variabel => 10,10
  6:   iconst_1 //putt tallet 1 på stakken => 1,10,10
  7:   iadd //popp to ganger og legg sammen, => 11,10
  8:   dup //dupliser første element =>, 11,11,10
  9:   putstatic       #5; //Field bias:I //og putt dette til variabelen => 11,10
  12:  iadd //legg sammen => 21
  13:  ireturn //returner 21, verdien til hele metodeinvokasjonen er da 21

static int postPluss(int, int);
 Code:
  0:   iload_0 => 21
  1:   iload_1 => 11,21
  2:   iadd => 32
  3:   getstatic       #5; //Field bias:I => 11,32
  6:   dup => 11,11,32
  7:   iconst_1 => 1,11,11,32
  8:   iadd => 12,11,32
  9:   putstatic       #5; //Field bias:I => 11,32
  12:  iadd => 43
  13:  ireturn (43) =>


 

Legg merke til hvordan postkrement er "get dup const add put" mens prekrement er "get const add dup put".

Lenke til kommentar
  • 1 måned senere...

Her er en måte: La til en toString() metode slik at man lett kan se info'en i Decrementer-klassen.

 

class DecDemo {
public static void main(String[] args) {
	double d = 12.3;
	Decrementer dec = new Decrementer(d);
	System.out.println(dec.getDecrementNum());
	System.out.println(dec.toString());
}
}

class Decrementer {
double num;
public Decrementer(double num) {
	this.num = num;
}

public double getDecrementNum() {
	return (num - 1);
}

public String toString() {
	return "Gammelt nummer: " + num + "\nNytt nummer: " + getDecrementNum();
}
}

Endret av LarTVE
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...