sendetiklat Sahip | Gönderilme Tarihi: 23 Kasım 2009 18:20:15
POINTERLAR
Pointer(Gösterici) nedir?-1
Gösterici, bellek alanındaki bir gözün adresinin saklandığı değişkendir. Göstericilere veriler (yani değişkenlerin içeriği) değil de, o verilerin bellekte saklı olduğu hücrenin başlangıç adresleri atanır. Kısaca gösterici adres tutan bir değişkendir.
Bu tanımlamada geçen bellek adresinin ne olduğunu detaylıca tanımlamak gerekir.
Değişken ve Bellek Adresi
Bilgisayarın ana belleği (RAM) sıralı kaydetme gözlerinden oluşmuştur. Her göze bir adres atanmıştır. Bu adreslerin değerleri 0 ile belleğin sahip olduğu üst değere bağlı olarak değişebilir. Örneğin 64 MB bir bellek, 64*1024*1024 = 67108864 adet gözden oluşur. Değişken tiplerinin bellekte işgal ettiği alanın bayt cinsinden uzunluğu sizeof() operatörüyle öğrenilir.
/* sizeof operatörünün kullanımı */
#include <stdio.h>
main()
{
printf( "char : %d bayt\n", sizeof(char));
printf( "short : %d bayt\n", sizeof(short));
printf( "int : %d bayt\n", sizeof(int));
printf( "long : %d bayt\n", sizeof(long));
printf( "unsigned char : %d bayt\n", sizeof(unsigned char));
printf( "unsigned short : %d bayt\n", sizeof(unsigned short));
printf( "unsigned int : %d bayt\n", sizeof(unsigned int));
printf( "unsigned long : %d bayt\n", sizeof(unsigned long));
printf( "float : %d bayt\n", sizeof(float));
printf( "double : %d bayt\n", sizeof(double));
printf( "long double : %d bayt\n", sizeof(long double));
getchar();
}
_
Değişken ve Bellek Adresi-2
Bir programlama dillinde, belli bir tipte değişken tanımlanıp ve bir değer atandığında, o değişkene dört temel özellik eşlik eder:
değişkenin adı
değişkenin tipi
değişkenin sahip olduğu değer (içerik)
değişkenin bellekteki adresi
Örneğin tam adlı bir tamsayı değişkenini aşağıdaki gibi tanımladığımızı varsayalım:
int tam = 33;
Bu değişken için, int tipinde bellekte (genellikle herbiri 1 bayt olan 4 bayt büyüklüğünde) bir hücre ayrılır ve o hücreye 33 sayısı ikilik (binary) sayı sitemindeki karşılığı olan 4 baytlık (32 bitlik):
00000000 00000000 00000000 00100001
sayısı elektronik olarak yazılır.
Değişken ve Bellek Adresi-3
tam değişkenine ait dört temel özellik şekilsel olarak şöyle gösterilebilir.
Değişken ve Bellek Adresi-4
Değişkenin saklı olduğu adres, & karakteri ile tanımlı adres operatörü ile öğrenilebilir. Bu operatör bir değişkenin önüne konursa, o değişkenin içeriği ile değil adresi ile ilgileniliyor anlamına gelir.
Aşağıdaki program parçasının:
int tam = 33;
printf("icerik: %d\n",tam);
printf("adres : %p\n",&tam);
çıktısı:
icerik: 33
adres : 00ff2274
şeklindedir.
Burada birinci satır tam değişkeninin içeriği, ikinci ise adresidir. Adres yazdırılırken %p tip belirleyicisi kullanılır.
Pointer(Gösterici) nedir?-2
İlk slaytta tanımlandığı üzere:
Gösterici, bellek alanındaki bir gözün adresinin saklandığı değişkendir. Göstericilere veriler (yani değişkenlerin içeriği) değil de, o verilerin bellekte saklı olduğu hücrenin başlangıç adresleri atanır. Kısaca gösterici adres tutan bir değişkendir.
Bir gösterici, diğer değişkenler gibi, sayısal bir değişkendir. Bu sebeple kullanılmadan önce program içinde bildirilmelidir. Gösterici tipindeki değişkenler şöyle tanımlanır:
tip_adı *gösterici_adı;
Burada tip_adı herhangi bir C tip adı olabilir. Değişkenin önündeki * karakteri yönlendirme (indirection) operatörü olarak adlandırılır ve bu değişkenin veri değil bir adres bilgisi tutacağını işaret eder. Örneğin:
char *kr; /* tek bir karakter için */
int *x; /* bir tamsayı için */
float *deger, sonuc; /* deger gösterici tipinde, sonuc sıradan bir gerçel değişkenler */
Yukarıda bildirilen göstericilerden; kr bir karakterin, x bir tamsayının ve deger bir gerçel sayının bellekte saklı olduğu yerlerin adreslerini tutar.
Pointer Atama
Bir göstericiye, bir değişkenin adresini atamak için adres operatörü kullanılabilir. Örneğin tamsayı tipindeki tam adlı bir değişken ve ptam bir gösterici olsun. Derleyicide, aşağıdaki gibi bir atama yapıldığında:
int *ptam, tam = 33; . . .
ptam = &tam;
ptam göstericisinin tam değişkeninin saklandığı adresi tutacaktır. Bu durum Şekilsel olarak yandaki gibi olur.
Örnek:Adres ve değer gösterme.
// Bir değişkenin adres ve değerini gösterme örneği
#include <stdio.h>
main()
{
int *ptam, tam = 33;
ptam = &tam;
printf("tam: icerik = %d\n", tam);
printf("tam: adres = %p\n",&tam);
printf("ptam: adres = %p\n",ptam);
getchar();
}_
Örnek:Adres ve değer gösterme-2
#include <stdio.h>
main()
{
int *ptam, tam = 33;
ptam = &tam; /* ptam -> tam */
printf("&tam = %p\n",&tam);
printf("ptam = %p\n",ptam);
printf("\n");
printf("tam = %d\n",tam);
printf("*ptam = %d\n",*ptam);
printf("\n");
*ptam = 44; /* tam = 44 anlamında */
printf("tam = %d\n",tam);
printf("*ptam = %d\n",*ptam);
getchar();
}
_
Pointer ve Diziler
C dilinde bir dizinin adı, dizinin ilk elemanının adresini saklayan bir göstericidir. Bu yüzden, bir dizinin herhangi bir elemanına gösterici ile de erişilebilir. Örneğin:
int kutle[5], *p, *q;
şeklinde bir bildirim yapılsın. Buna göre aşağıda yapılan atamalar geçerlidir:
p = &kutle[0]; /* birinci elemanın adresi p göstericisine atandı */
p = kutle; /* birinci elemanın adresi p göstericisine atandı */
q = &kutle[4]; /* son elemanın adresi q göstericisine atandı */
İlk iki satırdaki atamalar aynı anlamdadır. Dizi adı bir gösterici olduğu için, doğrudan aynı tipteki bir göstericiye atanabilir. Ayrıca, i bir tamsayı olmak üzere,
kutle;
ile
*(p+i);
aynı anlamdadır.
Bunun sebebi, p göstericisi kutle dizisinin başlangıç adresini tutmuş olmasıdır. p+i işlemi ile i+1. elemanın adresi, ve *(p+i) ile de bu adresteki değer hesaplanır.
Örnek: Dizi elemanlarının fonksiyondaki pointer yardımıyla ortalamasının alınması
#include <stdio.h>
double ortalama(double dizi[], int n);
main()
{
double a[5] = {1.1, 2.2, 3.3, 4.4, 5.5};
double o;
o = ortalama(a,5);
printf("Dizinin ortalaması = %lf\n",o);
getchar();
}
double ortalama(double dizi[], int n)
{
double *p, t=0.0;
int i;
p = dizi; /* veya p = &dizi[0] */
for(i=0; i<n; i++)
t += *(p+i);
return (t/n);
}_
Dinamik Dizi Tanımlama
Bir dizi, programın başında kaç elemanlı olduğu belirtilerek bildirilirse, derleyici o dizi için gerekli bellek alanını program sonlandırılıncaya kadar saklı tutar ve o alan başka amaçlar için kullanılmaz. Dizilerde dinamik çalışma, programın çalıştırılması sırasında gerekli bellek alanının işletim sisteminden istenmesi ve işi bittiğinde bu alanın geri verilmesidir. Bu amaçla standart kütüphanede malloc(), calloc(), realloc() ve free() fonksiyonları vardır. Bu şekilde dizileri kullanmak için:
...
tip *ptr;
...
ptr = malloc(50); /* herbiri 8 bit olan 50 elemanlık yer isteniyor */ . . /* kullanılıyor */ . free(ptr); /* geri veriliyor */
Eleman sayısı dinamik olarak tanımlanan bir dizi elamanlarının aritmetik ortalamasını bulan program.
#include <stdio.h>
#include <stdlib.h>
main(){
int *x,i,N,toplam=0;
float ortalama;
printf("Eleman sayısı ");
scanf("%d",&N);
x = (int *) malloc(N*sizeof(int)); /* N tane int gözü isteniyor (Nx2 byte) */
puts("Elemanları girin:");
for(i=0;i<N;i++){
printf("%d.eleman = ",i+1);
scanf("%d",&x); /* x ile *(x+i) aynı anlamda !... */
toplam += x;
}
free(x); /* ayrılan yer boşaltılıyor... */
ortalama = (float) toplam/N;
printf("Bu %d sayının ortalaması %f dir\n",N,ortalama);
getchar();
getchar();
}_
|