Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Mitä tässä itse asiassa tapahtuu?

Sivun loppuun

Juhadex [15.07.2007 13:39:21]

#

Charhan on tavallaan myös kokonaislukutyyppi, joten ihan vain kokeilin tälläistä, mutta ohjelma sekoaa; antaa äänimerkkejä ym ainakin mingw:ssä.
Joten ihan vain kiinnostaisi, että tässä oikeastaan tapahtuu järjestelmän sisäisesti?

#include <iostream>
using namespace std;
int main()
{
    char merkki = 'a';
    while ('a' <= 'z')
    {
          cout << merkki;
          merkki++;
    }
    return 0;
}

E: Ohjelmanhan pitäisi tällätavalla tulostaa aakkoset a-z. En tavoittele varsinaista tarkoitusta, vaan tavoittelen vastausta, minkä takia ohjelma sekoaa. Normaalisti perus char merkkien laskeminen onnistuu pienillä luvuilla.

kayttaja-2499 [15.07.2007 13:47:32]

#

Ohjelmassasi on ikiluuppi, 'a' on aina pienempi kuin 'z'. While-silmukan ehto varmaankin piti olla muotoa "merkki <= 'z'".

Nyt ohjelmasi listaa kaikki char-tietotyypin arvot (0-255) luupilla. Nämä arvot sisältävät myös niitä äänimerkkejä.

Juhadex [15.07.2007 14:02:48]

#

kayttaja-2499 kirjoitti:

Ohjelmassasi on ikiluuppi, 'a' on aina pienempi kuin 'z'. While-silmukan ehto varmaankin piti olla muotoa "merkki <= 'z'".

Nyt ohjelmasi listaa kaikki char-tietotyypin arvot (0-255) luupilla. Nämä arvot sisältävät myös niitä äänimerkkejä.

Okei, kiitos.

Juhadex [15.07.2007 19:49:25]

#

Kysymys: Mitä eroa on class, struct ja union -luokilla? mitään eroa en näe. Onko väliä mitä käyttää? jos on, niin mitä pitää käyttää missäkin?

Blaze [15.07.2007 20:10:35]

#

Classin ja structin ero on se, että classin jäsenet on oletuksena privaatteja ja structin publiceja.

Metabolix [15.07.2007 20:18:12]

#

Unionin ja structin ero onkin paljon suurempi. Union on pakattu siten, että kaikki sen jäsenet käyttävät samaa tilaa. Ajatuksena siis on, että vain yhtä sen jäsentä käytetään kerralla. Usein unionia käytetään osana jotain structia, ja mukana on tavallisesti myös jokin tunnistekenttä, josta selviää, mikä on käytössä. Seuraava koodi havainnollistaa structin ja unionin eroa:

union yhdiste {
  int a;
  float f;
};
struct rakenne {
  int a;
  float f;
};

rakenne r;
r.a = 1;
r.f = 123.4f;
std::cout << r.a << ", " << r.f << std::endl;
// 1, 123.4

yhdiste y;
y.a = 1;
y.f = 123.4f;
std::cout << y.a << ", " << y.f << std::endl;
// 1123470541, 123.4

Juhadex [15.07.2007 20:45:46]

#

Metabolix kirjoitti:

...
yhdiste y;
y.a = 1;
y.f = 123.4f;
std::cout << y.a << ", " << y.f << std::endl;
// 1123470541, 123.4

Hmm... juuri tätä eron tekevää osuutta en ymmärrä. Miksi tulostus on miten sattuu?
Kenties häiriö, kun kahta jäsentä käytettiin samaan aikaan? Eeh. Yrittäisitkö vielä selittää.

EDIT: Näinhän se taitaa olla... testasin ottamalla y.f kokonaan pois, niin y.a tulostuu oikein. Hmm...
EDIT2: Onko muita (järkevämpiä) tapoja käyttää useampaa saman unionin jäseniä samassa lohkossa, kuin tyhjentää puskuri endl:llä?
EDIT3: Ja siis... Onko unionin ainut "pointti" siinä että se vie suhteessä vähemmän keskusmuistia? eli toisinsanoen ei tarvitsisi käyttää kuin isommissa ohjelmissa? vai häh?

Markus [15.07.2007 22:58:47]

#

lainaus:

EDIT3: Ja siis... Onko unionin ainut "pointti" siinä että se vie suhteessä vähemmän keskusmuistia?

Kyllä, ainut pointti tosiaankin on se, että se vie vähemmän muistia.

lainaus:

eli toisinsanoen ei tarvitsisi käyttää kuin isommissa ohjelmissa? vai häh?

Ei. Unioni kehitettiin aikana, jolloin tietokoneiden muisti oli kortilla. Nykyisissä tietokoneissa unionia ei tarvitse enää käyttää.

lainaus:

Hmm... juuri tätä eron tekevää osuutta en ymmärrä. Miksi tulostus on miten sattuu?
Kenties häiriö, kun kahta jäsentä käytettiin samaan aikaan? Eeh. Yrittäisitkö vielä selittää.
EDIT2: Onko muita (järkevämpiä) tapoja käyttää useampaa saman unionin jäseniä samassa lohkossa, kuin tyhjentää puskuri endl:llä?

Unionista voi lukea sen jäsenen, jolle on viimmeksi arvo annettu, koska se ylikirjoittaa aina unionin entisen sisällön. endl ei vaikuta asiaan.

union yhdiste
{
  int a;
  float f;
};

yhdiste y;
y.a = 1;
y.f = 123.4f;
std::cout << y.a << ", " << y.f << std::endl;  // a väärin, f oikein
y.f = 567.8f;
y.a = 5;
std::cout << y.a << ", " << y.f << std::endl;  // a oikein, f väärin

os [15.07.2007 23:35:28]

#

Vielä lyhyesti: union on siis täysin eri asia, kuin struct ja class.

class Tili {
 private:
  char valuutta;
  union saldo {
     int senttia;
     float kultaa;
  }

 public:
  void aseta_sentit(int s) { valuutta = EUROT; saldo.senttia = s; }
  void aseta_kulta(float g) { valuutta = KULTARAHAT; saldo.kultaa = g; }
  void nayta_saldo() {
    if(valuutta==EUROT)
      std::cout << "Tilillä on " << saldo.senttia/100.0 << " euroa.";
    else std::cout << "Omistat " << saldo.kultaa << " grammaa kultaa.";
  }
};

Tili tilit[1000000000000000000000000000000]; // :)

Muisti on edelleen kortilla, jos käsitellään riittävän suuria tietomääriä. Unionille on kyllä hankala keksiä mitään oikeasti järkevää käyttöä, mutta ainakin se tarjoaa yksinkertaisen tavan käsitellä eri tietotyyppejä (float, int) samassa muistipaikassa.

Juhadex [16.07.2007 15:29:09]

#

Blaze kirjoitti:

Classin ja structin ero on se, että classin jäsenet on oletuksena privaatteja ja structin publiceja.

Kukaan ei ikinä selitä mitä public ja private tarkottaa. Public = "luokan muuttujat ovat kaikkien käytössä"... kenenkä kaikkien hemmetti vieköön :D

KYSYMYS: Miten CMD:ssä voi kirjottaa useita rivejä ennen kuin se varsinaisesti suorittaa sen komennon?... toivottavasti selitin ymmärrettävästi :S

Blaze [16.07.2007 15:45:18]

#

Juhadex kirjoitti:

Kukaan ei ikinä selitä mitä public ja private tarkottaa.

No kun me oletetaan, että perusasiat on hallussa :)

Juhadex kirjoitti:

Public = "luokan muuttujat ovat kaikkien käytössä"... kenenkä kaikkien hemmetti vieköön :D

Kaikkien. :)

Otetaas esimerkki:
Tehdään luokka Kissa, jossa on jäsenet nimi ja tunniste. Nimi on public, tunniste private.
Mikä koodi tahansa missä tahansa pääsee sörkkimään minkä tahansa Kissa-olion nimeä, mutta tunnisteeseen pääsee käsiksi vain se ja juuri se Kissa-olio, joka sen tunnisteen omistaa.

Metabolix [16.07.2007 15:51:37]

#

Juhadex kirjoitti:

Kukaan ei ikinä selitä mitä public ja private tarkottaa.

Melko suuret luulot, jos odotat, että joku sinulle henkilökohtaisesti tulee kaiken selittämään. Googleta, ota selvää, oppaita on varmaan miljoona, ja ennen kaikkea kokeile!

struct rakenne {
private:
 int private_int;
public:
 int public_int;

 void aseta_private_int(int i) {
  private_int = i;
 }
 int hae_private_int() {
  return private_int;
 }
};

rakenne r;
r.public_int = 10;
r.private_int = 10;
r.aseta_private_int(10);
int i = r.hae_private_int();

Juhadex kirjoitti:

Miten CMD:ssä voi kirjottaa useita rivejä ennen kuin se varsinaisesti suorittaa sen komennon?

