Osaako joku kertoa miksi tulee seuraavassa koodissa koko ajan ajonaikainen virhe ja keskeytyy?
#include <iostream> using namespace std; int main() { int luvut[31]; int paiva; double keskiarvo,summa = 0; cout<< "Ohjelma laskee yhteen haluamasi ajanjakson aikana tehdyt \n"; cout<< "työtunnit sekä keskimääräisen työpäivän pituuden. \n"; cout<< "Kuinka monta päivää:"; cin>> paiva; for(int i = 1; i <= paiva; i++) { cout << "Anna " << i << ". päivän työtunnit: "<< endl; cin>>luvut[i]; summa=summa+luvut[i]; } keskiarvo = summa/paiva; cout << "Tehdyt tunnit yhteensä: "<< summa << endl; cout<< "Keskimääräinen työpäivän pituus: "<< keskiarvo << endl; for( i = 1; i <= paiva ; i++) { cout <<"Syötetyt tunnit " << luvut[i] << endl; } }
Käänsin ja ajoin tuon, mitään ajonaikaista virhettä ei tapahtunut.
Lisäys: PS. Aloitathan indeksoinnin aina kummiskin nollasta etkä ykkösestä.
Taulukon alkioiden numerointi alkaa siis nollasta. Jos taulukossa on 10 alkiota, ensimmäisen indeksi on 0 ja viimeisen indeksi on 9. Indeksin 10 kohdalle ei saa missään tapauksessa tallentaa, sillä sen osoittama muistipaikka ei kuulu taulukkoon, vaan siihen kohtaan saattaa esimerkiksi olla tallennettuna jokin toinen ohjelmassa käytettävä muuttuja. Kääntäjä ei valitettavasti huomaa tällaista virhettä.
Nyt jos annat päivien määräksi 30 niin ohjelmasi yrittää kirjoittaa luvut[30]:seen, mikä viittaa taulukon 31. alkioon, joka on varatun alueen ulkopuolella.
Edellä mainitun lisäksi ohjelmassa on sellainen virhe, että main-funktiossa oleva return-rivi lopettaa ohjelman kesken ja palauttaa käyttöjärjestelmälle virhekoodin. Et myöskään lue käyttäjältä työtunteja, joten ohjelman laskema tulos on tuurista kiinni.
En ole vieläkään tajunnut missä on virhe.
Tässä on tulostus jonka antaa:
Ohjelma laskee yhteen haluamasi ajanjakson aikana tehdyt
työtunnit sekä keskimääräisen työpäivän pituuden.
Kuinka monta päivää: 5
Anna 1. päivän työtunnit:
5.3
Anna 2. päivän työtunnit:
Anna 3. päivän työtunnit:
Anna 4. päivän työtunnit:
Anna 5. päivän työtunnit:
Tehdyt tunnit yhteensä: -2.28745e+09
Keskimääräinen työpäivän pituus: -4.5749e+08
Syötetyt tunnit 5 -1211613108 134519820 0 -1210355724 #
Nykyisellä koodillasi (ilmoitathan, jos muutat sitä) tulee ensin käännösvirhe g++:lla:
32:10: virhe: name lookup of ”i” changed for ISO ”for” scoping [-fpermissive]
Lisään kyseiselle riville i:n eteen "int", jonka jälkeen ohjelmasi toimii hienosti:
Ohjelma laskee yhteen haluamasi ajanjakson aikana tehdyt työtunnit sekä keskimääräisen työpäivän pituuden. Kuinka monta päivää:3 Anna 1. päivän työtunnit: 8 Anna 2. päivän työtunnit: 7 Anna 3. päivän työtunnit: 6 Tehdyt tunnit yhteensä: 21 Keskimääräinen työpäivän pituus: 7 Syötetyt tunnit 8 Syötetyt tunnit 7 Syötetyt tunnit 6
Huoimoi, että luvut-taulukko on int-tyyppinen; esimerkissäsi annat 1. päivän työtunneiksi liukuluvun. Kun muutin myös luvut-taulukon double-tyyppiseksi, toimii ohjelmasi jälleen oikein hienosti:
Ohjelma laskee yhteen haluamasi ajanjakson aikana tehdyt työtunnit sekä keskimääräisen työpäivän pituuden. Kuinka monta päivää:2 Anna 1. päivän työtunnit: 0 Anna 2. päivän työtunnit: 0.5 Tehdyt tunnit yhteensä: 0.5 Keskimääräinen työpäivän pituus: 0.25 Syötetyt tunnit 0 Syötetyt tunnit 0.5
Kuinka monta päivää:5 Anna 1. päivän työtunnit: 5.3 Anna 2. päivän työtunnit: 4 Anna 3. päivän työtunnit: 8 Anna 4. päivän työtunnit: 6 Anna 5. päivän työtunnit: 3 Tehdyt tunnit yhteensä: 26.3 Keskimääräinen työpäivän pituus: 5.26 Syötetyt tunnit 5.3 Syötetyt tunnit 4 Syötetyt tunnit 8 Syötetyt tunnit 6 Syötetyt tunnit 3
Enpä tullut ajatelleeksikaan, että taulukon tyypityksessä olisi virhe.
Mitä tekisinkään ilman tätä foorumia?
En tajua miksi eka tulostus menee oikein ja toinen väärin?
Viope on todella surkea opettelu ympäristö ohjelmointii.
Tulostus:
# ./a.out
Syötä ensimmäinen kokonaisluku: 1
Syötä toinen kokonaisluku: 2
Syötä kolmas kokonaisluku: 3
Syöttämistäsi luvuista suurin oli 3 ja pienin 1.
#
# ./a.out
Syötä ensimmäinen kokonaisluku: 5
Syötä toinen kokonaisluku: 32
Syötä kolmas kokonaisluku: 22
Syöttämistäsi luvuista suurin oli 22 ja pienin 5.
#include <iostream> using namespace std; int suurin(int eka, int toka, int kolmas); int pienin(int eka, int toka, int kolmas); int main() { int luku1, luku2, luku3, suurinLuku, pieninLuku; cout << "Syötä ensimmäinen kokonaisluku:"; cin >> luku1; cout << "Syötä toinen kokonaisluku:"; cin >> luku2; cout << "Syötä kolmas kokonaisluku:"; cin >> luku3; suurinLuku = suurin(luku1, luku2, luku3); pieninLuku = pienin(luku1, luku2, luku3); cout << "Syöttämistäsi luvuista suurin oli " << suurinLuku; cout << " ja pienin " << pieninLuku << "." << endl; int suurin(int eka, int toka, int kolmas) { int yksi, kaksi, kolme; if(yksi>kaksi && kolme) { return yksi; } else if(kaksi>yksi && kolme) { return kaksi; } else //(kolme> yksi && kaksi) { return kolme; } } int pienin(int eka, int toka, int kolmas) { //int luku1, luku2, luku3; if(eka < toka && kolmas) { return eka; } if(toka < eka && kolmas) { return toka; } if(kolmas < eka && toka) { return kolmas; } }
Aivan ensimmäinen virhe on, että suurin-funktion sisällä määrittelet uudet muuttujat etkä käytä parametreja ollenkaan.
Toinen vika on, että olet ymmärtänyt &&-operaattorin käytön väärin. Lausekkeen ”yksi > kaksi && kolme” ensimmäinen osa on ”yksi > kaksi” ja toinen osa on mystisesti vain ”kolme”. Jotta saisit myös kolmatta lukua vertailtua johonkin, sinun pitää kirjoittaa sille ihan oma vertailu, esimerkiksi siis ”yksi > kaksi && yksi > kolme”.
Koodisi on myös kolmannella tavalla väärin: esimerkiksi lukujen ollessa 2, 2 ja 1 suurin-funktio tuottaa väärän tuloksen (1), ja luvuilla 1, 1 ja 1 taas pienin-funktio ei tuota mitään tulosta eli voi tuottaa oikeastaan minkä tahansa väärän tuloksen. Sinun pitäisi käyttää yhtäsuuruuden sisältäviä vertailuja >= ja <=.
Lisäksi olet ilmeisesti säheltänyt jotain koodin kopioinnin yhteydessä, nimittäin main-funktion lopusta puuttuu }-merkki.
Alkaja kirjoitti:
Viope on todella surkea opettelu ympäristö ohjelmointii.
Veikkaan, että suurin vika on kyllä lukijassa eikä Viopessa: ei mikään oppimisympäristö osaa kertoa, miksi koodisi toimii väärin, ja kai sinulla on joka tapauksessa jotain oppimateriaalia, josta ne asiat pitäisi opetella jo ennen koodin kirjoittamista. Jos kuitenkin olet sitä mieltä, että materiaali on huonoa, mikset lue sen sijaan vaikka tämän sivuston C- ja C++-oppaita?
Jatkossa tee uudesta kysymyksestä uusi aihe, jolla on järkevä otsikko. Siirrän nämä viestit myöhemmin.
Aihe on jo aika vanha, joten et voi enää vastata siihen.