Računalništvo 1 (FMF)/Študentska vprašanja

Iz MaFiRaWiki

Tu zbiramo vprašanja o snovi in domačih nalogah. Če se v wiki ne prijavite, lahko vprašanje zastavite tudi anonimno. Na vprašanje lahko odgovori kdorkoli, ne samo predavatelj in asistent. Pri vprašanjih sledite vzorcu, po katerem so oblikovana ostala vprašanja.


Vsebina

V čem je smisel metod?

Mene pa zanima, zakaj sploh delamo metode, ker mi ni nič jasno.

Odgovor: Primaren namen metod (poleg omogočanja naprednejšega programiranja) je večja urejenost programa ter lažje nadgrajevanje. Že zelo osnovna metoda "public class void izpisi", ki dobi kot argument tabelo, ki jo nato izpiše, nam lahko olajša delo, saj bo ob vsakem izpisovanju dovolj poklicati to metodo ter ne bo potrebno konstanto pisati zanke for. Kakor hitro postane program bolj zapleten bo tak način programiranja olajšal iskanje napak ter dodajanje novih testnih primerov.


Hornerjev algoritem

Nisem razumel asistenta, ko je pojasnil Hornerjev algoritem. Kaj je to?

Odgovor: Glej Hornerjev algoritem. Poanta je v tem, da ni treba posebej računati potenc, tako da si prihranimo nekaj nepotrenih množenj. AndrejBauer 23:47, 22 november 2006 (CET)


Metoda main in razredi

Zakaj moramo za testiranje razreda napisati Test.java? Ali se metode main ne da napisati znotraj datoteke Datum.java (naprimer)?

Odgovor: To je samo stvar dobrega programiranja. Načeloma bi lahko zatlačili metodo main v Datum.java. Glavna slabost je, da Datum.java ni namenjen testiranju, ampak je to samo eden od razredov, ki bi lahko bili del večjega programa. Kmalu bomo imeli opravka s programi, ki so sestavljeni iz treh ali štirih razredov. Če bi imel vsak od teh razredov metodo "main", s katero preizkusimo delovanje, bi nastala dokaj velika zmeda, saj ne bi bilo jasno, katera od vseh "main" metod je tista, ki šteje kot glavni program.

Morda se komu zdi, da je "bolj preprosto" vtakniti metodo main kar v originalni razred. To je morda res na kratek rok. Na dolgi rok pa je bolje, če razred ne vsebuje nepotrebne navlake, ki je tam samo zato, da programer vidi, ali razred pravilno deluje. To poveča organiziranost vaših programov. In pomembna reč pri pouku računalništva je, kako pisati programe organizirano.

Naj še omenim, da je za preprosto testiranje bolj praktično, da metodo preizkusite kar iz ukazne vrstice v Drjava. Za domačo nalogo pa je seveda potrebno napisati testni program, da ga lahko oddate. AndrejBauer 17:59, 24 november 2006 (CET)


Kako učinkovito iskati napake?

Kadar napišem program in se mi ta prevede, potem pa ob zagonu ne dela ne vem kako odpraviti napako. Piše mi sicer vrstice kjer se napaka pojavi, vendar ne razumem kaj je narobe. Ali obstaja kakšen seznam pogostih napak in kaj pomenijo?

Odgovor: Tak seznam bi bil dobrodošel. Predlagam, da zbiramo napake wikiju. Zaenkrat jih postavljajte kar med ta vprašanja, jaz bom iz njih delal ustrezno stran. Pri vsaki napaki objavite natančno sporočilo, ki ste ga dobili in tudi relevantni del izvorne kode. Sicer pa je odpravljanje napak ena izmed veščin, ki se jo mora naučiti programer. AndrejBauer 23:38, 25 november 2006 (CET)


Napaka NullPointerException

Pogosta napaka, ki se zgodi, je NullPointerException. Pomeni, da smo na nedefiniranem objektu null poklicali metodo ali dostopali do komponente. Primer:

> String s = null;
> s.length()
NullPointerException: 
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
  at java.lang.reflect.Method.invoke(Method.java:585)