Ainakin sillä, että tekee komennoista bat- tai cmd-tiedoston ja ajaa sen. En nyt juuri muista, ymmärtääkö Windows puolipisteellä erotettujen komentojen päälle, voit toki kokeilla:
dir ; cd .. ; dir

WinC [16.07.2007 16:23:40]

#

cmd.exe ei ymmärrä puolipistettä, mutta sen tilalla tulee käyttää '&' merkkiä.
Esimerkiksi: dir & cd.. & dir

Juhadex [16.07.2007 16:58:06]

#

Metabolix kirjoitti:

Juhadex kirjoitti:

Kukaan ei ikinä selitä mitä public ja private tarkottaa.

Melko suuret luulot, jos odotat, että joku sinulle henkilökohtaisesti tulee kaiken selittämään. Googleta, ota selvää, oppaita on varmaan miljoona, ja ennen kaikkea kokeile!

Minähän nimenomaan kokeilen ja kysyn juuri siksi, kun en tiedä... mitäs luulit? Ja minähän otan selvää kysymällä täältä... ennen tätä kuitenkin olen katsonut oppaita.. kirjoista ja netistä. Sitäpaitsi tarkoitin tuolla sitä että edes kaikissa oppaissa ei kerrottu. Esim yhdessäkin kirjassa sanottiin vain noin että "ovat kaikkien käytössä"... eihän tuosta voi ottaa selvää.
Sen sijaan nyt saatte selittää minkä takia, jos tässä pistää unionin nimi luokaksi, niin etu ja sukunimi tulostuu... niinkuin ajan takaa, mutta jos pistän structin, niin vain etunimi tulostuu.

#include <iostream>
using namespace std;
union NIMI
{
       char etunimi[15];
       char sukunimi[25];
};
struct HENKILO
{
       NIMI etunimi;
       NIMI sukunimi;
};
int main()
{
    HENKILO H0000001 = { "Joku", "Jokunen"};

    cout << "Nimi: ";
    cout << H0000001.etunimi.etunimi << " ";
    cout << H0000001.sukunimi.sukunimi << endl;

    return 0;
}

Selville ottamisesta vielä sen verta, että minusta on todella tyhmää sellainen kun monesti foorumeilla on tapana kehottaa käyttämään googlea. Minäkin monesti haen jotain googlella, joka löytää jonkun foorumin, joka käsittelee kyseistä asiaa ja joku siellä on kysynyt sitä mihinkä itsekin hakisin vastausta... kiusa on vain kun ensimmäinen vastaus siellä on "käytä googlea"...........
ehh?

jcd3nton [16.07.2007 17:54:32]

#

Kylla tuommoset asiat varmasti selitetaan vahankaan hyvassa C++-oppaassa. Liekko hakutaidot hakusessa?

Tuohon koodinpatkaan liittyen, en todellakaan ymmarra mita nyt oikeasti yritat tuolla saada aikaan, mita sen pitaisi tehda ja mita se ei tee (oikein). Tuo unioni tuossa on ihan tarkoitukseton. Meniko unionit ohi ymmarryksen? Kaikki unionissa oleva siis on *samassa* kohtaa muistia. Jos sinulla on vaikka kaksi lukua: int luku1 ja int luku2, niin noihin tallennettu tieto on aivan samassa kohtaa muistia -- molemmat siis osoittavat tasantarkkaan samaan tietoon. Jos luku1 on 5, niin luku2 on myos 5, silla nuo muuttujat ovat muistissa yksi ja sama. Jos vaihdat luvun2 vaikkapa 10:ksi, niin myos luku1 on 10. Miksi siis tallentaisit kaksi merkkijonoa muistiin toistensa paalle? Jos etunimi ja sukunimi ovat samassa kohtaa muistia, myos niiden arvo on sama.

Jos haluat tallentaa henkilolle nimen, tee henkilosta luokka tai structi ja laita sinne kaksi merkkijonoa: etunimi ja sukunimi. Unohda unionit.

Juhadex [16.07.2007 18:00:47]

#

jcd3nton kirjoitti:

Kylla tuommoset asiat varmasti selitetaan vahankaan hyvassa C++-oppaassa. Liekko hakutaidot hakusessa?

Tuohon koodinpatkaan liittyen, en todellakaan ymmarra mita nyt oikeasti yritat tuolla saada aikaan, mita sen pitaisi tehda ja mita se ei tee (oikein). Tuo unioni tuossa on ihan tarkoitukseton. Meniko unionit ohi ymmarryksen? Kaikki unionissa oleva siis on *samassa* kohtaa muistia. Jos sinulla on vaikka kaksi lukua: int luku1 ja int luku2, niin noihin tallennettu tieto on aivan samassa kohtaa muistia -- molemmat siis osoittavat tasantarkkaan samaan tietoon. Jos luku1 on 5, niin luku2 on myos 5, silla nuo muuttujat ovat muistissa yksi ja sama. Jos vaihdat luvun2 vaikkapa 10:ksi, niin myos luku1 on 10. Miksi siis tallentaisit kaksi merkkijonoa muistiin toistensa paalle? Jos etunimi ja sukunimi ovat samassa kohtaa muistia, myos niiden arvo on sama.

Jos haluat tallentaa henkilolle nimen, tee henkilosta luokka tai structi ja laita sinne kaksi merkkijonoa: etunimi ja sukunimi. Unohda unionit.

Voisit lukea hieman tarkemmin. Ymmärsin kyllä unionit. Tiedät itsekkin mitä tuon pitää tehdä vain vilasemalla.
Siis tuo toimii aivan oikein noin miten sen tuohon pistin. En vain ymmärrä miksi se toimii! koska siinähän nyt on se union... ja jos pistää struct niin silloin vain etunimi tulostuu.

Metabolix [16.07.2007 18:01:41]

#

Juhadex kirjoitti:

Sitäpaitsi tarkoitin tuolla sitä että edes kaikissa oppaissa ei kerrottu. Esim yhdessäkin kirjassa sanottiin vain noin että "ovat kaikkien käytössä"... eihän tuosta voi ottaa selvää.

Yksi kirja on huono, joten et voi kokeilla jotain toista? Esimerkiksi cppreference.com kertoo selkeästi näin:

cppreference.com kirjoitti:

Public data in a class are accessible to everyone.
– –
Private data of a class can only be accessed by members of that class.

Kun ei juutu tässä lukemaan vain ensimmäistä kohtaa ja ihmettelemään "kenelle kaikille", niin näkee jälkimmäisestä selvästi, että yksityiset muuttujat eivät selvästikään ole käytettävissä kuin rajatulla alueella.

Tuosta viimeisestä kysymyksestäsi ei nyt oikein ottanut selvää. Miten tuossa luokat liittyivät mihinkään? Mitä nyt muutit ja millaiseksi? Jos tarkoitit, että vaihdat unionin joksikin muuksi, niin silloin tuo asetuksesi HENKILO H0000001 = { "Joku", "Jokunen"}; asettaa etunimi-jäsenen etunimen ja sukunimen (siis etunimi.etunimi ja etunimi.sukunimi), jolloin sukunimi-jäsen jää tyhjäksi. Unionina taas vain toinen jäsenistä voi olla asetettuna, joten ensimmäiseen unioniin (etunimi) menee "Joku" ja jälkimmäiseen (sukunimi) "Jokunen". Kaikkiaan tuollainen kaksi eri char-taulua sisältävä union-rakenne on kuitenkin aivan järjetön, järkevämpää olisi määritellä NIMI suoraan yhdeksi char-tauluksi.

Juhadex [16.07.2007 18:13:00]

#

Metabolix kirjoitti:

Tuosta viimeisestä kysymyksestäsi ei nyt oikein ottanut selvää. Miten tuossa luokat liittyivät mihinkään? Mitä nyt muutit ja millaiseksi? Jos tarkoitit, että vaihdat unionin joksikin muuksi, niin silloin tuo asetuksesi HENKILO H0000001 = { "Joku", "Jokunen"}; asettaa etunimi-jäsenen etunimen ja sukunimen (siis etunimi.etunimi ja etunimi.sukunimi), jolloin sukunimi-jäsen jää tyhjäksi. Unionina taas vain toinen jäsenistä voi olla asetettuna, joten ensimmäiseen unioniin (etunimi) menee "Joku" ja jälkimmäiseen (sukunimi) "Jokunen". Kaikkiaan tuollainen kaksi eri char-taulua sisältävä union-rakenne on kuitenkin aivan järjetön, järkevämpää olisi määritellä NIMI suoraan yhdeksi char-tauluksi.

Tätä juuri tarkoitin...
ja se EI ole järjetön kun tehdään enemmän kaikkia.. esim syntymäaika, asuinpaikka, postinumero ymym.. kaikki löytyy HENKILO luokasta. Siis kun esim NIMI luokassa on etu ja sukunimi ja OSOITE luokassa kaikki osoitteeseen liittyvät... tällöin se EI ole järjetöntä. Ja sitäpaitsi tämän tein puhtaasti kiinnostuksen ja harjoittelun vuoksi... että sillee.
No mut kiitos vastauksesta jokatapauksessa.

jcd3nton [16.07.2007 18:15:51]

