L?sningsforslag ukeoppg. 1: 30. aug ? 3. sep (INF1000 - H?st 2010)
Et f?rste m?te med Java (kapittel 1 og 2.1?2.3 i l?reboka, "Rett p? Java" 2. utg.)
M?l
I f?rste terminalstue-time skal du greie ? skrive dine f?rste Java-programer
og f? de til ? fungere. P? timene med tavleundervisning (teoritimene)
f?r du mer informasjon om Java og kurset generelt, og gjennomgang
av noen av disse oppgavene.
Oppgaver til teoritimen
- Det f?rste programet: kap. 1, oppg. 1 (side 23 i
l?reboken)
Lag et program som skriver f?lgende tekst p? skjermen:Rachmaninovs 3. klaverkonsert har et vakkert ?pningstema
Velg selv hvilket navn du vil gi klassen.L?sningsforslag:
Lagre f?lgende programkode i en fil kalt "Rach3.java":class Rach3 { public static void main(String[] args) { System.out.println("Rachmaninovs 3. klaverkonsert har et vakkert ?pningstema"); } }
Kj?reeksempel:> javac Rach3.java > java Rach3 Rachmaninovs 3. klaverkonsert har et vakkert ?pningstema
Tips: Fremgangsm?te for ? lage ditt f?rste program:- Innlogging: Du kan bruke din egen datamaskin eller en maskin p? en
av
?terminalstuene? p? universitetet. For ? logge inn p? terminalstuen trenger du
bare ? skrive ditt
brukernavn
og passord p? velkomstskjermen til maskinen. Hvis du har med deg en
b?rbar pc til UiO kan du koble den til det tr?dl?se nettet ved UiO (klikk p? teksten hvis du ?nsker mer
informasjon).
Hvis du sitter p? en egen pc hjemme sjekk at du har installert en
Java-kompilator f?r du g?r videre ― Mac og Linux kommer som regel med
Java-kompilator, men p? Windows m? du vanligvis
installere kompilatoren selv
(Veiledning kommer...).
- Redigering: Deretter starter du et tekstredigerings-program.
Det finnes mange slike ? velge mellom, for eksempel
Emacs (som finnes
p? Linux-maskinene i terminalstuen) eller TextPad (p?
Windows-maskinene).
Skriv programmet ditt i redigerings-programmet.
Se f?lgdende eksempel for gode tips til
hvordan du kan bygge opp programmet ditt ― det eneste du trenger ? endre
er teksten som st?r i anf?rselstegn!
Lagre programmet
i en fil med riktig filnavn. Filnavnet skal v?re likt
klassenavnet etterfulgt av .java, f.eks.
f?lgende program (fra side 16 i l?reboken) skal lagres med
filnavnet Utskrift.java fordi klassen i programmet heter
Utskrift.
Husk at store og sm? bokstaver har betydning her.
class Utskrift { public static void main(String[] args) { System.out.println("Beethoven komponerte Skjebnesymfonien"); } }
- Kompilering: Videre bruker du et ?kommandovindu?,
ogs? kalt terminalvindu, for ? kompilere programet.
P? Linux-maskinene p? Ifi ?pnes det automatisk et kommandovindu n?r du
logger inn, men du kan ogs? ?pne det ved ? trykke h?yre musknapp og
velge Open Terminal.
P? Mac finner du ogs? kommandovinduet under navnet ?Terminal?.
P? Windows kan du ?pne kommandovinduet ved ? holde inn Windows-tasten
(tasten til venstre for Alt-tasten) mens du trykker bokstaven r, og
s?
skrive cmd (og trykke Enter).
For ? kompilere programmet skriver du p? kommandovinduet kommandoen javac etterfulgt av mellomrom og filnavn, for eksempel:
> javac Utskrift.java
NB! Husk at du ikke skal taste inn ">"-tegnet, dette tegnet kalles prompt og brukes bare for ? angi at det som f?lger er en kommando som skal tastes inn p? kommandovinduet. Promptet du ser p? skjermen avhenger bl.a. av operativsystem, p? Unix (Linux) kan det f.eks. se slik ut: bruker@maskin ~ $
- Debugging:
Hvis kompilatoren oppdager feil i programmet, retter du disse i
tekstredigerings-programmet, lagrer, og kompilerer igjen. Feilmeldingen fra
kompilatoren sier ofte hvor i programmet feilen sannsynligvis ligger, bl.a.
vha. linjenummer. Bruk dette til ? finne feilen, og husk at store og sm?
bokstaver har betydning, b?de i programkoden og filnavnet. Mer info om
kompilering og debugging kan du finne p? side 17-18 i l?reboken, og p?
Terminalvaktenes
hjelpesider.
- Kj?ring: N?r du har rettet skrivefeilene slik at kompilatoren ikke
gir noen feilmelding kan du ?kj?re? programmet ved ?
skrive java Klassenavn p? kommandovinduet,
for eksempel:
> java Utskrift
- Innlogging: Du kan bruke din egen datamaskin eller en maskin p? en
av
?terminalstuene? p? universitetet. For ? logge inn p? terminalstuen trenger du
bare ? skrive ditt
brukernavn
og passord p? velkomstskjermen til maskinen. Hvis du har med deg en
b?rbar pc til UiO kan du koble den til det tr?dl?se nettet ved UiO (klikk p? teksten hvis du ?nsker mer
informasjon).
Hvis du sitter p? en egen pc hjemme sjekk at du har installert en
Java-kompilator f?r du g?r videre ― Mac og Linux kommer som regel med
Java-kompilator, men p? Windows m? du vanligvis
installere kompilatoren selv
(Veiledning kommer...).
Finn feilene i dette programmet:
class Utskrift { public stitac void main(String args) ( System.out.println("Beethoven skrev Skjebnesymfonien") System.out.println("og ?tte andre symfonier.); } }
Det er fem syntaksfeil i programmet:
1. N?kkelordet "static" er stavet feil. 2. Det mangler hakeparenteser ("[]") etter "String" p? linje 2. Denne feilen oppdages ikke av kompilatoren, men av kj?resystemet fordi det er lov ? lage metoder uten "[]" der, bare ikke lov ? bruke de som hoved-main-metoden n?r man kj?rer et program. Kj?resystemet gir ofte litt mer uventede feilmeldinger enn kompilatoren, men disse vil du ogs? etter hvert l?re deg ? kjenne igjen. I dette tilfellet f?r vi f?lgende feilmelding n?r vi pr?ver ? kj?re programmet: java.lang.NoSuchMethodError: main Exception in thread "main" Som vi ser s? betyr feilmeldingen at kj?resystemmet ikke fant noen (riktig skrevet) main-metode. 3. Det st?r vanlig parentes i stedet for kr?llparentes p? slutten av linje 2. 4. Det mangler semikolon p? slutten av linje 3. 5. Avsluttende anf?rselstegn mangler p? linje 4.
Vi ?nsker ? skrive ut f?lgende tekst p? skjermen (med samme pyramideformatering):
a a a a b a a c c a a d f d aLag et Java-program som gj?r dette, ved ? bruke flere utskriftssetninger.
Tips:
Idéen her er ? finne hvor og hvordan man kan legge inn mellomroms-tegn i programmet for ? f? til pyramideformateringen. Senere i kurset, i kapittel 3 (side 52) vil du l?re en annen m?te ? l?se denne oppgaven p? hvor Java tar seg av pyramideformateringen.
class Pyramide { public static void main(String[] args) { System.out.println(" a"); // 4 mellomrom f?r ?a? System.out.println(" a a"); // 3 mellomrom f?r ?a a? System.out.println(" a b a"); System.out.println(" a c c a"); System.out.println("a d f d a"); } }
Her er en annen m?te ? programmere dette p?, som gir samme resultat.
"\n" (bakover-skr?strek etterfulgt av n) er koden for linjeskift i Java.
class Pyramide { public static void main(String[] args) { System.out.println(" a\n" + " a a\n" + " a b a\n" + " a c c a\n" + "a d f d a"); } }
Kj?reeksempel: (Begge programmene ovenfor gir samme resultat)
> javac Pyramide.java > java Pyramide a a a a b a a c c a a d f d a
Skriv et program som beregner arealet av rektanglene med disse sidest?rrelsene: 3 og 5, 7 og 3, samt 4 og 9, og som skriver ut resultatet med en passende fortekst. Kompier og kj?r programmet.
Tips:
Denne kan l?ses ved ? f?lge oppskriften fra programmet p? side 30 og skrive et lignende program, men med litt andre variabelnavn og beregninger.
class Rektangel { public static void main(String[] args) { int bredde; int lengde; int areal; bredde = 3; lengde = 5; areal = lengde * bredde; System.out.println("Areal av et rektangel med bredde " + bredde + " og lengde " + lengde + " er " + areal); bredde = 7; lengde = 3; areal = lengde * bredde; System.out.println("Areal av et rektangel med bredde " + bredde + " og lengde " + lengde + " er " + areal); bredde = 4; lengde = 9; areal = lengde * bredde; System.out.println("Areal av et rektangel med bredde " + bredde + " og lengde " + lengde + " er " + areal); } } Kj?reeksempel: > java Rektangel Areal av et rektangel med bredde 3 og lengde 5 er 15 Areal av et rektangel med bredde 7 og lengde 3 er 21 Areal av et rektangel med bredde 4 og lengde 9 er 36
Finn feilene i dette programmet:
class Volum { public static void main (String[] args) { integer lengde, bredde, h?yde; lengde = 3; volum = lengde * bredde * h?yde; System.out.println("Volumet er: " + volum); } }
linje 3: - heltallstypen heter "int", ikke "integer". linje 5: - "volum" er ikke deklarert. - "bredde" er ikke initialisert. - "h?yde" er heller ikke initialisert.
Disse feilene kan fikses ved ? endre linje 3-5 til f.eks.:
int lengde, bredde = 1, h?yde = 2; lengde = 3; int volum = lengde * bredde * h?yde;
Hva betyr f?lgende feilmeldinger, som kompilatoren spytter ut n?r vi pr?ver ? kompilere og debugge dette programmet:
1 class Test { 2 public static void main(String[] args) { 3 int jens; 4 int siv = Jens * 3; 5 System.out.println("Svar: " siv); 6 erna = siv - jens; 7 System.out.printn(erna); 8 }
a. Test.java:8: reached end of file while parsing } ^ b. Test.java:4: cannot find symbol symbol : variable Jens location: class Test int siv = Jens * 3; ^ c. Test.java:4: variable Jens might not have been initialized int siv = Jens * 3; ^ d. Test.java:5: ')' expected System.out.println("Svar: " siv); ^ Test.java:5: illegal start of expression System.out.println("Svar: " siv); ^ e. Test.java:6: cannot find symbol symbol : variable erna location: class Test erna = siv - jens; ^ f. Test.java:7: cannot find symbol symbol : method printn(int) location: class java.io.PrintStream System.out.printn(erna); ^
a. Feilmeldingen i a. ovenfor ("reached end of file while parsing") betyr at Java-kompilatoren kom til slutten av filen men likevel ikke fant avslutning av elementene den holdt p? ? kompilere. I dette tilfellet er det en kr?llparentes som ikke var avsluttet, fordi som du ser er det to ?pnings-kr?llparenteser ("{") i programmet, men bare én avslutnings-kr?llparentes ("}"). Denne feilen retter vi ved ? legge til en avslutnings-kr?llparentes ("}") til slutt i filen. b. "Cannot find symbol" er den vanligste feilmeldingen i Java, og betyr at noe ikke er deklarert. I dette tilfellet viser feilmeldingen at variabelen "Jens" med stor "J" ikke er deklarert i programmet. Denne feilmeldingen f?r man s? ofte at det er lurt ? l?re seg ? lese alle detaljer i feilmeldingen. F?rste linje i feilmeldingen angir hvilken linje i programet Java-kompilatoren oppdaget feilen i, i dette tilfellet ser vi at det er linje 4 (fordi det st?r Test.java:4 i feilmeldingen). Neste linje i feilmeldingsteksten sier hva som ikke var deklarert, i dette tilfellet ser vi at det er "variabelen Jens". Og de siste 3 linjene i feilmeldingen angir n?yaktig hvor i koden det udeklarerte symbolet er fors?kt brukt. I dette tilfellet ser vi at det er i klassen Test, og akkurat der identifikatoren "Jens" st?r (se det lille hatt-tegnet "^" under Jens). Denne feilen retter vi ved ? endre variabelnavnet til "jens" med liten "j" p? linje 4, slik at navnet blir likt med navnet vi deklarerte variabelen med p? linje 3 (int jens;). c. Feilmeldingen "variable Jens might not have been initialized" betyr at Java-kompilatoren mener vi b?r gi en startverdi til variabelen Jens. Dette fikser vi ved ? endre linje 3 til f.eks.: (husk ogs? at vi endret variabelnavnet til "jens" med liten "j") int jens = 1; d. ") expected" betyr at Java-kompilatoren fant noe uventet i koden p? et sted der det hadde passet bedre med en ")"-parentes. Legg merke til hvor "hatten" ("^") er plassert i feilmeldingen. Unders?ker vi n?rmere det stedet i linjen, s? skj?nner vi fort at det skulle st?tt en "+" der, s? vi korrigerer linje 5 til: System.out.println("Svar: " + siv); e. Et annet eksempel p? "cannot find symbol". Som vi s? i punkt b. over s? betyr denne feilmeldingen at et symbol (angitt p? linje 2 i feilmeldingen) ikke er deklarert. Videre ser vi at sombolet som ikke er deklarert er "variable erna". Da vet vi at l?sningen er ? deklarer typen til erna, f.eks. ved ? legge til n?kkelordet "int" foran p? linjen: int erna = siv - jens; f. En annen vri p? "cannot find symbol". Denne gangen ser vi at det er symbolet "method printn(int)" som ikke er deklarert. Ser vi n?ye p? hvor "hatten" peker n?, s? skj?nner vi raskt at det er en stavefeil i metodenavnet println. Vi fikser det ved ? endre "printn" til "println" p? linje 7: System.out.println(erna);Hvis vi fjerner "{"-kr?llparentesen p? linje 2 f?r vi ca. 10 nye feilmeldinger, bl.a. f?lgende. Hva tipper du er grunnen til at s? mange feilmeldinger for?rsakes av bare denne enkle lille feilen?
g. Test.java:2: ';' expected public static void main(String[] args) ^ Test.java:5: <identifier> expected System.out.println("Svar: " + siv); ^ Test.java:5: illegal start of type System.out.println("Svar: " + siv); ^
g. Problemet er at n?r vi tar bort "{"-kr?llparentesen, s? har vi tatt bort angivelsen av at kroppen til metoden main startet der (fordi innmaten til alle metoder m? starte med "{" i Java). Dermed g?r kompilatoren i surr og skj?nner ikke noe av det som kommer etterp?. Den venter seg bare deklarasjoner, som er det eneste som kan st? utenfor metoder, og gir feilmelding for alle andre typer setninger (de som ikke er deklarasjoner).
Hvilke av disse programsetningene er lovlige, og for de som er lovlige: hvilken verdi f?r variabelen? Du kan i hvert av punktene regne med at variablen som deklareres ikke er deklarert tidligere i programmet.
(a) int x = 4; // lovlig, x f?r verdien 4. (b) int x = 4.56; // ikke lovlig, tap av informasjon. (c) int x = (int) 4.56; // lovlig, x f?r verdien 4. (d) int z = 1/2; // lovlig, z f?r verdien 0. (e) double x = 5.7723; // lovlig, x f?r verdien 5.7723. (f) double a = (int) 5.7723; // lovlig, a f?r verdien 5. (g) double x = 6; // lovlig, x f?r verdien 6. (h) double tall = true; // ikke lovlig, true er ikke en double. (i) char c = "hei p? deg"; // ikke lovlig, en char-variabel kan ikke inneholde en tekst. (j) char c = "&"; // ikke lovlig, "&" er en tekst. (k) char c = '&'; // lovlig, c f?r verdien &. (l) boolean a = sann; // ikke lovlig, "sann" er ikke en boolsk verdi. (m) boolean verdi = true && false; // lovlig, verdi f?r verdien false. (n) boolean a = (true == true); // lovlig, a f?r verdien true. (o) boolean a = (false == false); // lovlig, a f?r verdien true. (p) boolean a = (a == a); // ikke lovlig, a er ikke definert p? h?yre side av likhetstegnet. (q) String t = 'hei p? deg'; // ikke lovlig, tekst skal angis i doble anf?rsel. (r) String t = "hei p? deg"; // lovlig, t f?r verdien "hei p? deg". (s) String t = "" + 7.33; // lovlig, t f?r verdien "7.33" (som tekst). (t) String tekst = 7.33; // ikke lovlig, 7.33 er ikke en String, men en double.
Avgj?r i hvert av disse tilfellene, uten ? bruke datamaskin, hvilken verdi som blir skrevet ut p? skjermen. Husk at reglene for divisjon i Java avhenger av om vi jobber med heltall eller flyttall (=desimaltall) (se side 36-37 i l?reboka).
1. System.out.println(10 / 9); // 1 2. System.out.println(10 / 10); // 1 3. System.out.println(10 / 11); // 0 4. System.out.println((int) 3.65); // 3 5. System.out.println((int) 3.65 - 4); // -1 6. System.out.println((int) (3.65 - 4)); // 0 7. System.out.println(Math.round(3.65)); // 4 8. System.out.println(1 / 2); // 0 9. System.out.println(1 / 2.0); // 0.5 10. System.out.println(1.0 / 2); // 0.5 11. System.out.println((double) 1 / 2); // 0.5 12. System.out.println((double) (1 / 2)); // 0.0 13. System.out.println(73 / 10); // 7 14. System.out.println(73 % 10); // 3
Oppgaver til terminaltimen
- Det f?rste programet: kap. 1, oppg. 1 (side 23 i
l?reboken)
(Se punkt 1. ovenfor) - Kompilerings- vs. kj?refeil: kap. 1, oppg. 2 (side 23)
Med utgangspunkt i programmet nedenfor skal du utf?re de angitte endringene en for en. Pr?v f?rst ? kompilere programmet og studér eventuelle feilmeldinger. Dersom programmet lar seg kompilere, s? fors?k ? kj?re det. For hvert fors?k skal du rette programmet tilbake til utgangspunktet og kontrollere at det virker. Her er programmet (som skrives inn i en fil med navnet Studie.java):class Studie { public static void main(String[] args) { System.out.println("Rett p? Java"); } }
- Fjern ordet static.
- Fjern ordet void.
- Skriv studie i stedet for Studie.
- Skriv Skr?tt i stedet for Rett.
- Fjern den siste kr?llparentesen.
a. Uten n?kkelordet 'static' f?r vi denne feilmeldingen ved kj?ring: > javac Studie.java > java Studie.java Exception in thread "main" java.lang.NoSuchMethodError: main Programmet lar seg kompilere (med kommandoen javac), men alts? ikke kj?re (med java) fordi det mangler en main-metode av riktig type. b. N?r vi fjerner n?kkelordet 'void' gir javac feilmeldingen: > javac Studie.java Studie.java:2: invalid method declaration; return type required public static main(String[] args) { ^ Programmet lar seg ikke kompilere fordi Java krever at alle metodene i et program (main er en s?kalt "metode", som vi skal se i kapittel 7) deklareres med en returtype. Returtypen "void" angir at main-metoden ikke skal "returnere" noen verdi, og m? angis som returtypen til main. Mer om dette i avsnitt 7.5 i l?reboka. c. Programmet lar seg kompilere, men ikke kj?re fordi klassen har feil navn. Ved kj?ring f?r vi en veldig kryptisk feilmelding, som alts? betyr at filnavn ikke stemmer med klassenavn: java.lang.NoClassDefFoundError: Studie (wrong name: studie) at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(Unknown Source) ... Exception in thread "main" d. Programmet lar seg b?de kompilere og kj?re. Resultatet er bare en litt annen utskrift enn f?r. e. Ved kompilering f?r vi f?lgende feilmelding: Studie.java:4: reached end of file while parsing } ^ Denne feilmeldingen betyr alts? at vi har glemt ? avslutte en kr?llparentes i programmet.
- Enkel formatering av utskrift: kap. 1, oppg. 5 (side
24)
(Oppgaveteksten st?r i punkt 3. ovenfor) - Areal av rektangler: kap. 2, oppg. 1 (side 43)
(Oppgaveteksten st?r i punkt 4. ovenfor) - Typiske feilmeldinger:
(Oppgaveteksten st?r i punkt 6. ovenfor). Korrigér feilene slik at programmet kompilerer. - Lovlig eller ikke? kap. 2, oppg. 5 (side 44)
(Oppgaveteksten st?r i punkt 7. ovenfor) -
Hvis du har enda mer tid kan du ogs? begynne ? titte litt p? noen av disse
kildene med nyttig informasjon. Det er bare de 2 f?rste som er viktigst,
men spesielt interesserte kan fortsette nedover i lista og finne enda
mer informasjon.
- Kursets hjemmeside: ifi.uio.no/inf1000/h10 er din viktigste kilde til informasjon om kurset. Du b?r bli godt kjent med denne websiden, og f?lge med p? beskjedene som publiseres der (s?rlig i forbindelse med de 4 obligatoriske oppgavene). Kurshjemmesiden har (eller vil snart f?) lenker til forelesningsnotater, obliger, ukeoppgaver, Innleveringssystemet, Godkjentsystemet wwws, og Bloggen.
- Webmail: webmail.uio.no Her finner du din e-post-konto p? universitetet. Denne b?r du sjekke regelmessig, eller evt. sette opp automatisk videresending av mailene dine til en annen e-post-adresse (se ?UiO-instillinger? n?r du er inne i systemet). Du kan bruke som e-post adresse: brukernavn@ulrik.uio.no
- IfiDVD: ifi.uio.no/ifidvd Finnes b?de p? nettet og som fysisk plate du kan f? gratis (p? gruppene eller Ifi-ekspedisjonen). Denne DVD-ROM-platen inneholder mye nyttig programvare du kan installere i din egen datamaskin.
- Terminalvaktenes hjelpesider: termvakt.uio.no har info om terminalstuene; programvare tilgjengelig i disse, bl.a. en Enkel innf?ring i Emacs og Unix/Linux; og mye mer.
- Oracles offisielle websider om Java: Her finner du bl.a. siste versjon av Java (for tiden JDK 6 Update 16), og mye dokumentasjon, f.eks. om API og en tutorial.
- L?rebokens hjemmeside: Har bl.a. l?sningsforslag til noen av oppgavene i boken, og lenke til en veiledning om hvordan du kan installere Java og easyIO p? egen Windows-pc (men noen av disse lenkene er utdatert, vi skal legge ut oppdaterte veiledninger p? INF1000-websidene).
- Forkurs i informatikk: Har forelesningsnotater og lab-oppgaver om Linux, Emacs, og Java fra forkurset som foregikk 18. - 20. aug 2010. Der finner du ogs? lenker til mer informasjon om Emacs, og om hvordan du kan koble deg til UiO hjemmefra eller overf?re filer.
- Wikipedia: Har mye nyttig informasjon om Java og relaterte teknologier, og mye mer!
- Google: Hvis du ikke skj?nner en feilmelding fra kompilatoren kan du lime inn feilmeldingen i s?kefeltet til Google og finne hjelp!
- Gruppel?rer: Du kan alltid sende mail til din gruppel?rer hvis du har sp?rsm?l, kommentarer, e.l.
Tibakemelding om dette oppgavesettet kan du skrive i bloggen eller sende p? mail til josek [a] ifi.uio.no