Včasih je težko razumeti, zakaj je objekt nedefiniran. Primer iz nedavne domače naloge, iz razreda Polinom.java:

  1. public Polinom zmnozek(Polinom q) {
  2. Ulomek[] z = new Ulomek[t.length + q.t.length - 1];
  3. for(int i = 0; i < (t.length + q.t.length - 1); ++i) {
  4. for (int j = 0; j <= i; ++j) {
  5. if (j > (t.length - 1) || i - j > (q.t.length - 1)) continue;
  6. else {
  7. t[j].zmnozi(q.t[i - j]);
  8. z[i].pristej(t[j]);
  9. }
  10. }
  11. }
  12. Polinom w = new Polinom(z);
  13. return w;
  14. }

Ko preizkusimo metodo zmnozek, ta javi napako NullPointerException v vrstici 8, ki se glasi

              z[i].pristej(t[j]);

Tu na objektu z[i] kličemo metodo pristej. Zakaj je z[i] nedefiniran objekt? Tabelo z ustvarimo v vrstici 2, tako da se zdi, da je so elementi nove tabele nedefinirani. In res, če naredite tabelo objektov, bodo vrednosti v tabeli nastavljene na null:

> String[] t = new String[10];
> t[5]
null

Napako odpravimo tako, da nastavimo vrednost z[i], preden na njem prvič pokličemo metodo. To se najbolje naredi takoj za vrstico 2, kamor dodamo

 z[i] = new Ulomek(0,1);

Hmm, tole bi bilo dobro dati na samostojno stran o NullPointerException. AndrejBauer 10:42, 26 november 2006 (CET)


Metoda toString v razredu Polinom

Mene pa zanima, kako se naredi metoda String pri domaci nalogi Polinom. ne znam sestavit polinoma iz ulomkov.

Odgovor: Šele zdaj sem opazil tole vprašanje, čeprav imam vklopljen nadzor nad to stranjo. Treba bi bilo nekaj narediti, da bomo bolj ažurno odkrivali nova vprašanja. Sicer pa lahko odgovori kdorkoli, ki pač vidi vprašanje.

Najprej pripomba na samo vprašanje (povsem dobronamerna): če ne znaš prav postaviti vprašanja, tudi pravega odgovora verjetno ne boš dobil. V konkretnem primeru:

  • Metoda se ne imenuje String ampak toString. Tisti, ki bo odgovarjal, mora torej uganiti, kaj res sprasuješ.
  • Fraza "ne znam sestavit polinoma iz ulomkov" ne opisuje zadosti, kaj je tisto, česar ne znaš. Tako sem v dilemi: če ti pokažem rešitev, se ne boš ničesar naučil. Če ti ne pokažem celotne rešitve, kako naj odgovorim? Kadar imate programersko vprašanje, vedno zraven dodajte kodo, ki ste jo napisali sami (tudi če ne deluje), ker bom lahko tako uganil, kaj se mota po vaših glavah.

Tako, zdaj pa odgovor po mojih najboljših močeh, glede na dano informacijo:

  1. rezultat računamo v spremenljivko String r, ki ima na začetku vrednost "".
  2. gremo čez tabelo koeficientov polinoma in po vrsti dodajamo v r nize oblike "7/2 x^3" (to je primer, da je koeficient pri x^3 enak 7/3), ločimo jih z znaki "+".
  3. ulomek spremenimo v niz z metodo toString. Npr., če je tabela koeficientov a in želimo prikazati ulomek pri x^i z nizom, napišemo a[i].toString(). Sicer pa se ulomek samodejno pretvori v niz, če ga staknemo skupaj z nizom.
  4. mogoče pa nisi pravilno implementiral razreda Ulomek in sedaj nimaš metode toString v razredu Ulomek.

AndrejBauer 22:53, 3 december 2006 (CET)


Stik seznamov

Znaima me, kaj pomeni stik seznamov? da npr seznam t das na konec seznama? kaksna je potem razlika med metodama pritakni in stakni, ki smo jih delali na vajah?


Napake

Ko hocem prevesti program Seznam (program, ki smo ga delali na vajah) mi java javi napako in sicer izpise: Note: Seznam.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details.

Kaj to pomeni?


Prevajalnik ti ni javil napake, ampak je izpisal opozorilo. V kodi so namreč operacije, ki so morebiti problematične. Najbolj pogoste morebiti problematične operacije so operacije, pri katerih spreminjamo tipe objektov. Običajno ni nič narobe, če taka sporočila kar ignoriramo. Namreč prevajalnik je opravil svoje delo in izdelal class datoteko, ki jo lahko uporabljamo. --Matija Lokar 13:15, 12 februar 2007 (CET)

Osebna orodja