Page 27 of 50

Re: C++ -kysymykset

Posted: Wed Apr 22, 2009 11:00 am
by matti3
Juu. Ja kerron saman tien toisen tavan, kun tässä C++ lueskelin. :P

system("pause");

Tuo pysäyttää sen joten se ei katoa siitä. :)

Re: C++ -kysymykset

Posted: Wed Apr 22, 2009 11:53 am
by anttipanda
... ja kolmas tapa on käyttää sellaista IDE:ä/kääntäjää joka osaa lisätä moisen kyselyn automaattisesti kehitysaikana.

Re: C++ -kysymykset

Posted: Wed Apr 22, 2009 7:53 pm
by lukutoukka
Noniin, nyt aloitin koodaamisen ja testaan liittää kirjastoja, joita käytän mukaan, niin aloitin SDL:n liittämisellä. Laitoin linkkeriin -lSDL ja -lSDLmain liput, sekä include <SDL/SDL.h>. Nyt sitten tulee seuraava virhesanoma:

Code: Select all

  [Linker error] undefined reference to `WinMain@16' 
  ld returned 1 exit status 
 C:\Dev-Cpp\MinChat\Makefile.win [Build Error]  [MinChat.exe] Error 1 
Noniin tämän jälkeen, niin miten saan SDL_net kirjaston asennettua, eli pitääkö tuossa siirtää tuonne Dev-cpp kansioon joitan systeemejä.

Re: C++ -kysymykset

Posted: Wed Apr 22, 2009 8:38 pm
by zHelmet
@lukutoukka: lisää linkkeriin vielä -lmingw32 niin pitäisi toimia

Re: C++ -kysymykset

Posted: Wed Apr 22, 2009 8:42 pm
by lukutoukka
Ei auttanut tuo lisäys

PS: Ohjelma toimii, kun poistan include <SDL/SDL.h> kutsun ja koodissa ei ole tämän lisäksi kuin minimaalinen main osio:

Code: Select all

int main(int argc, char *argv[]) {
    return 1;
}
EDIT:

Noniin ongelmassa päästy eteenpäin, eli luin muutaman ohjeen netistä ja sain seuraavanlaisen sähellyksen:
-lmingw32
-lSDL
-lSDLmain
-mwindows

ja ny virhekoodi on seuraava:

Code: Select all

 C:\Dev-Cpp\lib\libSDLmain.a(SDL_win32_main.o)(.text+0x2ec) In function `console_main': 
  [Linker error] undefined reference to `SDL_strlcpy' 
  [Linker error] undefined reference to `SDL_Init' 
  [Linker error] undefined reference to `SDL_GetError' 
  [Linker error] undefined reference to `SDL_SetModuleHandle' 
  [Linker error] undefined reference to `SDL_main' 
 C:\Dev-Cpp\lib\libSDLmain.a(SDL_win32_main.o)(.text+0x42b) In function `WinMain': 
  [Linker error] undefined reference to `SDL_strlcpy' 
  [Linker error] undefined reference to `SDL_strlcat' 
  [Linker error] undefined reference to `SDL_strlcpy' 
  [Linker error] undefined reference to `SDL_strlcat' 
  [Linker error] undefined reference to `SDL_strlcpy' 
 C:\Dev-Cpp\lib\libSDLmain.a(SDL_win32_main.o)(.text+0x195) In function `cleanup': 
  [Linker error] undefined reference to `SDL_Quit' 
 C:\Dev-Cpp\lib\libSDLmain.a(SDL_win32_main.o)(.text+0x195) ld returned 1 exit status 
[/edit]

Re: C++ -kysymykset

Posted: Thu Apr 23, 2009 3:34 pm
by Sami The Great
lukutoukka wrote:Ei auttanut tuo lisäys

PS: Ohjelma toimii, kun poistan include <SDL/SDL.h> kutsun ja koodissa ei ole tämän lisäksi kuin minimaalinen main osio:

Code: Select all

int main(int argc, char *argv[]) {
    return 1;
}
EDIT:

Noniin ongelmassa päästy eteenpäin, eli luin muutaman ohjeen netistä ja sain seuraavanlaisen sähellyksen:
-lmingw32
-lSDL
-lSDLmain
-mwindows

ja ny virhekoodi on seuraava:

Code: Select all

 C:\Dev-Cpp\lib\libSDLmain.a(SDL_win32_main.o)(.text+0x2ec) In function `console_main': 
  [Linker error] undefined reference to `SDL_strlcpy' 
  [Linker error] undefined reference to `SDL_Init' 
  [Linker error] undefined reference to `SDL_GetError' 
  [Linker error] undefined reference to `SDL_SetModuleHandle' 
  [Linker error] undefined reference to `SDL_main' 
 C:\Dev-Cpp\lib\libSDLmain.a(SDL_win32_main.o)(.text+0x42b) In function `WinMain': 
  [Linker error] undefined reference to `SDL_strlcpy' 
  [Linker error] undefined reference to `SDL_strlcat' 
  [Linker error] undefined reference to `SDL_strlcpy' 
  [Linker error] undefined reference to `SDL_strlcat' 
  [Linker error] undefined reference to `SDL_strlcpy' 
 C:\Dev-Cpp\lib\libSDLmain.a(SDL_win32_main.o)(.text+0x195) In function `cleanup': 
  [Linker error] undefined reference to `SDL_Quit' 
 C:\Dev-Cpp\lib\libSDLmain.a(SDL_win32_main.o)(.text+0x195) ld returned 1 exit status 
[/edit]
Epäilen, että et ole linkittänyt headereita. Eli laita se include takaisin sinne koodiin. Ja main funktion tulisi palauttaa 0, jos suoritus onnistui eikä 1.

Re: C++ -kysymykset

Posted: Thu Apr 23, 2009 4:24 pm
by lukutoukka
noniin, tuossa ohjelmassa on nyt return 0 ja include <SDL/SDL.h> ja edelleenkin ilman tuota <SDL/SDL.h> tuo toimii oikein, eli miten tämän saisi korjattua?

Re: C++ -kysymykset

Posted: Thu Apr 23, 2009 4:45 pm
by Sami The Great
lukutoukka wrote:noniin, tuossa ohjelmassa on nyt return 0 ja include <SDL/SDL.h> ja edelleenkin ilman tuota <SDL/SDL.h> tuo toimii oikein, eli miten tämän saisi korjattua?
Muttä eihän SDL toimi ilman sen header filuja. Eli tuon SDL.h:n includettaminen on välttämätöntä, jos haluat SDL:ää käyttää. Mitä virhe sanomaa kääntäjä antaa, jos yrität includettaa SDL.h:ta?

Re: C++ -kysymykset

Posted: Thu Apr 23, 2009 4:51 pm
by lukutoukka
pelkkää SDL.h:ta kutsuessa se sanoo, että sitä ei ole, mutta muuloin tuo edellinen virhesanoma tuli kun oli tuo <SDL/SDL.h> include ja SDL:n olen asentanut parikin kertaa uudestaan, eli mikäköhän vikana?
EDIT:

ONGELMA RAKTAISTU!

Syynä oli lippujen väärä järjestys, eli -lSDLmain ennen -lSDL:ää.


Re: C++ -kysymykset

Posted: Fri May 01, 2009 1:18 pm
by Flip
Pikaseen voisin kysellä miten pointterit toimivat funktioissa? Oisko jotain lyhyttä toimivaa esimerkkiä tarjota? Itse olen kokeillut näin, mutta tämä palauttaa jotain ihan muuta mitä haluaisin (tulostuksena pitäisi olla "39"):

Code: Select all

#include <iostream>
using namespace std;

int *PalautaPointer(int p)
{
	return &p;
}

int main(void)
{
	int Lukema = 39;
	int * pLukema = PalautaPointer(Lukema);

	cout << *pLukema << endl;
	
	system("PAUSE");
	return EXIT_SUCCESS;
}

En ole varma ymmärsinkö edes tuota "osoittaja funktiossa"-osaa hassun hauskassa c++ oppaassa oikein. Mulla oli joskus hyvä c++ -kirja jossa asia oli selitetty siten että ymmärsin sen, en enää vain muista miten se meni.

Re: C++ -kysymykset

Posted: Fri May 01, 2009 1:23 pm
by Koodiapina
Tässä on varmaan turhaa sekoilua, mutta ainakin toimii.

Code: Select all

#include <iostream>
using namespace std;

int *PalautaPointer(int &p)
{
   return (int*)p;
}

int main(void)
{
   int Lukema = 39;
   int * pLukema = PalautaPointer(Lukema);

   cout << (int)pLukema << endl;
}

Re: C++ -kysymykset

Posted: Fri May 01, 2009 1:36 pm
by Flip
Niinnojuu tuo toimii, muttei kuitenkaan kovin selkeästi:

Code: Select all

cout << (int)pLukema << endl;  ->  cout << pLukema << endl;
 => Tulostaa taas melkeinpä mitä sattuun.

cout << (int)pLukema << endl;  ->  cout << *pLukema << endl;
 => Ohjelma kaatuu.
Jos jollain olisi vielä selvempi esimerkki?

Re: C++ -kysymykset

Posted: Fri May 01, 2009 1:43 pm
by Koodiapina
Käsitit väärin. Se toimii myös muodossa:

Code: Select all

cout << pLukema << endl;
Mutta tulostaa tällöin tuloksen heksana. 0x27 on desimaaleina 39, eli haluttu tulos.

Re: C++ -kysymykset

Posted: Fri May 01, 2009 2:01 pm
by Flip
Aijuu no juu no jaa. ok.

http://www.cplusplus.com/doc/tutorial/pointers/
Tuollaisen löysin, luulen että tuo auttaa enemmän. Mut kiitos kuitenkin yrityksestä :)

Re: C++ -kysymykset

Posted: Mon May 04, 2009 9:41 am
by anttipanda
No osoittimista sanon sen että niitä kannattaa käyttää erittäin harkiten - viittaukset ovat yleensä aivan riittäviä. Yksi tavanomaisimmista tilanteista milloin osoittimia käytetään on se, kun metodin/funktion täytyy luoda osoitemuuttujalle olio. Esimerkki missä funktio palauttaa luodun olion osoitteen:

Code: Select all

MyObject* createObject(const string& tag)
{
    // Palautetaan juuri luodun olion osoite
    return new MyObject( tag, ", no changes made" );
}
Jos taas halutaan vain antaa suurehko olio parametrina, kannattaa käyttää const-viittausta. Se tarkoittaa että oliota ei kopioida, vaan pelkkä viittaus siihen annetaan funktiolle, mutta kuitenkaan oliota ei voi muokata funktion sisällä. Tämä vähentää ohjelmointivirheiden riskiä. Lisäksi luettavuuksin on parempi kun voidaan käyttää pisteoperaattoria.

Code: Select all

void printObject( const MyObject& object )
{
    // Täällä object-oliota voi vain tarkastella, ei muokata. Täällä kutsuttavien MyObjectin metodien tulee päättyä const-sanaan! Kts. tag() alempana.
    cout << object.tag() << endl;
}
Jos taas oliota halutaan muokata funktion sisällä, voidaan käyttää tavallista viittausta. Oliota itseään ei voi tosin vaihtaa tai tuhota, mutta se on tarkoituskin.

Code: Select all

void changeTag( MyObject& object, const string& newTag )
{
    // Täällä tehdyt muutokset näkyvät myös viitattavassa oliossa
    object.setTag( newTag );
}
Jos funktiossa halutaan muuttaa itse oliota johon osoitin osoittaa, käytetään viittausta osoittimeen. Tällöin täytyy varmistaa ettei edellinen olio vuoda kun osoittimen arvo vaihtuu. Tätä tyyliä voidaan käyttää myös jos ei haluta palauttaa luotua oliota, esimerkiksi jos halutaan palauttaa virhekoodi tai jos halutaan luoda useita eri olioita samalla funktiolla.

Code: Select all

void reallocateObject( MyObject*& pointer )
{
	// Ennenkuin osoittimeen laitetaan tavaraa, on hyvä varmistaa ettei muisti vuoda
	delete pointer;
	pointer = NULL;

	// Luodaan uusi olio
	pointer = createObject("reallocated object");
}
Tuossa on mielestäni kaksi käyttökelpoista tapaa osoittimille funktiossa, ja pari tapaa viittauksillekin. On toki tuhat ja yksi tapaa jolla osoittimia voi käyttää, mutta tärkeintä on pitää ohjelma selkeänä, ja käyttää aina samanlaisia tapoja samoihin asioihin. Olen huomannut että jos osoittimia joudutaan käyttämään "eksoottisesti", on jokin muu usein pielessä.

Tietenkin osoittimia tulee käyttää silloin kun täytyy (esim. API:t jotka vaativat osoittimia, tai kun muokataan taulukoita tai esimerkiksi kuvapuskureja), mutta se ei nyt kuulu tähän. Tässä vielä kääntyvä esimerkki noista äskeisestä:

Code: Select all

#include <iostream>
#include <string>

using namespace std;

class MyObject
{
public:
	MyObject(const string& tag, const string& somethingElse)
	{
		m_tag = tag + somethingElse;
	}

	void setTag(const string& newTag)
	{
		m_tag = newTag;
	}

	// Tämä on const-loppuinen, koska se ei muuta oliota sisäisesti
	const string& tag() const
	{
		return m_tag;
	}

private:
	string m_tag;
};

MyObject* createObject(const string& tag);
void printObject( const MyObject& object );
void changeTag( MyObject& object, const string& newTag );
void reallocateObject( MyObject*& pointer );

int main(const int&)
{
	// Luodaan uusi olio ja tulostetaan
	MyObject* myObject = createObject("tadaa");
	printObject( *myObject );

	// Muutetaan sen tilaa
	changeTag( *myObject, "let's change the state, shall we?" );
	printObject( *myObject );

	// Luodaan uusi olio entisen "tilalle"
	reallocateObject( myObject );
	printObject( *myObject );

	return 0;
}

MyObject* createObject(const string& tag)
{
    // Palautetaan juuri luodun olion osoite
    return new MyObject( tag, ", no changes made" );
}

void printObject( const MyObject& object )
{
    // Täällä object-oliota voi vain tarkastella, ei muokata. Täällä kutsuttavien MyObjectin metodien tulee päättyä const-sanaan! Kts. tag() alempana.
    cout << object.tag() << endl;
}

void changeTag( MyObject& object, const string& newTag )
{
    // Täällä tehdyt muutokset näkyvät myös viitattavassa oliossa
    object.setTag( newTag );
}

void reallocateObject( MyObject*& pointer )
{
	// Ennenkuin osoittimeen laitetaan tavaraa, on hyvä varmistaa ettei muisti vuoda
	delete pointer;
	pointer = NULL;

	// Luodaan uusi olio
	pointer = createObject("reallocated object");
}

Re: C++ -kysymykset

Posted: Wed May 13, 2009 8:29 pm
by lukutoukka
Noniin, koodasin C++ ja SDL pientä hienoa isometristä grafiikkaengineä ja sain tämän menemään kääntäjästä läpi, mutta en ymmärrä, mitä minä pystyin mokaamaan tässä, eli voitteko auttaa, mikä meni auttamattomasti vikaan? Samalla myös parannusehdotukset sallittuja siitä, miten joku kohta kannattaisi tehdä ennemmin.

Code: Select all

#include <cstdlib>
#include <cstdio>

#ifdef __APPLE__
#include <SDL/SDL.h>
#else
#include <SDL.h>
#endif

#include <string>

//FUNKTIOT

// Erittäin alkeellinen kuvien piirtämiseen tarkoitettu funktio
void PiirraKuva(SDL_Surface *kuva, SDL_Surface *naytto, int x, int y)
{

    SDL_Rect alue; // mille alueellä näyttöä kuva piirretään
    alue.x = x; // koordinaatit
    alue.y = y;
    SDL_BlitSurface(kuva, NULL, naytto, &alue); // piirto
}

// Pelikentän tiedot sisältävä olio
class Huone
{
    private:
        unsigned int sx; // Huoneeseen tultaessa sisäänkäynti ja uloskäynti
        unsigned int sy;

        unsigned int kentta [50][50]; //Kentän koko
    public:
        Huone(int x, int y);
        ~Huone();
        int Nayta(unsigned int x, unsigned int y);
};

Huone::Huone (int x, int y)
{
    sx = x; // Sisäänkäynnin koordinaatit asetetaan oikeiksi
    sy = y;

    for (int x = 0; x < 50; x++) //Alustetaan taulukko
    {
        for (int y = 0; y < 50; y++)
        {
            kentta[x][y] = 0; // Laitetaan kentän tiedot 0, joka tarkoittaa tyhjää maastoa
        }
    }

}

Huone::~Huone()
{
   ;
}

int Huone::Nayta(unsigned int x, unsigned int y)
{
    return 0;
}

// Pelaajan tiedot säilövä olio
class Hahmo
{
    private:
        unsigned int x; // Pelaajan koordinaatit
        unsigned int y;
        unsigned int alue; //Millä alueella pelaaja on
    public:
        Hahmo();
        ~Hahmo();
        void Liiku(int suunta); // Liikutetaan pelaajaa
        void NaytaYmparisto(Huone& Kentta, SDL_Surface* ruohikko, SDL_Surface* Naytto); // Pelaajan ympäristö näkyviin
        void AsetaPaikka(int ux, int uy); //Pelaajalle asetetaan joku paikka
};

Hahmo::Hahmo()
{
    x = 0;
    y = 0;
    alue = 0;
}

Hahmo::~Hahmo()
{
    ;
}

void Hahmo::AsetaPaikka(int ux, int uy)
{
    x = ux;
    y = uy;
}

void Hahmo::NaytaYmparisto(Huone& Kentta, SDL_Surface *ruohikko, SDL_Surface *naytto)
{
    for (unsigned int ax = 0; ax < 50; ax++) //Tarkastetaan, että ollaanko tarpeeksi lähellä piirtääksemme karttaan
    {

        if (ax > x - 10 and ax < x + 10)
            {

                for (unsigned int ay = 0; ay < 50; ay++)
                {
                    if (ay > y - 10 and ay < y + 10)
                    {
                        if (Kentta.Nayta(ax, ay) == 0)
                        {
                            PiirraKuva(ruohikko, naytto, ((ax-x)*25)+((ay-y)*(-25)), ((ax-x)*25)+((ay-y)*25));
                        }
                    }
                }
            }
    }
}


//PÄÄFUNKTIO
int main ( int argc, char** argv )
{
    // initialize SDL video
    if ( SDL_Init( SDL_INIT_EVERYTHING ) < 0 )
    {
        printf( "SDL:n alustus epäonnistui: %s\n", SDL_GetError() );
        return 1;
    }

    // Varmistaa, että SDL suljetaan ennen lopettamista
    atexit(SDL_Quit);

    // Luodaan näyttö                      x,   y,   värisyys
    SDL_Surface* naytto = SDL_SetVideoMode(640, 480, 32,
                                           SDL_HWSURFACE|SDL_DOUBLEBUF);
    if ( !naytto )
    {
        printf("Näyttösi ei tue 640, 280, 32 näyttötilaa: %s\n", SDL_GetError());
        return 1;
    }

    // Ladataan kuvat
    SDL_Surface* ruohikko = SDL_LoadBMP("Kuvat/ruoho.bmp");
    SDL_SetColorKey(ruohikko, SDL_SRCCOLORKEY, SDL_MapRGB(ruohikko->format,255,0,255));

    SDL_Surface* hahmo = SDL_LoadBMP("Kuvat/hahmo.bmp");
    SDL_SetColorKey(hahmo, SDL_SRCCOLORKEY, SDL_MapRGB(hahmo->format,255,0,255));

    //Luodaan Pelaaja, sekä kartta
    Hahmo Pelaaja; // Luodaan pelaaja
    Huone Kentta(0,0); // Luodaan testikenttä

    // PÄÄSILMUKKA
    bool done = false;
    while (!done)
    {
        // Syötteiden tarkistus
        SDL_Event event;
        while (SDL_PollEvent(&event))
        {
            // Tarkistetaan syötteen tyyppi
            switch (event.type)
            {
                // Sulkemisnäppäimestä sulkeminen
            case SDL_QUIT:
                done = true;
                break;

                // Varsinainen näppäintentarkistus
            case SDL_KEYDOWN:
                {
                    // Jos painetaan esc:iä, niin suljetaan
                    if (event.key.keysym.sym == SDLK_ESCAPE)
                        done = true;
                    break;
                }
            } // Lopetetaan syötteiden tarkistus
        } // Lopetetaan syötteiden luku

        // PIIRTÄMINEN ALKAA TÄSTÄ

        // Puhdistetaan ruutu
        SDL_FillRect(naytto, 0, SDL_MapRGB(naytto->format, 0, 0, 0));

        Pelaaja.NaytaYmparisto(Kentta,ruohikko,naytto);

        // PIIRTÄMINEN LOPPUU TÄSSÄ

        // Näytölle piirtäminen
        SDL_Flip(naytto);
    } // PÄÄSILMUKKA LOPPUU

    // Vapautetaan kuvien käyttämä muisti
    SDL_FreeSurface(ruohikko);
    SDL_FreeSurface(hahmo);

    // Tulostetaan kaiken onnistuneen oikein
    printf("Ohjelma suljettiin onnistuneesti\n");
    return 0;
}
ja tuon käyttämät kuvat ovat seuraavat erittäin yksinkertaiset testikuvat ovat bmp muodossa ja koko on 50*50 px ja niiden pitäisi muodostaa isometrinen neliö, jotka lähtevät reunojen keskeltä 25px kohdalta. 45 asteen kulmassa toiseen reunaan. Läpinäkyvänä värinä 255,0,255. Oisin itse antanut kuvan tähän, mutta ei pystynyt lataan bmp tiedostoa foorumille :(. Toivottavasti tuo ei ole liian iso vaiva, jotta voisitte tarkistaa ohjelmani virheen, jota en löydä itse kirveelläkään tuolta (tai sitten en vain havaitse ilmiselvää virhettä...)

Re: C++ -kysymykset

Posted: Thu May 14, 2009 11:29 am
by anttipanda
Mitenpä lukutoukko se virhe ilmenee? Et selittänyt mikä virhe on kyseessä.

Re: C++ -kysymykset

Posted: Thu May 14, 2009 4:49 pm
by lukutoukka
Ai, sekö tässä unohtui, no tuon pitäisi piirtää kuvia ruudulle, mutta ei onnistu, mutta löysin nyt sen ongelmankin siellä, kun koodasin hieman erilälailla tuon systeemini.

Re: C++ -kysymykset

Posted: Sun May 17, 2009 12:20 am
by zHelmet
Olisiko jollain jotain linkkiä johonkin yksinkertaiseen oppaaseen (suomeksi) jossa opetetaan yhdistämään luokan sisään structuri??

Re: C++ -kysymykset

Posted: Sun May 17, 2009 1:09 pm
by Sami The Great
zHelmet wrote:Olisiko jollain jotain linkkiä johonkin yksinkertaiseen oppaaseen (suomeksi) jossa opetetaan yhdistämään luokan sisään structuri??
Se ei ole vaikeaa jos tätä mietit:

Code: Select all

struct PelaajanKoordinaatit
{
    float x;
    float y;
    float z;
};

class Pelaaja
{
private:
PelaajanKoordinaatit koordinaatit;
};