PO�NTER (G�STER�C�, ��ARET��)

Tan�mlanmas� ve Kullan�m�    Pointer Aritmeti�i    Pointerler ve Diziler    

Fonksiyonlar� Referans Yoluyla �a��rma (Call by Reference)     Pointerler ve Yap�lar

1. Tan�mlanmas� ve Kullan�m�

Bir veri blo�unun bellekte bulundu�u adresi i�eren (g�steren) veri tipidir. Tan�mlama bi�imi:

veri tipi *p; �eklindedir.

p de�i�keni <veri tipi> ile belirtilen tipte bir verinin bellekte sakland��� adresi i�erir.

int *iptr;

float *fptr;

Bu kadar tan�mlama sonucunda bellekte p de�i�keni mevcuttur. Ancak i�aret etti�i veri blo�u yoktur. Bunun i�in iki yol vard�r. Birincisi kullan�lan herhangi bir de�i�keni i�aret etmek, ikincisi ise veri blo�unu bo� belle�i kullanarak olu�turmakt�r.

I. Pointer De�i�kenin Var Olan Bir De�i�kenin Bulundu�u Adresi G�stermesi

Bu i�lemi yapabilmek i�in var olan de�i�kenin adresinin bilinmesi gerekmektedir.

&i�leci : Bir de�i�kenin adresinin belirlenmesi i�in kullan�l�r. Kullan�m bi�imi: �&de�i�ken� �eklindedir.

&i : i de�i�kenin adresini verir.

�rnek:

main()

{

int i;

int *iptr;

i = 5;

iptr = &i;

clrscr();

printf("i de�i�keninin adresi %p\n", &i);

printf("iptr de�i�keninin de�eri %p\n", iptr);

}

II. Veriye Pointer De�i�ken Yoluyla Eri�im

Bir pointerin g�sterdi�i adresteki veriye eri�mek i�in pointer de�i�keninin �n�ne * karakteri konur.

main()

{

int i;

int *iptr;

iptr = &i;

*iptr = 8; Ekranda ��kt� :

printf("i de�i�keninin de�eri %d\n", i); i de�i�keninin de�eri 8

printf("iptr adresinin i�eri�i %d\n", *iptr); iptr adresinin i�eri�i 8

}

2. Pointer Aritmeti�i

Pointer de�i�kenler �zerinde toplama ve ��kartma i�lemleri (++,--) ge�erlidir. Ancak eklenecek de�er tamsay� olmal�d�r. Pointer de�i�kenin de�eri 1 art�r�ld��� zaman de�i�ken bir sonraki veri blo�unu i�aret eder. De�i�kenin alaca�� yeni de�er pointer de�i�kenin ne tip bir veri blo�unu i�aret etti�ine ba�l�d�r.

int *iptr, i;

...

iptr = &i; i de�i�kenin adresinin 1000 oldu�unu varsayal�m. iptr nin de�eri 1000 dir.

iptr++; iptr nin de�eri 1002 olur. ( int de�eri i�aret etti�i i�in)

 Ayn� �rne�i double i�in yaparsak

double *iptr, i;

...

iptr = &i; i de�i�kenin adresinin 1000 oldu�unu varsayal�m. iptr nin de�eri 1000 dir.

iptr++; iptr nin de�eri 1008 olur. ( double de�eri i�aret etti�i i�in)

int *iptr, i, j;

...

iptr = &i; i de�i�kenin adresinin 1000 oldu�unu varsayal�m. iptr nin de�eri 1000 dir.

*(iptr+4)=2; 1008 adresinin i�eri�ini 2 yapar.

Uyar�: Artt�rma i�aret edilen veri blo�una g�re yap�l�r Yani bir sonraki veri blo�unun g�sterilmesi sa�lan�r.

iptr++ ; bir sonraki veri blo�unu g�sterir.

(*iptr)++; iptr de�i�keninin g�sterdi�i adresteki de�eri 1 artt�r.

3. Pointerler ve Diziler

Pointerler �zerinde ge�erli aritmetik yard�m�yla dizilere pointer de�i�kenler ile eri�mek m�mk�nd�r.

#include <stdio.h>

main()

{

int i[10], j;

int *iptr;

for (j=0; j<10; j++)

i[j]=j;

/* Dizinin ba�lang�� adresine eri�mek i�in ilk eleman�n adresi kullan�labilir &i[0] veya do�rudan */

iptr = i;

clrscr();

for (j=0; j<10; j++) {

printf("%d ", *iptr);

iptr++;

}

printf("\n");

/* iptr art�k dizinin ba��n� g�stermez */

iptr = i;

for (j=0; j<10; j++)

printf("%d ", *(iptr+j));

printf("\n");

/* iptr hala dizinin ba��n� g�sterir */

getch();

}

�rnek : Pointer ve dizi kullan�m�.

#include <stdio.h>

main()

{

char *a="1234567890";

char b[11];

char *p1, *p2;

printf("%s\n", a);

p1 = a;

p2 = b;

while (*p1 != '\0') {

*p2 = *p1;

p1++;

p2++;

}

printf("%s\n", b);

}

4. Fonksiyonlar� Referans Yoluyla �a��rma (Call by Reference)

�u ana yazd���m�z fonksiyonlarda g�nderilen parametrelerin (diziler hari�) de�erlerinin de�i�tirilmesi m�mk�n de�ildi. Fonksiyon �a��r�ld��� zaman parametrelerin bir kopyas� ��kart�l�p fonksiyona g�nderiliyordu. Bir fonksiyonun birden fazla de�er g�nderebilmesi i�in pointerlere gereksinimiz vard�r.

