Eli C-kielen ohjelmoinnin tentissä oli seuraavanlainen kysymys:
Kirjoita funktio, joka saa parametreinaan suorakulmion sivujen pituudet. Funktio laskee annetun suorakulmion pinta-alan ja palauttaa sen kutsujalle. Huom., kutsuvaa ohjelmaa ei tarvitse tehdä.
Vastasin siihen näin:
int main(void) { /* Alustetaan aluksi vain nollaksi, kun ei tiedetä oikeaa arvoa */ float ala = 0; float leveys = 2.5; float pituus = 4.0; /* Lasketaan alalle oikea arvo */ ala = leveys * pituus; /* Tulostetaan luvut yhden desimaalin tarkkuudella */ printf("Suorakumion pinta-ala on %.1f \n", ala); return 0; }
Vastasinko oikein, vai olenko ymmärtänyt tehtävänannon kokonaan väärin?
Mod. lisäsi kooditagit
Kutsuvaa ohjelmaahan ei ollut tarkoitus tehdä vai kuinka? Olet nyt tehnyt kuitenkin pääohjelman, muttet itse funktiota, joka tehtävässä pyydettiin.
Käytä toki kooditageja avuksesi, helpottaa lukemista huomattavasti.
Mielestäni olet ymmärtänyt tehtävänannon hieman väärin. Mielestäni oikea vastaus olisi:
float Ala(float leveys, float pituus) { return leveys*pituus; }
Grez kirjoitti:
Mielestäni olet ymmärtänyt tehtävänannon hieman väärin. Mielestäni oikea vastaus olisi:
float Ala(float leveys, float pituus) { return leveys*pituus; }
Saisiko muilta vielä mielipiteitä kuitenkin oikeasta vastauksesta kiitos :)
Eipä tuohon oikein muuta mielipidettä irtoa, koska Grez:n vastaus hipoo täydellisyyttä.
Grezin vastaus on oikein. Aloittaja ei tainnut ymmärtää, mitä funktion parametreilla ja arvon palauttamisella tarkoitetaan.
Tehtävänannossa sanotaan että funktio saa parametreinä sivujen pituudet, sinun funktio ei ota parametrejä vastaan. Ja _Palauttaa_ kutsuvalle funktiolle, eikä _Tulosta_ lopputuloksena saatavaa alaa, sinun funktio tulostaa ja Grezin funktio palauttaa alan.
Asiapa selvä, aloittelija ei voi aina tietää :D Kiitos paljon!
Vielä jos jollakin on ylimääräistä aikaa niin olisi kiva saada vastaus myös seuraavaan tehtävään:
KIRJOITA FUNKTIOLLE PÄÄOHJELMA, JOSSA PYYDETÄÄN SUORAKULMION SIVUJEN PITUUDET. OHJELMASSA LASKETAAN SUORAKULMION PINTA-ALA KÄYTTÄEN HYVÄKSI EDELLISEN FUNKTIOTA. LASKTTU PINTA-ALA TULOSTETAAN PÄÄOHJELMASSA.
pekkk kirjoitti:
Asiapa selvä, aloittelija ei voi aina tietää :D Kiitos paljon!
Vielä jos jollakin on ylimääräistä aikaa niin olisi kiva saada vastaus myös seuraavaan tehtävään:
KIRJOITA FUNKTIOLLE PÄÄOHJELMA, JOSSA PYYDETÄÄN SUORAKULMION SIVUJEN PITUUDET. OHJELMASSA LASKETAAN SUORAKULMION PINTA-ALA KÄYTTÄEN HYVÄKSI EDELLISEN FUNKTIOTA. LASKTTU PINTA-ALA TULOSTETAAN PÄÄOHJELMASSA.
Ei tarvitse huutaa, mutta tähän olet jo vastannut ekassa viestissäsi, kunhan vain kutsut siinä vaikka tuota Grezin tekemää funktiota.
Teuro.. Lisäsi siihen täytyy tietenkin tehdä tuo kyselyrutiini. Alkuperäisessä esimerkissähän mitat oli kovakoodattu.
Kappas siinähän vain tulostettiin alustetut arvot. Hanki teuro lasit.
int main(void) { float Ala(float leveys, float pituus) printf("Anna pituus: "); scanf("%f", &pituus); printf("Anna leveys: "); scanf("%f", &leveys); ala = pituus*leveys; printf("Ala on %.2f \n", ala); return 0; }
Onkohan tämä oikein?
Seuraavassa voi olla virheitä, en testannut sitä mitenkään. Idea kuitenkin selvinnee. (alkuperäisen viestin ohjelmaa muokaten)
float Ala(float leveys, float pituus); int main(void) { float ala, leveys, pituus; printf("Leveys? "); scanf("%f", &leveys); printf("Pituus? "); scanf("%f", &pituus); /* Lasketaan alalle oikea arvo funktiolla */ ala = Ala(leveys, pituus); /* Tulostetaan luvut yhden desimaalin tarkkuudella */ printf("Suorakumion pinta-ala on %.1f \n", ala); return 0; }
Edit: Pekk, olit näköjään nopeampi. Mielestäni omasi on muuten oikein, mutta siinä piti käyttää tehtyä funktiota alan laskemiseen. Tuossahan olit laskenut ihan vaan suoraan kertomalla.
Lisäksi muuttujien esittely puuttui ja siellä oli oudosti ikäänkuin esitelty tuo Ala-funktio ilman puolipistettä. Ulkomuistista sanoisin, että funktioiden esittelyt tehdään funktioiden ulkopuolella (ei siis esim. main-funktion sisällä).
Joskaan en ole C:llä koodannut oikeastaan koskaan, että voin muistaa väärinkin. C++ on varmaan lähimmäs kielistä mitä käytän/olen käyttänyt.
Kiitos taas paljon! :)
Grez kirjoitti:
Lisäksi muuttujien esittely puuttui ja siellä oli oudosti ikäänkuin esitelty tuo Ala-funktio ilman puolipistettä. Ulkomuistista sanoisin, että funktioiden esittelyt tehdään funktioiden ulkopuolella (ei siis esim. main-funktion sisällä).
Mikään ei estä esittelemästä myös funktioita muuttujien tapaan lohkojen sisällä. Niihin pätevät samat säännöt. Ne on esiteltävä lohkojen alussa ennen koodirivejä ja niiden näkyvyysalue rajoittuu kyseisen lohkon sisään. Tosin monet kääntäjät (kuten gcc) sallivat standardin vastaisesti muuttujien ja funktioiden esittelyn keskellä koodiakin. Varoitusten kera tosin.
Tässä esimerkin vuoksi ohjelma kokonaisuudessaan, siten että funktio on esitelty mainin sisällä. Kääntyy gcc:llä kaikki varoitusliput päällä ilman herjauksia ja toimii laillisilla syötteillä oikein.
#include <stdio.h> /* Pääohjelma */ int main(void) { /* Funktioiden ja muuttujien esittely */ double laske_ala(float leveys, float korkeus); float leveys, korkeus; /* Pyydetään käyttäjää syöttämään lähtöarvot */ printf("Anna suorakulmion leveys: "); scanf("%f", &leveys); printf("Anna suorakulmion korkeus: "); scanf("%f", &korkeus); /* Lasketaan ja tulostetaan ala yhden desimaalin tarkkuudella */ printf("Pinta-ala on: %.1f\n", laske_ala(leveys, korkeus)); return 0; } /* Funktio palauttaa annetun suorakulmion pinta-alan */ double laske_ala(float leveys, float korkeus) { return (leveys*korkeus); }
Torgo kirjoitti:
Mikään ei estä esittelemästä myös funktioita muuttujien tapaan lohkojen sisällä. Niihin pätevät samat säännöt.
Näihin sääntöihin kuitenkin kuuluu myös se puolipiste, jonka puuttumisesta Grez mainitsi. Aivan hukkaan sekään vastaus ei siis mennyt.
Torgo kirjoitti:
Tosin monet kääntäjät (kuten gcc) sallivat standardin vastaisesti muuttujien ja funktioiden esittelyn keskellä koodiakin. Varoitusten kera tosin.
C99 sallii määrittelyt koodin seassakin. Kukaan ei ole maininnut, mistä standardin versiosta on kyse, joten minusta on erittäin perusteltua käyttää kymmenen vuotta vanhaa standardia 20 vuotta vanhan sijaan.
Joo, taas huomaa ettei pitäisi luottaa ulkomuistiin, varsinkaan kielen kanssa mitä ei tule käytettyä kovin usein. Kiitokset oikaisusta.
Tässä aletaan nyt eksymään jo aika kauas ketjun aloittajan alkuperäisestä ongelmasta, mutta silläkin uhalla... ;)
Metabolix kirjoitti:
C99 sallii määrittelyt koodin seassakin. Kukaan ei ole maininnut, mistä standardin versiosta on kyse, joten minusta on erittäin perusteltua käyttää kymmenen vuotta vanhaa standardia 20 vuotta vanhan sijaan.
Tottahan tuokin, mutta tässä tapauksessa on mielestäni paljon perustellumpaa käyttää vanhempaa C90 standardia uudemman C99 sijaan. Mielestäni pitäisi kokonaan unohtaa että C99 sen edes sallii. Perusteena ei ole tyyliseikat tai edes kääntäjien antamat varoitukset. Perusteena on että tuon C90 mukaan tehty koodi on yhteensopivaa myös C99 standardin kanssa, mutta sama ei päde toisinpäin. (Ja siitä se kääntäjän varoituskin tulee.)
Tämän ketjun esimerkin kannalta siinä ei ole mitään ongelmaa, mutta todellisessa elämässä alkaakin jo olla. Eikä mielestäni kannata alun alkaenkaan opetella tapoja, jotka voivat myöhemmin aiheuttaa ongelmia. Esimerkiksi minä käytän työssäni neljään eri ympäristöön neljää eri kääntäjää. Kaikki kääntäjät ovat C99-standardin jälkeisiä tekeleitä, mutta ainoastaan yksi niistä tukee koodin sekaan upotettuja esittelyjä (nimittäin gcc). Jos tekisin koodia tuolla C99 sallimalla tavalla, niin joutuisin muokkaamaan sen uudestaan kun sitä siirretään ympäristöön, joka ei sitä tuekaan. Mitä suurempi ohjelma, sen valtavampi urakka.
Vielä, vaikka onkin mahdollista esitellä funktiot toisen funktion sisällä, kannattaa ottaa tavaksi esitellä ne ennen funktioiden toteutuksia. Mitään vahinkoa ei siis tapahdu vaikka Grezin kommentin absoluuttisena totuutena ottaisikin. :)
Torgo kirjoitti:
Mikään ei estä esittelemästä myös funktioita muuttujien tapaan lohkojen sisällä. Niihin pätevät samat säännöt.
Täsmennetään (tai oikeastaan korjataan) hieman vielä. Sääntö ei tarkalleen ottaen ole ihan sama. Funktion tapauksessa se vain esitellään, kun taas muuttujan tapauksessa se sekä esitellään että määritellään (siis jos se tehdään tuolla funktion sisällä normaalisti ilman externiä). Funktion tapauksessa esittelyt ovat implisiittisesti externejä. Muuttujan tapauksessa sille siis varataan sen tarvitsema muisti, mutta funktion tapauksessa sitä ei varata, vaan ainoastaan kerrotaan että symbolitaulukosta pitäisi löytyä tälläinen funktio ja että se tarvitsee niin ja niin paljon tilaa pinosta kutsua varten.
Funktion määrittely puolestaan ei ole mahdollista toisen funktion sisällä. Toteutus on siis oltava funktion ulkopuolella, vaikka esittely voikin olla funktion sisällä.
Toivottavasti selvensi jotain, vaikka pahaa pelkään että sekoitin vain lisää. :P
Ohjelmaan voisi lisätä vielä tarkistuksen, että leveys ja korkeus ovat positiivisia.
Aihe on jo aika vanha, joten et voi enää vastata siihen.