#

Huomaa sana UNION. Kaksi eri char-taulua UNIONISSA on todellakin aivan jarjeton juttu. Luokassa ei sen sijaan olisi mitaan vikaa.

Juhadex [16.07.2007 18:17:54]

#

jcd3nton kirjoitti:

Huomaa sana UNION. Kaksi eri char-taulua UNIONISSA on todellakin aivan jarjeton juttu. Luokassa ei sen sijaan olisi mitaan vikaa.

Niin kauan kun ohjelma toimii oikein, en näe mitään syytä muuttaa asioita. Ja niinkuin jo sanoin... tämä on vain testailua ja uteliaisuutta, miten eri jutut toimii missäkin ja mitenkä... ei tarvi tulla viilaamaan mulkkua tollasista asioista varsinkaan tässä tilanteessa, jossa käyttökohteella ei ole hittojakaan väliä.

Metabolix kirjoitti:

...asettaa etunimi-jäsenen etunimen ja sukunimen (siis etunimi.etunimi ja etunimi.sukunimi)...

Mmmm... tarkoititko etunimi.etunimi ja sukunimi.sukunimi?

jcd3nton [16.07.2007 18:32:01]

#

Ei vaan etunimi.etunimi ja etunimi.sukunimi. Miksi muuten etunimella on etunimi ja sukunimi, sukunimella etunimi ja sukunimi?

Juhadex [16.07.2007 18:39:38]

#

Siis en osaa nyt katsoa oikein... HENKILO.etunimi.etunimi ja HENKILO.sukunimi.sukunimi... emm... ymmärtäisin paremmin tuon Metan selostuksen, jos näkisin siellä jossain etunimi.sukunimi... siis eikö esim tuo HENKILO.etunimi olekkaan suora viittaus NIMI union etunimeen vaan myös sukunimeen?

KeKimmo [16.07.2007 18:47:03]

#

Kannattaa unohtaa, että olet koskaan kuullut unioneista yhtään mitään. Jos joskus tulet tarvitsemaan niitä johonkin, olet varmasti siihen mennessä jo oppinut tarpeeksi ymmärtääksesi niiden idean.

Juhadex [16.07.2007 18:48:03]

#

KeKimmo kirjoitti:

Kannattaa unohtaa, että olet koskaan kuullut unioneista yhtään mitään. Jos joskus tulet tarvitsemaan niitä johonkin, olet varmasti siihen mennessä jo oppinut tarpeeksi ymmärtääksesi niiden idean.

Juuh... mutta tuo ohjelma nyt ei toimi ilman sitä =p

KeKimmo [16.07.2007 18:51:42]

#

struct HENKILO
{
       char etunimi[15];
       char sukunimi[25];
};

Mikä vikä tässä on?

Juhadex [16.07.2007 18:55:06]

#

KeKimmo kirjoitti:

struct HENKILO
{
       char etunimi[15];
       char sukunimi[25];
};

Mikä vikä tässä on?

ei mikään, mutta...

Juhadex kirjoitti:

Ja niinkuin jo sanoin... tämä on vain testailua ja uteliaisuutta, miten eri jutut toimii missäkin ja mitenkä...

Haluaisin nyt vain jotenkin saada toimimaan tuolla idealla... mutta siis ei voi?

KeKimmo [16.07.2007 18:56:38]

#

Juhadex kirjoitti:

Haluaisin nyt vain jotenkin saada toimimaan tuolla idealla... mutta siis ei voi?

Millä idealla?

Juhadex [16.07.2007 19:01:37]

#

KeKimmo kirjoitti:

Juhadex kirjoitti:

Haluaisin nyt vain jotenkin saada toimimaan tuolla idealla... mutta siis ei voi?

Millä idealla?

Juuri tuolla idealla mikä siinä nytkin on, eli nuo etunimi ja sukunimi olisi jossain luokassa ja sieltä toiseen luokkaan... en osaa selittää sitä hienoilla nimityksillä, mutta kuitenkin.

KeKimmo [16.07.2007 19:06:06]

#

Juhadex kirjoitti:

Juuri tuolla idealla mikä siinä nytkin on, eli nuo etunimi ja sukunimi olisi jossain luokassa ja sieltä toiseen luokkaan... en osaa selittää sitä hienoilla nimityksillä, mutta kuitenkin.

- Missä luokassa ne olisivat ja miksi?
- Mitä tarkoitat tuolla "toiseen luokkaan"?
- Mikä se toinen luokka olisi?

EDIT:
Ja tuo koodisihan ei edes käytä luokkia missään? Tai no, sen struktuurin voi kai laskea luokaksi, jonka kaikki jäsenet ovat julkisia.

Mutta tosiaan, unohda koko unionien olemassaolo. Tuon koodisi perusteella olet joka tapauksessa ymmärtänyt niiden idean väärin, eikä sinun siis kannata niitä käyttää.

Jos tuo koodisi muuten on C++:aa (kuten luokkapuheista käsitin), merkkijonojen tallentamiseen kannattaa käyttää std::stringiä eikä char-taulukoita.

jcd3nton [16.07.2007 19:06:50]

#

struct snimi {
   char etunimi[50];
   char sukunimi[50];
};
struct shenkilo {
   snimi nimi;
};

int main() {
   shenkilo henkilo01;
   henkilo01.nimi.etunimi = "pelle";
   henkilo01.nimi.sukunimi = "peloton";
   return 0;
}

Ja unoha nyt tosiaan ne unionit. Et nyt tarvitse niita yhtaan mihinkaan, etka tule tarvitsemaankaan ennen kun tajuat mita tarkoittaa, kun sanotaan etta unionin "muuttujat" jakavat saman alueen muistissa.

Juhadex [16.07.2007 19:09:56]

#

Miksi? no lol...

Juhadex kirjoitti:

Ja niinkuin jo sanoin... tämä on vain testailua ja uteliaisuutta, miten eri jutut toimii missäkin ja mitenkä...

siksi...

toisella luokalla tarkoita juuri sitä mitä sanon... -.-... en osaa sen paremmin sanoa, anteeksi vain =/..

JA edelleenkin en ole ihastunut unioniin... JOS vain kertoisitte miten tuo paska toimis ilman sitä... edelleenkin.. lukekaa viestini tarkemmin tästä lähtien =/.. ei jaksais toistella...

WinC [16.07.2007 19:12:39]

#

Yritän selittää miksi se toimii:

Juhadex kirjoitti:

En vain ymmärrä miksi se toimii! koska siinähän nyt on se union...

Se toimii siksi, että käytät kahta ilmentymää tuosta unionista NIMI structin HENKILO sisällä. Kyseisessä tapauksessa H0..01 pitää sisällään seuraavaa: etunimi.etunimi ja etunimi.sukunimi on "joku" ja sitten sukunimi.etunimi että sukunimi.sukunimi on "jokunen" (eli molemmilla on oma ilmentymä union NIMI tietorakenteesta)

Kannatan että siirryt jcd3ntonin ehdottamaan malliin :)

Juhadex [16.07.2007 19:21:59]

#

WinC kirjoitti:

Kannatan että siirryt jcd3ntonin ehdottamaan malliin :)

Juuri sitä alunperin hain ja etinkin.. mutta sitten rupesitte vänkäämään ja teitte minusta tyhmän =D

jcd3nton [16.07.2007 19:27:47]

#

Kerroin juuri miten hoidat homman ilman unionia. Miksi ei kelpaa?
edit. Ah, nyt se siis kelpasi. Hyva niin. :)

Olen todellakin lukenut viestisi useaan kertaan koittaessani ymmartaa mita oikeasti tahdot tehda. Ja voisin pyytaa sinulta samaa tuota viestin lukemista koskien. Kannattaa myos lukemisen lisaksi yrittaa ymmartaa. :)

Jos se unioni nyt viela vaivaa niin voin koittaa jotenkin sen selittaa. Joku muu kylla osaisi paremmin mutta...
Ajattele unioni tasan tarkkaan yhtena muuttujana. Jos luot esimerkiksi tallaisen unionin:

union joku {
   int ensimmainen;
   int toinen;
}

Vaikka unionissa "maaritellaan kaksi muuttujaa", tosiasiassa koko unioni on edelleen vain yksi muuttuja, jonka varaamaan muistiin voidaan viitata kahdella eri nimella: ensimmainen ja toinen. Vaikka lisaisit enemman noita int-tyyppisia "muuttujia", ko. unioni on edelleen vain yksi muuttuja, johon on lisatty nimia, joilla samaan arvoon voidaan viitata.

Jos maarittelet kahden intin sijaan vaikkapa intin ja floatin, molemmat jakavat saman alueen muistissa, joten tosiasiassa voit tallentaa vain yhden arvon. Jos siis annat floattia kayttaen jonkin arvon, sitten tallennat jotain inttiin, floatin arvo ei ole enaa sama kuin mita annoit aluksi, silla intilla kirjoitit muistiin jotain muuta. Et siis voi unioniin tallentaa kahta eri arvoa.