�rnek:

void arttir(int);

main()

{

int i;

i = 5;

printf("�ncesi %d\n", i);

arttir(i);

printf("sonras� %d\n", i);

getch();

}

void arttir(int k)

{

k++;

}

��kt� :

�ncesi 5

sonras� 5

G�nderilen parametrenin kopyas� fonksiyona g�nderildi�i i�in fonksiyon i�erisinde yap�lan de�i�iklikler fonksiyonun �a��r�ld��� yeri etkilemez. E�er parametredeki de�i�ikliklerin fonksiyonun �a��r�ld��� yerde de ge�erli olmas�n� istiyorsak fonksiyona parametrenin adresini g�ndermek gerekir.

�rnek:

void arttir(int*);

main()

{

int i;

i = 5;

printf("�ncesi %d\n", i);

arttir(&i);

printf("sonras� %d\n", i);

getch();

}

void arttir(int *k)

{

(*k)++;

}

�ncesi 5

sonras� 6

�rnek: S�raya dizme. Yer de�i�ikli�i fonksiyonde ve parametrelere referans yolu ile eri�im.

#include <stdio.h>

#include <conio.h>

#define N 20

void degistir (int *, int *);

main()

{

int s[N];

int i, k;

clrscr();

for (i=0; i<N; i++) {

s[i] = rand() % 100;

printf("%4d",s[i]);

}

printf("\n");

k=1;

do

{

k=0;

for (i=0; i<N-1; i++)

if (s[i] > s[i+1]) {

degistir (&s[i], &s[i+1]);

k = 1;

}

}

while (k);

for (i=0; i<N; i++)

printf("%4d",s[i]);

printf("\n");

getch();

}

void degistir (int *a, int *b)

{

int gec;

gec = *a;

*a = *b;

*b = gec;

}

Uyar�: Dizilerde pointer oldu�u i�in a de�i�keni bir dizi (veya pointer ise) a[i] ile *(a+i) ifadeleri ayn� anlam� ta��r.

void malloc(n): En az n byte uzunlu�unda bellekten yer ay�r�r. Fonksiyonun de�eri >0 ise blo�un bellekteki yeri, NULL yer yok demektir.

int *i;

i = (int *) malloc(2000) ; 2000 byte yer ay�r�p blo�un ba�lang�� adresini i 'ye atar

double *x;

x = (double *) malloc(8*2000); 2000 elemanl� double dizi

sizeof(n) : n ifadesinin/tipinin byte olarak uzunlu�unu verir.

i = (int *) malloc(1000*sizeof(int)) ; 1000 tane int de�er i�erecek bellek uzunlu�u

x = (double *) malloc(2000*sizeof(double)) ; 2000 elemanl� double dizi

void free (void *block) : malloc fonksiyonu tersi. Block de�i�kenin tuttu�u yeri bo� belle�e g�nderir

#include <stdio.h>

#include <conio.h>

#define N 8

float ort (int []);

main()

{

int *s;

int i, k;

s = (int *) malloc(2*N);

clrscr();

for (i=0; i<N; i++) {

s[i] = rand() % 10;

printf("%4d",*(s+i));

}

printf("\n");

printf("Ortamala = %.2f\n",ort(s));

getch();}

float ort (int a[])

{

int i;

float t = 0;

for (i=0; i<N; i++)

t = t + a[i];

return t/N;

}

�rnek : Bir pointernin adresini i�eren pointerler.

main()

{

int i;

int *iptr;

int **iptrptr;

i = 5;

iptr = &i;

iptrptr = &iptr;

clrscr(); Ekrana ��kt�:

printf(" i ve &i : %d %p\n", i, &i); i ve &i : 5 8FDD:1000

printf(" *iptr ve iptr : %d %p\n", *iptr, iptr); *iptr ve iptr : 5 8FDD:1000

printf("*iptrptr ve iptrptr : %p %p\n", *iptrptr, iptrptr); *iptrptr ve iptrptr : 8FDD:1000 8FDD:0FFC

getch();

}

5. Pointerler ve Yap�lar

struct ogrenci{

char no[10];

int notu;

};

struct ogrenci *a

Tan�mlamas�nda a de�i�kenini olu�turan alanlara eri�mek i�in, bilinen yol:

*a.notu=56;

strcpy((*a).no, "95001");

Bunun farkl� kullan�m�:

a->notu=56;

strcpy(a->no, "95001");

�rnek: Yap�n�n adresinin fonksiyona g�nderilmesi.

#include <stdio.h>

typedef struct {

char adi[35];

char adres1[40];

char adres2[40];

char tel[15];

float borc;

} kisiler;

void yaz(kisiler *z);

main()

{

kisiler a;

clrscr();

printf("Ad�n� gir : "); gets(a.adi);

printf("Adres-1 : "); gets(a.adres1);

printf("Adres-2 : "); gets(a.adres2);

printf("Telefonu : "); gets(a.tel);

printf("Borcu : "); scanf("%f", &(a.borc));

yaz(&a);

}

void yaz(kisiler *z)

{

clrscr();

printf("Ad� : "); puts(z->adi);

printf("Adresi : "); puts(z->adres1);

printf(" : "); puts(z->adres2);

printf("Telefonu : "); puts(z->tel);

printf("Borcu : "); printf("%.0f\n", z->borc);

}