Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: "Useita määrittelyitä"

Sivun loppuun

jsbasic [22.06.2010 13:20:16]

#

C++:ssa jäsenmuuttuja käsittääkseni esitellään ja alustetaan näin:

#ifndef PSETTER_H_INCLUDED
#define PSETTER_H_INCLUDED
#define KOKO 5

class Luokka {
   static const int taulukko[KOKO][KOKO];
};

const int Luokka::taulukko[KOKO][KOKO] =
        {{0, 1, 2, 1, 0},
        { 1, 3, 5, 3, 1},
        { 2, 5, 9, 5, 2},
        { 1, 3, 5, 3, 1},
        { 0, 1, 2, 1, 0}};

#endif // PSETTER_H_INCLUDED

Ensimmäisen luokan kanssa tuo toimi mutta toisen tekemäni luokan kanssa tuli virheilmoitus "Useita Luokka::taulukko määrittelyitä". Virheilmoitukset osoittaa minne sattuu. PSETTER_H_INCLUDED on yksilöllinen nimi.

Jokotai [22.06.2010 13:34:09]

#

Näyttäisitkö mitä oikein teit. Epäilen, että se voisi johtua taulukon staattisuudesta.

jsbasic [22.06.2010 15:17:55]

#

Luokka toimii kyllä kun otan toisesta projektiini kuuluvasta .cpp -tiedostosta pois includen tähän .h -tiedostoon:

/* luokka2.cpp */

//Tämä pois niin yllä oleva luokka toimii
#include "luokka.h"

Metabolix [22.06.2010 15:20:10]

#

Taulukon määrittely ei kuulu otsikkoon vaan cpp-tiedostoon (tässä ilmeisesti psetter.cpp). Muuten se sisällytetään ohjelmaan kerran jokaista cpp-tiedostoa kohti, mistä virheilmoituskin johtuu.

jsbasic [22.06.2010 16:44:08]

#

Siirsin alustuksen tuollaisenaan .cpp-tiedostoon ja alkoi toimia. Se onkin tietenkin paljon loogisempaa.

Hauskaa ettei tuo #ifndef - #endif suojaa taulukon alustamista (eli määrittelyä?), vaan pelkästään kuvailemista. Otsikkotiedostot siis ajetaan kahdella eri tavalla kääntäjässä. Ohjelmoijan pitää itse osata laittaa koodit oikeaan tiedostoon...

Metabolix [22.06.2010 17:27:46]

#

jsbasic kirjoitti:

Otsikkotiedostot siis ajetaan kahdella eri tavalla kääntäjässä.

Ei suinkaan, kaikki koodi käännetään tasan yhdellä tavalla. Kannattaa lukea oppaat C:n esikääntäjästä ja C++:n esittelyistä ja määrittelyistä sekä koodivinkit koodin jakamisesta tiedostoihin C-tyylisen ja C++-tyylisen koodin tapauksissa. Jos näiden jälkeen vielä on epäselvyyttä siitä, miksi yhdellä tavalla toimii ja toisella ei, kysy toki. :)

jsbasic [22.06.2010 19:42:15]

#

Taulukoihin ja olioihin liittyen olisi vielä tyhmä kysymys:

Kun olion konstruktori tai metodi ottaa vastaan taulukon näin...

//triviaali esimerkki
void setTaulukko(char taulukko[])
{
   ...
}

...niin miten olion jäsenmuuttujaan voi tallentaa viittauksen syötettävästä taulukosta jotta olio voisi jatkossa käsitellä taulukkoa.

PS. Omassa erikoistapauksessa taulukko on muotoa const ja taulukon lukeminen pitäisi olla nopeaa.

os [23.06.2010 21:27:52]

#

Voit tallentaa viittauksen pointteriin näin

class A
{
private:
	int *t;

public:
	void set(int t1[]) { t = t1; }
};

jsbasic [24.06.2010 10:54:25]

#

Mutta entäs 2-ulotteinen taulukko?

Näin saa tehtyä osoittimen 2-ulotteiseen taulukkoon mutta sitä voi käsitellä vain 1-ulotteisena.

int taulukko[][]={{1,2,3},{4,5,6},{7,8,9}};
int *osoitin;
osoitin = *taulukko;
int kolmasAlkio = *(osoitin+2);

No, taulukkoa on nopeampi käsitellä 1-ulotteisena. Kaksiulotteiseen taulukkoon osoittaminen vaatii kuitenkin jossain sen kertolaskun, eikö niin?

os [24.06.2010 20:56:22]

#

Tuollaisten nopeuserojen miettiminen on ennenaikaista optimointia, joka on tunnetusti kaiken pahan alku ja juuri. Lisäksi laskutoimitusten määrä ja laatu eivät määrää suoraan ohjelman suoritusnopeutta.

Kaksiulotteiseen C-taulukkoon voit kuitenkin viitata tuplapointterilla.

int t[][] = {{1,2},{3,4}};
int **p = t;

Kannattaa muistaa, että kaksiulotteisen taulukon käsittely yksiulotteisena onnistuu vain tietyissä tapauksissa.


Sivun alkuun

Vastaus

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

Tietoa sivustosta