PDA

Tam Sürümünü Görmek İçin : pointer pointer'i


sakruh
31/10/2007, 13:47
merhaba arkadaslar,

pointer pointer'i ile ile ilgili bilgi verebilir misiniz ? kullanim alani nedir ? syntax sekli nasildir ?..

tesekkurler...


Euclides
31/10/2007, 14:18
int **p;
int ***p;
int ********p;
şeklinde olabilir.
Amacı kodu daha okunaklı ve anlaşılır yapmaktır. "Bu değişkenin değeri bir pointer" demek yerine yapılabilir
int *p;
int iTmp = 0;
void dosomething(int **pX)
{
*pX = &iTmp;
}
main()
{
dosomething(&p);
(*p)++;
}

acehreli
31/10/2007, 20:35
Okunaklilik ve anlasilirlik yaninda olayin gereklilik yani da var tabii ki. ;)

Son zamanlarda hasir nesil oldugum bir C ortaminda asagidaki gibi bir yapinin benimsendigini gordum. O ortamda yapilari hemen hemen hic yigitta otomatik olarak tutmuyorlar. Ayni Java'da oldugu gibi, nesneleri hep dinamik bellekte yasiyorlar.

Soyle bir sey; kodun icin bir kac aciklama satiri da koydum...


#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

typedef struct
{
int i;
double d;
} Kayit;

/* Oylesine bir islev... Asagida bir hata denetimi icin yazdim */
double foo(double d)
{
return d * 3;
}

/*
Bu, bir takim islemler yaparak yeni bir nesne olusturuyor ve kendisine
verilen isaretcinin gosterdigi isaretcinin o nesneyi gostermesini
sagliyor.
*/
int Kayit_olustur(Kayit ** birKayit, int i, double d)
{
int hata = 0;
Kayit * yerelKayit = NULL;

// Bana verilen parametre kullanilabilir olmali:
assert((birKayit != NULL) && (*birKayit == NULL));

yerelKayit = malloc(sizeof(*birKayit));

if (!yerelKayit) {
// Bellekte yer ayiramadik; devam edemeyiz
hata = 1;
goto cikis;
}

yerelKayit->i = i;
yerelKayit->d = foo(d);

if (yerelKayit->d > 12.34) {
// Bu da baska bir hata durumu olsun; yine devam edemeyiz
hata = 2;
goto cikis;
}

// hersey yolunda gittigine gore, artik birKayit'i degistirebiliriz;
// yerelKayit'in sahip oldugu nesneyi birKayit'e aktariyoruz.
*birKayit = yerelKayit;
yerelKayit = NULL;

cikis:

free(yerelKayit);
return hata;
}

/*
Kendisine verilen isaretci isaretcisinin gosterdigi nesneyi silmek
yaninda, ayrica bu isaretcinin, kendisini cagiran ortamda da NULL
olmasini sagliyor. Boylece artik cagiranin ortanminda da kullanilamaz
hale geliyor.
*/
int Kayit_geriVer(Kayit ** birKayit)
{
free(*birKayit);
*birKayit = NULL;

return 0;
}

int main()
{
int hata = 0;
Kayit * birKayit = NULL;

hata = Kayit_olustur(&birKayit, 42, 1.2);
if (hata) goto cikis;

// birKayit simdi gecerli bir nesneyi gosteriyor olmali:
assert(birKayit != NULL);

printf("i: %d d: %f\n", birKayit->i, birKayit->d);

hata = Kayit_geriVer(&birKayit);
if (hata) goto cikis;

// Simdi de geri verildigi icin NULL'i gosteriyor olmali:
assert(birKayit == NULL);

cikis:

free(birKayit);
return hata;
}


Ali

acehreli
31/10/2007, 20:41
Ha ha! :) Hata yapmisim; soyle olacak tabii ki:


yerelKayit = malloc(sizeof(**birKayit));


Bir utanc abidesi olarak programda degistirmiyorum... :)

Ali