[LØST] Metodekall uten parameteroverføring

8 innlegg i emnet

Skrevet

Heisann, jeg begynner å forstå når vi sender parametere nå i metode kall, men se på denne koden:

public class Oppgave2b

{

public static void metode() {

int j = 9;

}

public static void main( String[] args ) {

int i = 2;

int j = 2*i + 1;

metode();

System.out.println(j);

}

}

Det som blir printet ut her er jo 5, men hvorfor?

Jeg tolker det slik at variabelen i blir satt en verdi = 2 og og variabelen j blir satt en verdi = 5

Videre så ser jeg at metoden "metode" blir kalt opp, men den sender ikke opp kopier av noen variable eller referanser. så trodde jeg at ja, da bryr vi ikke oss om hva som skjer i metoden "metode", men det er vel feil?

Hvis det hadde stått metode(j) så hadde vi ikke brydd oss om hva metoden gjorde, for det har ingen innvirkning på originalen, men hva skjer her med den tomme parantesen() ?? =)

0

Del dette innlegget


Lenke til innlegg
Del på andre sider

Skrevet

Inne i metode() blir en ny variabel "j" av type int opprettet. Den er lokal, og forsvinner derfor så fort funksjonen returnerer.

Prøv å endre "int j = 9;" til "j = 9;".

0

Del dette innlegget


Lenke til innlegg
Del på andre sider

Skrevet

Er det noe kjennetegn på at den er lokal?

Vil det si at alle variable som blir opprettet i en metode forsvinner når metoden er utført?

Eller er det slik at jeg i main opprettet en variabel j = 5, da blir den lagt inn i en adresse i minnet.

I metoden blir det opprettet enda en variabel men verdi lik = 9, får denne en annen adresse at derfor spiller den ikke noe rolle inn på variabelen j i main? er navnet inrelevant?

0

Del dette innlegget


Lenke til innlegg
Del på andre sider

Skrevet

Riktig. Alle variabler som opprettes i en funksjon blir utilgjengelige når funksjonen returnerer. De kan kalles 'lokale' fordi det kun er tilgjenelig for bruk inne i funksjonen (verdiene til disse kan alikevel 'hentes ut' ved returverdi og ved bruk av andre variabler som ikke vil forsvinne når funksjonen er ferdig).

Jepp, den nye j gjelder kun i den funksjonen, og jeg tror det er derfor den kan ha samme navn. Navnet "j" blir brukt til en ny variabel i den tiden der funksjonen kjøres.

0

Del dette innlegget


Lenke til innlegg
Del på andre sider

Skrevet

Alle variabler har en rekkevidde (scope) og det er enten globalt eller lokalt. Hva som bestemmer rekkevidden til en variabel er hvor den blir opprettet (deklarert).

I f.eks. Java så definerer du kodeblokker (statement blocks) med { og }. De gir et avgrenset område , som regel en funksjon men kan også være i for-løkker, if setninger eller andre ting.

En variabel som blir opprettet innenfor en slik kodeblokk vil bare være tilgjengelig i den blokken og ikke utenfor. Den er da en lokal variabel.

I mange språk har man muligheten til å opprette variabler utenfor de vanlige blokkene og da får du en global variabel. Den vil være tilgjengelig i hele programmet ditt.

public class Oppgave2b

{

	public static void metode() {

		int j = 9;

	}


	public static void main( String[] args ) {

		int i = 2;

		int j = 2*i + 1;

		metode();

		System.out.println(j);

	}

}
Her blir en variabel j opprettet to ganger, den ene gangen i main() metoden din. Derfra er den bare tilgjengelig innenfor { og } som hører til main(). Den er ikke tilgjengelig i andre metoder, slik som f.eks. i metode(). Men der opprettes det en ny variabel j. Den har tilfeldigvis samme navn (siden det er en oppgave så er det vel strengt tatt ikke så tilfeldig) men er altså, som du selv sier, en helt ny variabel og en helt annen plass i minnet. Disse to er ikke i konflikt i det hele tatt siden de begge er i hver sin kodeblokk og er ikke i nærheten av å plage hverandre. Som du korrekt sier så er navnet fullstendig irrelevant og det er fordi de er i forskjellige kodeblokker.
public class Oppgave2b

{

	static int j = 12;


	public static void metode() {

		int j = 9;

	}


	public static void main( String[] args ) {

		int i = 2;

		int j = 2*i + 1;

		metode();

		System.out.println(j);

		System.out.println(Oppgave2b.j);

	}

}

Her er det kommet opp en ny j variabel i den ytterste kodeblokken. Den variabelen er da tilgjengelig i i hele Oppgave2b klassen, også inne i kodeblokkene til metode() og main(). Men så deklareres det variabler i de to metodene med samme navn. De vil da skjule (overskygge / shadowing) den ytterste j-en. For å nå den ytterste j-en må vi ha et litt mer detaljert navn, Oppgave2b.j, som forteller eksakt hvilken j vi mener.