Jos haluat tallentaa usean eri arvon, esimerkiksi jostain kaupan tuotteesta lukumaaran ja hinnan, kayta silloin luokkaa (class) tai rakennetta (struct). Kun maarittelet luokkaan vaikkapa int- ja float- muuttujaa, molemmat saavat oman, toisistaan riippumattoman palan muistia, joten voit tallentaa kumpaankin arvon, ilman etta toinen muuttuu mihinkaan.

(Osaako joku opettaa selittamisen saloja? Ei tasta tule mitaan.)

Juhadex [16.07.2007 19:39:18]

#

jcd3nton kirjoitti:

(Osaako joku opettaa selittamisen saloja? Ei tasta tule mitaan.)

Selitit ainakin sen verta riittävän hyvin, että tajusin about aika täydellisesti.

EDIT. Miten minun pitää esitellä aliohjelma jossa on rakenteen muuttuja?

Blaze [16.07.2007 21:33:44]

#

Juhadex kirjoitti:

Miten minun pitää esitellä aliohjelma jossa on rakenteen muuttuja?

struct lol {
  int a;
  int b;
};

struct lol palauttaa_struktin() {
  ...
}

void ottaa_struktin_parametrina(struct lol nimi) {
  ...
}

Juhadex [16.07.2007 22:23:44]

#

Blaze kirjoitti:

Juhadex kirjoitti:

Miten minun pitää esitellä aliohjelma jossa on rakenteen muuttuja?

struct lol {
  int a;
  int b;
};

struct lol palauttaa_struktin() {
  ...
}

void ottaa_struktin_parametrina(struct lol nimi) {
  ...
}

Siis onko tuo nyt ihan oikein? kun en saa (doh) toimimaan.

Blaze [16.07.2007 22:30:10]

#

Juhadex kirjoitti:

Siis onko tuo nyt ihan oikein?

En kai minä nyt vääryyksiä tänne kirjota :)

Metabolix [16.07.2007 22:30:35]

#

Taas selitit vähän niin, että joutuu arvailemaan, mitä oikein haluat. Mitä tarkoittaa rakenteen muuttuja? Pitääkö sen olla muokattavissa vai pitääkö vain välittää arvo funktiolle, ...

Juhadex [16.07.2007 22:34:00]

#

Metabolix kirjoitti:

Taas selitit vähän niin, että joutuu arvailemaan, mitä oikein haluat. Mitä tarkoittaa rakenteen muuttuja? Pitääkö sen olla muokattavissa vai pitääkö vain välittää arvo funktiolle, ...

Kyllä Blaze tuntu tajuavan...

Mazzimo [16.07.2007 23:07:43]

#

Turhaan alat juhadex aukomaan päätäsi. Täällä kaikki, jotka yrittävät auttaa, tekevät sen vapaasta tahdostaan. Saisit olla kiitollinen siitä, eikä todellakaan kannattaisi käyttäytyä kuin mikäkin maailmanomistaja. Olet selvästikin hyvin nuori (siinä 10 v. paikkeilla sanoisin), joten tuollainen on osittain ymmärrettävää. Siltikin tuo alkaa olla jo naurettavaa. Esität todellakin kysymyksesi hyvin epäselvästi, josta johtuen niitä saa arvata eikä kunnollisen vastauksen tekeminen ole mahdollista. Jos sinulta kysytään tarkennusta kysymykseesi, käyt jauhamaan mitä uskomattominta paskaa siitä, että pitäisi lukea tarkemmin.

Vielä kerran: SINÄ olet se, joka kysyy apua. SINUN asemassasi kannattaa olla nöyrä ja olla kiitollinen siitä avusta, jonka joku on viitsinyt sinulle antaa. Täällä auttajat osaavat SINUA paremmin nämä jutut, joten ei tarvitse käydä väittelemään perstorassa vaan kuunnella mitä asiaa näillä hepuilla on. Ohjelmointi on vaikeaa, eikä ensimmäisestä vastoinkäymisestä saa hermostua. Jos jatkat tuollaista asennetta, saat varmasti kovistella itseksesi (joka olisi kuule sinulle oikein!).

Joops.. No offence sen enempää. Toivottavasti voimme antaa neuvoja paremmissa tunnelmissa jatkossa. :)

Metabolix [16.07.2007 23:10:42]

#

Juhadex kirjoitti:

Kyllä Blaze tuntu tajuavan...

Mistä tiedät, jos ei kerran edes toiminut? Blaze valitsi sen kaikkein helpoimman ja yksinkertaisimman vaihtoehdon olettaen, että oli kyse koko rakenteesta eikä vain yhdestä sen (jäsen)muuttujasta (kuten minulle ensiksi sanamuodostasi tuli mieleen). Jos arvoja pitäisi vielä päästä muokkaamaankin, tarvitset vanhanaikaisesti osoittimen (pointer) tai uudemmin C++:n tapaan viittauksen (reference).

Blaze on vielä C-miehiä, C++ tulee toimeen ilman sanaa struct muualla paitsi tuolla uuden tyypin struct lol määrittelyssä.

struct rakenne {
  int a, b;
};

void osoittimella(rakenne *r)
{
  r->a = r->a + r->b;
}
void viittauksella(rakenne& r)
{
  r.a = r.a + r.b;
}
int viittauksella_vakioon_eli_ei_voi_muokata(rakenne& const r)
{
  return r.a + r.b;
}

rakenne r;
osoittimella(&r);
viittauksella(r);
r.a = viittauksella_vakioon_eli_ei_voi_muokata(r);

Juhadex [16.07.2007 23:18:12]

#

Mazzimo kirjoitti:

Turhaan alat juhadex aukomaan päätäsi. Täällä kaikki, jotka yrittävät auttaa, tekevät sen vapaasta tahdostaan. Saisit olla kiitollinen siitä, eikä todellakaan kannattaisi käyttäytyä kuin mikäkin maailmanomistaja. Olet selvästikin hyvin nuori (siinä 10 v. paikkeilla sanoisin), joten tuollainen on osittain ymmärrettävää. Siltikin tuo alkaa olla jo naurettavaa. Esität todellakin kysymyksesi hyvin epäselvästi, josta johtuen niitä saa arvata eikä kunnollisen vastauksen tekeminen ole mahdollista. Jos sinulta kysytään tarkennusta kysymykseesi, käyt jauhamaan mitä uskomattominta paskaa siitä, että pitäisi lukea tarkemmin.

Vielä kerran: SINÄ olet se, joka kysyy apua. SINUN asemassasi kannattaa olla nöyrä ja olla kiitollinen siitä avusta, jonka joku on viitsinyt sinulle antaa. Täällä auttajat osaavat SINUA paremmin nämä jutut, joten ei tarvitse käydä väittelemään perstorassa vaan kuunnella mitä asiaa näillä hepuilla on. Ohjelmointi on vaikeaa, eikä ensimmäisestä vastoinkäymisestä saa hermostua. Jos jatkat tuollaista asennetta, saat varmasti kovistella itseksesi (joka olisi kuule sinulle oikein!).

Joops.. No offence sen enempää. Toivottavasti voimme antaa neuvoja paremmissa tunnelmissa jatkossa. :)

Nöyyrimmät anteeksipyyntöni. Olen 7wee enkä 10!!

Kyllä tuo kysymykseni oli aika selkeä... "Miten esitellään aliohjelma, jossa on rakenteen muuttuja"... mitä kohtaa et ymmärtänyt? Enkä ole nähdäkseni aukonut päätä oikeesti kertaakaan. Kyllä tuo purkauksesi oli aivan turhaa.
Ja ihan vain tiedoksi, että vaikka saatan kuullostaa tylyltä, niin se ei tarkoita etten olisi kiitollinen. Kiittelen jälkeenpäin kun asiat ovat selvät. En vain jaksa tuhlata aikaa turhiin =)=)=) kiiiiiiittti jeejee sepustuksiin... sori... enkä minä hermostu... olen harvinaisen rauhallinen. Sähän siinä tunnut hermostuvan ^__^
Noh mutta... anteeksi jos sinua nyt kuitenkin rupes ahistamaan.

Metabolix kirjoitti:

Mistä tiedät, jos ei kerran edes toiminut? Blaze valitsi sen kaikkein helpoimman ja yksinkertaisimman vaihtoehdon olettaen, että oli kyse koko rakenteesta eikä vain yhdestä sen (jäsen)muuttujasta (kuten minulle ensiksi sanamuodostasi tuli mieleen). Jos arvoja pitäisi vielä päästä muokkaamaankin, tarvitset vanhanaikaisesti osoittimen (pointer) tai uudemmin C++:n tapaan viittauksen (reference).

Blaze on vielä C-miehiä, C++ tulee toimeen ilman sanaa struct muualla paitsi tuolla uuden tyypin struct lol määrittelyssä.

Noh pistetään taas koodia... eihän tästä muuten tuu taas yhtään mitään :D

