[ glorius @ 06.12.2007. 11:26 ] @
Evo jednog standardnog primera izgradnje liste:

Ovaj kod ne radi:

Code:


#include <iostream>
using namespace std;

class List
{
public:
    int data;
    List * pNext;

    List() : data(0), pNext(0) {}
    List(int d) : data(d), pNext(0) {}
};

void AddNode(List * pHead, int data)
{
    List * n = new List(data);

    if(!pHead)
    {
        pHead = n;
        return;
    }

    AddNode(pHead->pNext, data);
}

void Stampaj(List * pHead)
{
    if(pHead)
    {
        cout << pHead->data << endl;
    }

    if(pHead->pNext)
        Stampaj(pHead->pNext);
}

void main()
{
    List * pHead = 0;

    AddNode(pHead, 3);

    Stampaj(pHead);

}



Greska je u AddNode funkciji... Ona bi trebala ovako da bude napisana:

Code:


List * AddNode(List * pHead, int data)
{
    List * n = new List(data);

    if(!pHead)
    {
        pHead = n;
        return pHead;
    }

    pHead->pNext = AddNode(pHead->pNext, data);
 
             return pHead;
}



'Idealno' resenje za ovo je:

Code:


#include <iostream>
using namespace std;

class List
{
public:
    int data;
    List * pNext;

    List() : data(0), pNext(0) {}
    List(int d) : data(d), pNext(0) {}
};

void AddNode(List ** pHead, int data)
{
    List * n = new List(data);

    if(!*pHead)
    {
        *pHead = n;
        return;
    }

    AddNode(&((*pHead)->pNext), data);
}

void Stampaj(List * pHead)
{
    if(pHead)
    {
        cout << pHead->data << endl;
    }

    if(pHead->pNext)
        Stampaj(pHead->pNext);
}

void main()
{
    List * pHead = 0;

    AddNode(&pHead, 3);
    AddNode(&pHead, 4);

    Stampaj(pHead);

}



Mozda sam nesge pogresio ali, glavni problem je:

U prvom primeru, pHead ostaje NEPROMENJEN...
U drugom primeru, gde funkcija AddNode vraca pHead, on se menja i u glavnom programu.
U trecem primeru se pHead menja i bez vracanja iz funkcije...

Zasto je ovde potrebno raditi sa 'dvostrukim' pokazivacima da bi pNode bio promenjen u funkciji kada je i on sam, pokazivac?
[ NastyBoy @ 06.12.2007. 15:07 ] @
Prelistaj pointere josh koji put, tj. pitaj sebe da li menjash sam pointer, ili ono na shta pokazuje pointer?

Inache, ovo je C++, zashto pokushavash da napravish listu na C nachin, sa glavom liste koja je deklarisana ko zna gde u odnosu na ostatak liste? Kada napravish razliku izmedju chlana liste i same liste videcesh da ce nestati i inicijalni problem pointera.
[ glorius @ 06.12.2007. 17:29 ] @
Izvinjavam se na losem primeru...

Evo primera iz DirectX - a...

ID3DXMesh * pMesh = 0;
D3DXCreateMesh( &pMesh ); // funkcija ima jos parametara ali sam ih ovde zanemario

Znaci, funkcija uzima pokazivac na pokazivac jer se SAM pokazivac (pMesh) menja ( u ovom slucaju se konstruise u funkciji )...

Ne znam da li sam ovo dobro razumeo...

[ glorius @ 06.12.2007. 18:01 ] @
Mislim da sam skapirao...

I pointer je lokalna kopija ali ne i ono na sta pokazuje...

[code]
void Swap(int * a, int * b)
{
int * temp = a;
a = b;
b = temp;
}

void main()
{
int * a = new int(3);
int * b = new int(5);

// ovo ce im razmeniti adrese ali, posto su pointeri predati po vrednosti, swapping se desava nad lokalnim kopijama njihovih adresa
Swap(a, b);
}

[code]

RESENJE je da se predaju adrese pointera da bi se dereferenciranjem promenile originalne adrese pointera. WHHOH! :)