hva skjer her med den tomme parantesen() ?? =)
En metode skal alltid ha paranteser. Det er bl.a. slik kompilatoren kan se at dette er en metode og ikke en variabel. Så en metode uten parameter skal altså ha en tom parantes.

Denne oppgaven er forøvrig ett godt argument for lengre og mer beskrivende variabelnavn. Da slipper man mye av den forviringen når man bruker i,j, k og str rundt omkring og overalt.

Er det noe kjennetegn på at den er lokal?

Vil det si at alle variable som blir opprettet i en metode forsvinner når metoden er utført?

Kjennetegnet er at den blir deklarert inne i en metode. Når programmet forlater rekkevidden til variabelen (out of scope), dvs er ferdig med metoden, så "forsvinner" den. I praksis så blir det minneområdet merket som ubrukt og Java sin garbage collector frigjør minnet ved ledighet.

Håper du ble noe klokere :)

0

Del dette innlegget


Lenke til innlegg
Del på andre sider

Skrevet

Ble mye klokere =)

Men har et spørsmål til som handler mye om det du hjalp med i går :)

public static void main(String[] args) {

int[] tab = {1,2,3,4};


fun2(tab);

for( int i = 0; i < tab.length; i++ ) {

System.out.print("" + tab[i] + " " );

}


public static void fun2( int[] a ) {

for( int i = 0; i < a.length; i++ ) {

a[i] = 1;

}

Her så oppretter jeg jo en heltallsarray på 4 elementer, skal jeg se på den som en primitiv type, eller objekt type?

int[] tab = {1,2,3,4} er det det samme som at vi deklarer en variabel "tab" som har referanse(adresse) til en heltallstabellobjekt ???

fun2 får adressen kopiert til seg og vi kan si "Hei, her er adressen til tabellen, gå å gjør hva du vil med den".

fun2 gjør det jeg sier og dataene vil bli endret, siden vi ikke tok kopi av dataene som vi i eksempelvis gjør med primitive variable.

så spørsmålet er vel egentlig int[] tab = {1,2,3,4} , hva gjør den? er det et objekt type? int type? eller hva?

0

Del dette innlegget


Lenke til innlegg
Del på andre sider

Skrevet

int tab[] = {1,2,3,4}; eller int *tab = {1,2,3,4};, legger 4 stk ints i minnet, og lagrer adressen til det første elementet i tab (en peker altså).

tab er en peker, *tab eller tab[] peker til første element i lista. Hvor den peker hen kan påvirkes med offsets, tab[n] peker til element med offset n (første element har offset 0). Det er også mulig å skrive *(tab+n), men jeg er usikker på om det fungerer som ønsket, ettersom n muligens angir offset i antall bytes på denne måten.

Håper det svarte på spørsmålet.

0

Del dette innlegget


Lenke til innlegg
Del på andre sider

Skrevet

så spørsmålet er vel egentlig int[] tab = {1,2,3,4} , hva gjør den? er det et objekt type? int type? eller hva?
I Java (som jeg antar at du holder på med siden alt det andre har handlet om det :) ) så får du et objekt, altså en referansetype. Innholdet i en array er som du sier bare en adresse til hvor den finner dataene, samt noko attåt som du ikke har direkte bruk for.

Når du så sender en array variabel inn til en metode så blir adressen til arrayen kopieres inn i metoden din. Men kun adressen, ikke dataene som adressen refererer til. Du kan dermed, fra metoden, manipulere dataene som ligger i arrayen (som adressen peker på). Dette er et velkjent triks for å sende noe data inn til en metode som du vil at metoden din skal forandre på.

int tab[] = {1,2,3,4}; eller int *tab = {1,2,3,4};, legger 4 stk ints i minnet, og lagrer adressen til det første elementet i tab (en peker altså).

tab er en peker, *tab eller tab[] peker til første element i lista. Hvor den peker hen kan påvirkes med offsets, tab[n] peker til element med offset n (første element har offset 0). Det er også mulig å skrive *(tab+n), men jeg er usikker på om det fungerer som ønsket, ettersom n muligens angir offset i antall bytes på denne måten.

* operatoren er en C/C++ sak og finnes ikke i Java. Pekeraritmetikk går dårlig i Java.

*(tab+n) vil kun fungere på en array av char (siden den er en byte). Bruk heller *(tab+n*sizeof(int)) (bytt ut int med den aktuelle datatypen).

0

Del dette innlegget


Lenke til innlegg
Del på andre sider

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å

  • Hvem er aktive   0 medlemmer

    Ingen innloggede medlemmer aktive