#include <iostream>
#include <string>
using namespace std;
void Tulostus();
void Tietokanta();
struct HENKILO
{
    char etunimi[15];
    char sukunimi[25];
    string katuosoite;
    unsigned int postinumero;
    char postitoimipaikka[30];
};
int main()
{
    Tulostus();

    return 0;
}
void Tulostus()
{

    cout << "Nimi:";
    cout.width(14);
    cout.fill('_');
    cout << H0000001.etunimi << " " << H0000001.sukunimi << endl;
    cout << "Osoite:";
    cout.width(29);
    cout.fill('_');
    cout << H0000001.katuosoite << endl;
    cout.width(20);
    cout << H0000001.postinumero << " " << H0000001.postitoimipaikka << endl;
}
void Tietokanta()
{
    HENKILO H0000001 = {"Joku", "Jokunen", "Jokusenkuja 9", 999999, "Jokusela"};
}

Älkää aukoko päätänne, että "EIHÄN SE NOIN OLE!".. tiedän, otin suluista kaikki määrittelyt nyt pois. NYT rupean tutkimaan aijempia viestejä...

Blaze [16.07.2007 23:48:13]

#

Metabolix kirjoitti:

Blaze valitsi sen kaikkein helpoimman ja yksinkertaisimman vaihtoehdon olettaen

Suunnilleen näin :)
Mietin kyllä, pitäiskö alkaa saarnaamaan pointtereista, mutten sitten jaksanu. :)

Metabolix kirjoitti:

Blaze on vielä C-miehiä, C++ tulee toimeen ilman sanaa struct

Kas, hyvä tietää. C:llähän tuon voi kiertää typedeffaamalla sen structin. Selkeyden vuoks jätin sen tosta esimerkistä pois.

Juhadex kirjoitti:

Olen 7wee enkä 10!!

Joo, ja minä oon Saaban kuningatar ;)

Juhadex kirjoitti:

Kyllä tuo kysymykseni oli aika selkeä... "Miten esitellään aliohjelma, jossa on rakenteen muuttuja"

"Miten esitellään aliohjelma, joka ottaa parametrikseen rakenteen/palauttaa rakenteen?" ois ollu paljo selkeämpi.

Juhadex [16.07.2007 23:56:27]

#

Blaze kirjoitti:

Juhadex kirjoitti:

Kyllä tuo kysymykseni oli aika selkeä... "Miten esitellään aliohjelma, jossa on rakenteen muuttuja"

"Miten esitellään aliohjelma, joka ottaa parametrikseen rakenteen/palauttaa rakenteen?" ois ollu paljo selkeämpi.

Totta. Eipä tullut silloin mieleen.
Tuo 'palauttaminenkin on minulle sinänsä epäselvää. Tajuan sen symbolisesti, mutta en loogisesti. Ymmärrän main -funktion palauttamisen sillätavalla, että kun palautusarvo on 0, niin ohjelman suorituksen jälkeen keskusmuistiin ei jää mitään tietoja juuri suoritetusta ohjelmasta (?)... mutta aliohjelman "palautus" on jotenkin loogisesti epäselvä, koska minun logiikallani siinä ei olisi mitään järkeä, että aliohjelma palauttaisi 0 main -ohjelmalle... ei kun... Vai tarkoittaako aliohjelman 0 palautus sitä että se palauttaa 0 main ohjelmalle, kun tämän aliohjelman suoritus on päättynyt... siis ettei ohjelmalle jää tietoja aliohjelmasta........

Huh... en osaa selittää asoita lyhesti.

jcd3nton [16.07.2007 23:57:37]

#

Sulla on HENKILO H...1 maaritelty metodissa Tietokanta. Se ei nay ko. metodin ulkopuolelle. Seurauksena siis metodi Tulostus ei tieda mitaan H0000001:sta, joten tietenkaan sielta ei saada mitaan lukuja haettua. Jos haluat nopean purkkaratkaisun, niin voit maaritella henkilon julkiseksi -- siis maarittelet sen ennen mainin tai muiden metodien / funktioiden maarittelya. Ratkaisu ei kuitenkaan ole erityisen nerokas oliopohjaista suunnittelua ajatellen.

Miksi Tietokanta on metodi, joka ei oikeastaan tee mitaan? Metodin on tarkoitus tehda jotain toiminnallista, esimerkiksi ulostaa tekstia tai laskea ohjelman suorituksen kannalta tarkeita laskuja. Tiedon sailyttamiseen sen sijaan luokka sopii hyvin. Voisit tehda luokan Tietokanta. Kyseiseen luokkaan lisaat metodit, joilla voidaan "luoda" uusia henkiloita (esim. Tietokanta.UusiHenkilo("Pelle", "Peloton", ...;). Silloin Tietokanta-luokka luo uuden muuttujan tyyppia HENKILO. Lopuksi lisaat Tietokanta-luokkaan funktion tai funktioita, joilla voidaan hakea tietoa henkilosta. Jos siis vaikka haluaisit paaohjelmassa tulostaa henkiloiden osoitteen, kasky voisi olla jotain taman kaltaista:

cout << Tietokanta.HenkilonOsoite(henkilonID);

Jos ihmettelet tuota ID:ta, niin se on yksi keino tunnistaa henkilot toisistaan. Aina kun luodaan uusi henkilo, tietokanta antaa sille yksilollisen ID:n. Sitten kun halutaan tietoja jostain tietysta henkilosta, tietokanta etsii ja palauttaa henkilon, jolla on kysytty ID.

Metabolix [16.07.2007 23:59:39]

#

Juhadex kirjoitti:

Tuo 'palauttaminenkin on minulle sinänsä epäselvää. – – Ymmärrän main -funktion palauttamisen sillätavalla, että kun palautusarvo on 0, niin ohjelman suorituksen jälkeen keskusmuistiin ei jää mitään tietoja juuri suoritetusta ohjelmasta (?)...

Aiiiiivan väärin. Palautuksella ei ole mitään tekemistä keskusmuistin kanssa. Katsopa tätä:

#include <iostream>

int summa(int a, int b)
{
  return a + b; // Palautetaan se summa
}

int main(void)
{
  std::cout << "Lukujen 2 ja 5 summa on " << summa(2, 5) << std::endl;
  return 0;
}

Ja nyt sietäisit ihan tosissasi mennä lukemaan jotain oppaita, tuo sen todisti. Paljon yksinkertaisemmaksi ei ohjelmointi mene, ja jos tuollaiseen joudut kyselemään apua... Vähän nyt omaa yritystä siihen opetteluun, lue vaikka Antin C-opasta.

Juhadex [17.07.2007 00:05:10]

#

Metabolix kirjoitti:

Aiiiiivan väärin...
Ja nyt sietäisit ihan tosissasi mennä lukemaan jotain oppaita, tuo sen todisti. Paljon yksinkertaisemmaksi ei ohjelmointi mene, ja jos tuollaiseen joudut kyselemään apua... Vähän nyt omaa yritystä siihen opetteluun, lue vaikka Antin C-opasta.

..Kyllä minulla kirjat sun muut on, mutta niissä sanotaan vain "Palauttaa 0"... siis.. ei mitään pointtia. No katon linkkis........

EDIT... ok.. tuostakin selvis vain se että nyt tiedetään että ohjelmassa ei tapahtunut virhettä.... ok.... niin mitenkä?
Kaipaisin vähän syventävämpää tietoja. Mitä OIKEASTI tapahtuu return 0...

jcd3nton [17.07.2007 00:08:39]

#

Editoin asken edellista viestia mutta siirran nyt uuteen viestiin kun tuntuu etta keskustelun vauhti nujertaa tiedon alleen. :)

Tuosta palautuksesta. Aliohjelmaa, joka palauttaa arvon, kutsutaan funktioksi. Minne arvo palautetaan? Sinne missa sita kysytaan. Otetaan esimerkiksi yksinkertainen funktio, joka kertoo annetun luvun itsellaan. Funktion nimi voisi olla vaikka Nelio. Parametriksi se ottaa luvun (int luku). Koodissa funktio laskee ja palauttaa luvun nelion:

int Nelio( int luku ) {
    return luku * luku;
}

Nyt ko. funktiota voitaisiin kutsua nain:
Nelio(5);
Funktion palautusarvoa voidaan hyodyntaa muissa laskutoimituksissa. Jos vaikkapa haluat laskea yhteen kahden luvun neliot, se onnistuisi nain:

int lukujen_neliot = Nelio(6) + Nelio(3);

Tietenkaan noin yksinkertaisesta laskutoimituksesta ei ole jarkea tehda funktiota, mutta toivon mukaan ymmarsit nyt jotain.

Otetaan nyt viela toi henkilon osoite, josta puhuin edellisessa viestissa. Kuvitellaan siis, etta tietokannalta voidaan kysya jonkin henkilon osoitetta. Funktio voi PALAUTTAA kysytyn henkilon osoitteen esim. stringina. String voidaan suoraan tulostaa.

cout << Tietokanta.HenkilonOsoite(4); // 4 tuli ihan omasta paasta

Haetaan siis neljannen henkilon osoite. Funktio palauttaa tuon osoitteen (esim. return Henkilot[3].Osoite;), ja cout tulostaa palautetun osoitteen.

Sulla on perusteetkin aika hakusessa... Jos nyt ensin opettelisit funktiot ja tekisit jotain simppelia ennen kuin sukellat luokkiin. :) Toisaalta sujuuhan se nainkin.

Edit. Vastaan nyt viela tohon sun edelliseen, kun joku palauttaa nolla niin se tarkoittaa sita etta siina operaatiossa, missa kutsuttiin funktiota, saadaan tuo nolla. Jos vaikka asetat luvun luku = funktio() ja funktio palauttaa nollan niin sillon luku = 0. Jos funktio palauttaa 1 niin luku = 1.

Juhadex [17.07.2007 00:17:09]

#

Hei älkää nyt viittikö... Kyllähän minä sen returnin osaan pistää main funktion loppuun siinä missä muutkin. Oppaissa ei kerrota sen kummempaa, kun nopeasti kerrotaan mitä se suurinpiirtein tarkoittaa... ja sitten mennäänkin eteenpäin. Eli... ?... eli kukaan ei tunnu näkevän sitä tietoa edes tarpeellisena. Kyllähän minä luokat osaan... mutta haluan nyt oppia soveltamaan niitä. Ja minä en JOUDU kysymään mitä se tarkoittaa... minä kysyn kun se kiinnostaa minua.
Jos vain vastailisitte ja jättäisitte muut seikat huomioimatta, koska haluaisin kysyä enkä vastailla tälläisiin...

jcd3nton [17.07.2007 00:20:51]

#

Juhadex kirjoitti:

Hei älkää nyt viittikö... Kyllähän minä sen returnin osaan pistää main funktion loppuun siinä missä muutkin. Oppaissa ei kerrota sen kummempaa, kun nopeasti kerrotaan mitä se suurinpiirtein tarkoittaa... ja sitten mennäänkin eteenpäin. Eli... ?... eli kukaan ei tunnu näkevän sitä tietoa edes tarpeellisena. Kyllähän minä luokat osaan... mutta haluan nyt oppia soveltamaan niitä. Ja minä en JOUDU kysymään mitä se tarkoittaa... minä kysyn kun se kiinnostaa minua.
Jos vain vastailisitte ja jättäisitte muut seikat huomioimatta, koska haluaisin kysyä enkä vastailla tälläisiin...

GRRRRRRRRRRRRRR. LUE NYT EDES tuo viesti minka kirjotin juuri. (Ja vaikka se edellinenkin.) Selostin palautuksen kahdesti -- pitkasti ja lyhyesti. Et muuten tee luokilla mitaan, jos et funktioita ymmarra. Palautusarvo on olennainen osa funktioita.

Metabolix [17.07.2007 00:23:47]

#

Juhadex kirjoitti:

tuostakin selvis vain se – –

Herra on hyvä ja lukee myös myöhemmät osat, niin selviää muutakin. Osa 3 kertoo tarkemmin funktioista. Jos aivan välttämättä haluat kysymykseesi suoran vastauksen, niin x86-arkkitehtuureilla return 0 siirtää prosessorin eax-rekisteriin arvon 0, ja sieltä se funtkiota kutsunut paikka voi siirtää sen edelleen vaikkapa johonkin muistissa olevaan muuttujaan.

Juhadex kirjoitti:

Kyllähän minä luokat osaan...

... kuten nähtiin, kun juuri kyselit, mitä eroa on structilla, classilla ja unionilla. Alkaapi hermot hajota. Älä väitä osaavasi asiaa, kun kaikki näkevät, ettet oikeasti tajua siitä pätkän vertaa. Ensimmäinen askel oppimisessa on oman tietämättömyyden tunnistaminen ja tunnustaminen.

Juhadex kirjoitti:

Jos vain vastailisitte ja jättäisitte muut seikat huomioimatta, koska haluaisin kysyä enkä vastailla tälläisiin...

Käsittänet, että jos ihan oikeasti jaksaisit lukea oppaita ja kaikenlaista muuta, saisit helposti tuollaisiin kysymyksiin vastaukset. Käsittänet myös, että yhden tällaisen viestin kirjoittaminen kestää helposti sellaisen vartin tai usein paljon enemmänkin, ja se kaikki aika on pois siitä, mitä kaikkea muuta tässä voisi itse tehdä. Ja turhauttavaa on vastata, kun et tunnu erityisesti panostavan vastauksen ymmärtämiseen. Älä nyt itsekään pidä selvänä, että jos et ymmärrä, vika on selityksessä eikä sinussa. Yleensä tilanne on juuri päinvastoin.

Juhadex [17.07.2007 00:29:42]

#

jcd3nton kirjoitti:

Juhadex kirjoitti:

Hei älkää nyt viittikö... Kyllähän minä sen returnin osaan pistää main funktion loppuun siinä missä muutkin. Oppaissa ei kerrota sen kummempaa, kun nopeasti kerrotaan mitä se suurinpiirtein tarkoittaa... ja sitten mennäänkin eteenpäin. Eli... ?... eli kukaan ei tunnu näkevän sitä tietoa edes tarpeellisena. Kyllähän minä luokat osaan... mutta haluan nyt oppia soveltamaan niitä. Ja minä en JOUDU kysymään mitä se tarkoittaa... minä kysyn kun se kiinnostaa minua.
Jos vain vastailisitte ja jättäisitte muut seikat huomioimatta, koska haluaisin kysyä enkä vastailla tälläisiin...

GRRRRRRRRRRRRRR. LUE NYT EDES tuo viesti minka kirjotin juuri. (Ja vaikka se edellinenkin.) Selostin palautuksen kahdesti -- pitkasti ja lyhyesti. Et muuten tee luokilla mitaan, jos et funktioita ymmarra. Palautusarvo on olennainen osa funktioita.

Minä kirjotin tuota viestiäni sillä välin kun lähetit viestisi... tai sitten en vielä huomannut viestiäsi...

Minä ymmärrän funktiot paremmin kuin hyvin. Kyllä osaan käyttää funktioita. ...... ääh kirjoitin hirveästi tarinaa mutta varmaan paras etten sano enään mitään...

Metabolix kirjoitti:

... kuten nähtiin, kun juuri kyselit, mitä eroa on structilla, classilla ja unionilla. Alkaapi hermot hajota. Älä väitä osaavasi asiaa, kun kaikki näkevät, ettet oikeasti tajua siitä pätkän vertaa. Ensimmäinen askel oppimisessa on oman tietämättömyyden tunnistaminen ja tunnustaminen.

No tähän kuitenkin vielä.
Siis ihan oikeasti. En osaa hienoja nimityksiä ym. mutta olen tähänkin asti käyttänyt luokkia... tais siis "structia" ja "classia".. tosin tietämättä mitä eroa niillä on. Ei siis paljoa kun teiltä sellaisen käsityksen olen saanut, mutta enivei... en viitsi teille nyt ruveta luennoimaan mitä tiedän, mutta tunnen osaavani käyttää niitä... mutta samaan asiaan liittyy niin monta asiaa, niin kysyn jotain niistä. En ole kertaakaan täällä kysynyt mitä luokka tarkottaa ja mikä se on... tiennyt olen alusta asti...
naurettavaa keskustelua kyllä taas...

E: Ja ihan tosi... minä "panostan" vastaustenne ymmärtämiseen.. ja olen lukenut monet niistä useampaan kertaan... ja vieläkin kyllä luen, kun olen ensiksi vastaillut teidän haukkuihinne... -.-

KeKimmo [17.07.2007 00:43:54]

#

Struct ja class ovat molemmat C++:n avainsanoja. Miten olet voinut käyttää niitä koodissasi, jollet kerran osaa kumpaakaan? Lisäksi minua kiinnostaisi tietää, mikä tästä keskustelusta tekee naurettavaa.

Tuo "en osaa lopettaa virkkeitäni, joten käytän ellipsiä joka toisen perässä" -kirjoitustyylisi muuten syö uskottavuuttasi.

Mazzimo [17.07.2007 00:49:32]

#

Huoh... Nyt sinun TULEE LUKEA TÄMÄ KAIKKI. Tämän jälkeen et voi väittää, etteikö sinulle kerrottu juurta jaksaen kysymäsi asiat. Aloitetaan niistä funktioista:

lainaus:

Funktio (function) on kansantajuisesti toiminto. Se tekee jonkin tietyn toiminnon. Funktion toimintaa voidaan ohjata sille annettavilla parametreilla, ja se palauttaa tuloksena arvon. Näin teoriassa. Todellisuudessa funktiolle ei tarvitse antaa mitään parametrejä. Se voi vaikka tyhjentää ruudun, jolloin tarkempaa ohjausta ei tarvita. Funktion ei myöskään ole pakko palauttaa arvoa.

Kun funktio määritellään, pitää sen paluuarvon tyyppi määritellä. Jos ei haluta palauttaa yhtikäs mitään, annetaan paluuarvon tyypiksi void ("tyhjyys"). Sitten määrittelyssä annetaan funktion nimi. Minulla on tapana aloittaa funktion nimi isolla ja kirjoittaa jokainen nimen osa isolla. Muista! C++ tekee eron isojen ja pienten kirjainten välillä!

Funktiolle annettavat käynnistysarvot, parametrit, kirjoitetaan sulkeisiin. Niitä voi olla ihan miten paljon tahansa, tietenkin noin kymmenen on käytännön maksimi. Oliopohjaisissa ohjelmissa niitä tarvitaan vain muutama, melko usein ei yhtään. Älä kuitenkaan vaivaa päätäsi tällä vielä, kyllä ne oliot jo nurkan takana odottavat.

...

ESIM: double KeskiArvo(double luku1, double luku2);

double on funktion paluuarvon tyyppi. Eli kun funktio ajetaan, se palauttaa jonkun arvon, jonka pitää olla double-tyyppiä. Suluissa olevat ovat parametreja. double on parametrin tyyppi, ja luku1 on muuttuja johon se tallennetaan. luku2 on toinen double-tyyppinen parametri.

Funktiossa keskiarvolaskun tulos palautetaan return-käskyllä ja se annetaan vastaus-muuttujalle aivan kuten funktiokutsun tilalla olisi muuttuja.

Ja sitten vielä tämä main-kysymys:

lainaus:

int main()
{
    return 0;
}

Mihin main():n paluuarvo palautuu? Kuka main():ia edes kutsuu? Vastaus on, että kääntäjä kutsuu. Kun käynnistät ohjelman, käyttöjärjestelmä lataa sen ja rupeaa suorittamaan sitä. Se, että miten käyttöjärjestelmä käynnistää ohjelman riippuu ihan käyttöjärjestelmästä. Yksinkertaisessa tapauksessa se vain rupeaa syöttämään prosessorille ohjelmakoodia tiedoston alusta, yleensä kuitenkin ohjelmatiedostoissa (kuten .exe-tiedostoissa) on alussa jonkinlainen tunnisteosa, jonka käyttöjärjestelmä lukee ja siirtyy sen jälkeen ennalta määrättyyn kohtaan ohjelmakooditiedostoa ja rupeaa suorittamaan ohjelmaa siitä eteenpäin. Niinpä meidän kääntäjämme ovelasti järjestää asiat niin, että juuri siinä kohden mistä ohjelman suoritus alkaa on kutsu main()-funktioon. Eli käyttöjärjestelmä antaa alkusysäyksen ohjelmalle ja käyttöjärjestelmä myöskin saa main()-funktion paluuarvon.

Paluuarvo on siis on arvo, jonka ajettu ohjelma palauttaa käyttöjärjestelmään. Paluuarvo on peräisin Unixeista, joissa sitä hyödynnetäänkin melko ahkerasti. On hyvän ohjelmointitavan mukaista, että ohjelmat palauttavat arvon, jolla viestivät siitä kuinka ohjelman suoritus onnistui. Standardi on, että onnistunut ohjelma palauttaa arvon EXIT_SUCCESS (EXIT_SUCCESS on siis vakio, muuttuja joka on kääntäjän määrittelemä). Jos jokin menee pieleen, palautetaan EXIT_FAILURE. EXIT_SUCCESS on lähes poikkeuksetta 0, kun taas EXIT_FAILURE riippuu järjestelmästä riippuen - yleensä se on 1 tai 255. Yleinen tapa palauttaa nolla main():n onnistuneen suorituksen päätteeksi ei siis ole ihan kaikkien taiteen sääntöjen mukainen, vaikka käytännössä aina toimiikin.

Paluuarvo on hyvin kätevä, kun rakennetaan komentojonoja, jotka kutsuvat C++-ohjelmaa ja jatkavat toimintaansa suorituksen onnistumisen, siis paluuarvon, perusteella. Esimerkiksi kun kopiointiohjelma palauttaa EXIT_FAILURE-arvon mikäli levytila loppuu kopioidessa kesken, voi varmuuskopioita tekevä komentojono lukea paluuarvon ja sen perusteella käynnistää sähköpostiohjelman, joka lähettää ylläpitäjälle "Vaihda nauhavarmistimeen uusi nauha"-viestin. Unixissa lapsiprosessien suorituksen onnistumista voi myös tutkia paluuarvon perusteella. Useissa Unix-shelleissä paluuarvo löytyy $?-ympäristömuuttujasta, kun taas DOSissa (ja NT4 DOS-shellissä) paluuarvo löytyy muuttujasta ERRORLEVEL. Sen voit todeta vaikka tekemällä ohjelman, jonka main() palauttaa tietyn arvon, ajamalla sen ja komentamalla komentorivillä:

echo %ERRORLEVEL%

Ja vaikka et itse käyttäisi ohjelmaa tällaiseen tarkoitukseen, saat hyvin pienellä vaivalla aikaan hyvää mieltä muille, kun teet ohjelmasi niin että se viestii toiminnastaan paluuarvolla (esimerkiksi: EXIT_SUCCESS (tai 0) = virheetön toiminta, 1 = ajonaikainen virhe, 2 = virhe tiedoston avauksessa jne.. tai yksinkertaisesti ja standardisti: EXIT_SUCCESS = virheetön suoritus, EXIT_FAILURE = virheellinen suoritus).

HUOM!! Tämä kaikki on suoraa lainausta tältä sivulta: http://www.nic.funet.fi/c opas/funktiot.html
Joten nyt et voi väittää, etteikö oppaissa käsiteltäisi näitä tarkemmin.
Anteeksi moderaattorit. Jos viesti on liian pitkä, sen saa poistaa. Tämä oli vain tarkoitettu opetustarkoitukseen, että niitä tutoriaalejakin voisi lukea. :)
(Mod. Edit. Käytetäänhän niissä lainauksissakin asianomaisia tageja silti...)

Juhadex [17.07.2007 00:50:42]

#

KeKimmo kirjoitti:

Struct ja class ovat molemmat C++:n avainsanoja. Miten olet voinut käyttää niitä koodissasi, jollet kerran osaa kumpaakaan? Lisäksi minua kiinnostaisi tietää, mikä tästä keskustelusta tekee naurettavaa.

Tuo "en osaa lopettaa virkkeitäni, joten käytän ellipsiä joka toisen perässä" -kirjoitustyylisi muuten syö uskottavuuttasi.

#include <iostream>
using namespace std;
class Auto
{
      public:
      void Volvo() {cout << "Olen Volvo!\n";}
      void Mersu() {cout << "Olen Mersu!\n";}
      void Toyota() {cout << "Olen Toyota!\n";}
};
int main()
{
    Auto myytavat;
    myytavat.Volvo();
    myytavat.Mersu();
    myytavat.Toyota();
    return 0;
}

Tuollein pikkusesti olen käyttänyt.

Menikö tämä aihe tosiaan minun pilkkaamiseen?

Heh, vai uskottavuuteni heiluu. Ei hirveesti kiinnosta, mutta pyydän anteeksi jos kirjoitustyylinikin häiritsee =p

EDIT: Mazzimo kiitokset. Juuri tälläistä tietoa hain =) funktiot tiesin, mutta kaikki muu tieto oli mukavaa luettavaa.

KeKimmo [17.07.2007 00:57:25]

#

Tuo koodisi vaikuttaa järjettömältä. Mikä sen idea on?

EDIT:
Ymmärtäisin paremmin, jos Auto-luokalla olisi muuttujia tyyliin "merkki", "malli" ja "vuosimalli". Olioiden periyttämistä havainnollistettaessa oltaisiin myös voitu periyttää Auto-luokasta luokat Mersu, Volvo ja Toyota, jotka siis ovat kaikki autoja. Itse tosin olisin mieluummin periyttänyt vaikkapa luokat Henkilöauto ja Kuorma-auto.

Toinen EDIT:
Ääh. Kertokaa nyt joku minulle, onko tämä tyyppi trolli vai todellinen avuntarvitsija.

Juhadex [17.07.2007 01:06:17]

#

KeKimmo kirjoitti:

Tuo koodisi vaikuttaa järjettömältä. Mikä sen idea on?

EDIT:
Ymmärtäisin paremmin, jos Auto-luokalla olisi muuttujia tyyliin "merkki", "malli" ja "vuosimalli". Olioiden periyttämistä havainnollistettaessa oltaisiin myös voitu periyttää Auto-luokasta luokat Mersu, Volvo ja Toyota, jotka siis ovat kaikki autoja. Itse tosin olisin mieluummin periyttänyt vaikkapa luokat Henkilöauto ja Kuorma-auto.

Havaitsen nyt kyllä ihan pelkkää halveksuntaa minua kohtaan...

E: Minä en ole trolli. Kysyn oikeasti kysymyksiä mihin tarvitsen tietoa. Ongelmani on siinä että minua jää häiritsemään pikkuseikat jonka takia koko ymmärrys kaatuu.
Mutta selvä... ei tarvitse odotella minua enään tänne kyselemään.

KeKimmo [17.07.2007 01:07:00]

#

Juhadex kirjoitti:

Havaitsen nyt kyllä ihan pelkkää halveksuntaa minua kohtaan...

Toimiva havaintokyky sinulla.

EDIT:
Ihan oikeasti, tuo koodi on järjetöntä. Sen perusteella et ymmärrä luokkia, vaikka väitätkin toista. Kirjoititko tahallasi outoa koodia, vai valehteletko osaamisestasi? Vai yritätkö ärsyttää ihmisiä tahallasi?

Metabolix [17.07.2007 01:07:43]

#

Juhadex kirjoitti:

Havaitsen nyt kyllä ihan pelkkää halveksuntaa minua kohtaan...

Vaikea tuohon on muutenkaan suhtautua. Ihan oikeastiko tunnet, että osaat käyttää luokkia, ja tuoko on se, mihin niitä osaat käyttää? Tikahdun nauruuni...

Juhadex [17.07.2007 01:10:06]

#

Metabolix kirjoitti:

Juhadex kirjoitti:

Havaitsen nyt kyllä ihan pelkkää halveksuntaa minua kohtaan...

Vaikea tuohon on muutenkaan suhtautua. Ihan oikeastiko tunnet, että osaat käyttää luokkia, ja tuoko on se, mihin niitä osaat käyttää? Tikahdun nauruuni...

Kertokaa mitä on pielessä, niin voin taas oppia jotain?
..koska se ainakin toimii minulla.

KeKimmo [17.07.2007 01:10:22]

#

Juhadex kirjoitti:

Mutta selvä... ei tarvitse odotella minua enään tänne kyselemään.

Miksei, jos kerran vastauksen sait nytkin? Kyllä se siitä :)

tkarkkainen [17.07.2007 01:11:40]

#

lainaus:

Menikö tämä aihe tosiaan minun pilkkaamiseen?

Jos meneekin, niin ei ihan aiheetta. Millaisen vastaanoton kuvittelit saavasi ylimielisellä asenteellasi? Väität koko ajan osaavasi asiat, joista esität seuraavassa lausessa tai kappaleessa kysymyksen. Vastaus kysymykseen löytyisi kyllä oppaista ja kirjallisuudesta, mutta tässä kohtaa menee jotain poikki.

Voisin diagnosoida, että innostuksesi tappaa kärsivällisyyden perusteiden opetteluun. Ilman perusteita ei vaan ole mitään edistyneempääkään.

Tämän viestin ei ole tarkoitus olla pilkkaava.

Ohjelmointiharrastuksellesi toivotan onnea.

Juhadex [17.07.2007 01:13:08]

#

tkarkkainen kirjoitti:

lainaus:

Menikö tämä aihe tosiaan minun pilkkaamiseen?

Jos meneekin, niin ei ihan aiheetta. Millaisen vastaanoton kuvittelit saavasi ylimielisellä asenteellasi? Väität koko ajan osaavasi asiat, joista esität seuraavassa lausessa tai kappaleessa kysymyksen. Vastaus kysymykseen löytyisi kyllä oppaista ja kirjallisuudesta, mutta tässä kohtaa menee jotain poikki.

Voisin diagnosoida, että innostuksesi tappaa kärsivällisyyden perusteiden opetteluun. Ilman perusteita ei vaan ole mitään edistyneempääkään.

Tämän viestin ei ole tarkoitus olla pilkkaava.

Ohjelmointiharrastuksellesi toivotan onnea.

Minä en ole ylimielinen ollenkaan. Olen pahoillani jos sellaisen käsityksen olette saaneet. Kirjoitusasuni ilmeisesti nyt vain vaikuttaa siltä =/
E: Noniin, kai on korkea aika tunnustaa, että en ole ollut 3 viikkoon pihalla muun erään stressaavan tapahtuman ohella ja se kai vaikuttaa olemukseeni.
Sanon ihan vain, ettette saisi minusta aivan väärää käsitystä. Ei muisteta pahalla 0.0
Minua tosin jäi vieläkin häiritsemään mikä tuossa minun pienessä esimerkissä nyt oli NIIN pielessä :D

Metabolix [17.07.2007 01:34:21]

#

Juhadex kirjoitti:

Minua tosin jäi vieläkin häiritsemään mikä tuossa minun pienessä esimerkissä nyt oli NIIN pielessä :D

Se, että siinä ei ole mitään järkeä. Miksi tehdä noin, kun voi suoraan mainiin laittaa nuo kolme tulostettavaa riviä ja koodi mahtuu parille riville? Et selvästi ymmärrä alkuunkaan, mihin luokkia on tarkoitus käyttää ja mitä niillä voi tehdä. Oppisit paljon paremmin, kun unohtaisit nyt ensin kokonaan sanat class ja struct ja opettelisit tavallisia muuttujia ja funktioita niin, että oikeasti osaisit käyttää niitä.

Juhadex [17.07.2007 01:35:51]

#

Metabolix kirjoitti:

Juhadex kirjoitti:

Minua tosin jäi vieläkin häiritsemään mikä tuossa minun pienessä esimerkissä nyt oli NIIN pielessä :D

Se, että siinä ei ole mitään järkeä. Miksi tehdä noin, kun voi suoraan mainiin laittaa nuo kolme tulostettavaa riviä ja koodi mahtuu parille riville? Et selvästi ymmärrä alkuunkaan, mihin luokkia on tarkoitus käyttää ja mitä niillä voi tehdä. Oppisit paljon paremmin, kun unohtaisit nyt ensin kokonaan sanat class ja struct ja opettelisit tavallisia muuttujia ja funktioita niin, että oikeasti osaisit käyttää niitä.

No haloo sehän on -harjoitus- ;)
Enhän minä mitään softia vielä ole tekemässä.
Jostainhan se on aloitettava... tuskin itsekkään teit mitään tuon kummoisempaa aluksi.

Metabolix [17.07.2007 01:52:03]

#

Juhadex kirjoitti:

Jostainhan se on aloitettava... tuskin itsekkään teit mitään tuon kummoisempaa aluksi.

Aluksi en tehnyt luokkia vaan opettelin ne perusasiat kunnolla. Vaan katsotaanpa sitten sitä ensimmäistä luokkaani... Tähän ei varmaankaan lasketa niitä Delphin valmiskomponenteista periytettyjä tekstilaatikoita sun muita graafisia otuksia, kun ne eivät ole varsinaisesti itse tehtyjä. Yhtä kehnoa säieajastinta myös parantelin joskus muinoin. Mutta ensimmäinen aivan oma taitaa olla tuo pisteluokka, joka pitää sisällään x-, y- ja z-koordinaatit sekä kaksi kulmaa (joita olen sittemmin oppinut kutsumaan Eulerin kulmiksi) ja jolle voi siis asettaa kulmat, muuttaa kulmia, lukea kulmat (kaikki tietenkin sekä asteina että radiaaneina), asettaa sijainnin, muuttaa sijaintia, lukea sijainnin ja tietenkin vielä liikuttaa annetun verran kulmien määräämään suuntaan. Muuttujat ja pari apufunktiota ovat näköjään yksityisiä, nuo lueteltuihin kykyihin liittyvät funktiot julkisia. Ja tämä siis oli minusta äärimmäisen triviaali luokka.

Äläpä tee tuollaisia oletuksia muista. Kun osaa aiemmat asiat, voi ensimmäisen luokankin tehdä kunnolla ilman mitään vaikeuksia.

Juhadex [17.07.2007 01:57:27]

#

Itseasiassa lukiessani tuota, nyt vasta haistoin olioiden suuren merkityksen... no ei mitään.. vaikka pilkkaatte ja halveksutte minua, niin silti opetatte minua... jatkakaa vain xD

(Mod. Edit. Voisit säästellä lainauksia, turha on aina koko edellistä viestiä lainata. Keskustelu muuttuu noin aivan toden teolla sotkuiseksi, ja esimerkiksi tässä tapauksessa on jo muutoinkin päivänselvää, mihin viestiin viittaat.)

tesmu [17.07.2007 13:06:00]

#

Metabolix kirjoitti:

Jos aivan välttämättä haluat kysymykseesi suoran vastauksen, niin x86-arkkitehtuureilla return 0 siirtää prosessorin eax-rekisteriin arvon 0, ja sieltä se funtkiota kutsunut paikka voi siirtää sen edelleen vaikkapa johonkin muistissa olevaan muuttujaan.

Ja käytännön hyöty tästä on se että voidaan palauttaa virhekoodi jollon järjestelmä tietä että ohjelmassa on tapahtunut jokin virhe...

Ja return 0 luonnollisesti on ei virheitä.

Metabolix [17.07.2007 18:06:54]

#

tesmu kirjoitti:

Ja käytännön hyöty tästä on se että voidaan palauttaa virhekoodi jollon järjestelmä tietä että ohjelmassa on tapahtunut jokin virhe...

Voihan niitä arvoja palauttaa muualtakin kuin main-funktiosta käyttöjärjestelmälle, ja kummatkin täällä jo annetut esimerkit näyttävät, että hyöty on aivan muu kuin virheilmoitus.


Sivun alkuun

Vastaus

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

Tietoa sivustosta