Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Kysymys C-kielisestä tehtävästä

Sivun loppuun

pekkk [19.03.2009 12:34:00]

#

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

Teuro [19.03.2009 12:36:53]

#

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.

Grez [19.03.2009 12:45:19]

#

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;
}

pekkk [19.03.2009 12:51:48]

#

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 :)

Teuro [19.03.2009 12:54:19]

#

Eipä tuohon oikein muuta mielipidettä irtoa, koska Grez:n vastaus hipoo täydellisyyttä.

Chiman [19.03.2009 12:59:32]

#

Grezin vastaus on oikein. Aloittaja ei tainnut ymmärtää, mitä funktion parametreilla ja arvon palauttamisella tarkoitetaan.

tkok [19.03.2009 12:59:43]

#

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.

pekkk [19.03.2009 13:05:57]

#

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.

Teuro [19.03.2009 13:12:46]

#

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.

Grez [19.03.2009 13:22:25]

#

Teuro.. Lisäsi siihen täytyy tietenkin tehdä tuo kyselyrutiini. Alkuperäisessä esimerkissähän mitat oli kovakoodattu.

Teuro [19.03.2009 13:24:05]

#

Kappas siinähän vain tulostettiin alustetut arvot. Hanki teuro lasit.

pekkk [19.03.2009 13:27:05]

#

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?

Grez [19.03.2009 13:27:08]

#

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.

pekkk [19.03.2009 13:31:20]

#

Kiitos taas paljon! :)

Torgo [31.03.2009 12:11:25]

#

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);
}

Metabolix [31.03.2009 12:30:54]

#

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.

Grez [31.03.2009 12:37:03]

#

Joo, taas huomaa ettei pitäisi luottaa ulkomuistiin, varsinkaan kielen kanssa mitä ei tule käytettyä kovin usein. Kiitokset oikaisusta.

Torgo [31.03.2009 15:21:11]

#

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 [02.04.2009 15:46:23]

#

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

Jaska [02.04.2009 22:08:15]

#

Ohjelmaan voisi lisätä vielä tarkistuksen, että leveys ja korkeus ovat positiivisia.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta