exploit paylaşım grubumuz: t.me/HTTPwnn

mala anlatır gibi C 9 ("Pointer")("En önemli konudur bunu sakın ama sakın anlamadan herhangi proje yapmayın")

Katılım
16 Haz 2026
Mesaj
111
Reaksiyon
83
xentr_thread_starter
╔════════════════════════════════════════════════════════════════════╗
║ C PROGRAMLAMA DİLİ EĞİTİM SERİSİ #9 ║
║ POINTERLAR (İŞARETÇİLER) ║
║ (Mala Anlatır Gibi) ║
╚════════════════════════════════════════════════════════════════════╝

Bu noktaya kadar geldiysek artık C'nin gerçekten C olmaya başladığı yere geldik.

Birçok kişi:

"Dizileri öğrendim."

"Fonksiyonları öğrendim."

"Stringleri öğrendim."

der.

Sonra Pointer konusuna gelir.

Ve beyninden duman çıkmaya başlar.

Aslında Pointer konusu zor değildir.

Yanlış anlatıldığı için zor görünür.

Bugün Pointer mantığını kafana çivi gibi çakacağız.

════════════════════════════════════════════════════════════════════

▓▓▓ BİLGİSAYARDA HER ŞEYİN ADRESİ VARDIR

Evini düşün.

Bir arkadaşın sana gelmek istiyor.

Sadece:

"Türkiye'deyim"

dersen bulamaz.

Adres gerekir.

Örnek:

Ankara
Çankaya
Sokak
No

Bilgisayar da aynı şekilde çalışır.

Bellekte duran her verinin bir adresi vardır.

Örnek:

int sayi = 10;

Bellekte:

Adres Değer

1000 10

gibi tutulabilir.

Gerçekte adresler farklıdır.

Ama mantık budur.

════════════════════════════════════════════════════════════════════

▓▓▓ POINTER NEDİR?

Pointer:

Bir değişkenin değerini değil

adresini tutan değişkendir.

Tekrar okuyalım.

Normal değişken:

10

saklar.

Pointer:

10'un bulunduğu adresi saklar.

════════════════════════════════════════════════════════════════════

▓▓▓ & OPERATÖRÜ

Bir değişkenin adresini öğrenmek için:

&

kullanılır.

Örnek:

#include <stdio.h>

int main()
{
int sayi = 10;

printf("%p", &sayi);

return 0;

}

ÇIKTI

0x61ff08

Buna benzer bir şey görürsün.

Çünkü adresler sistemden sisteme değişir.

════════════════════════════════════════════════════════════════════

▓▓▓ İLK POINTER

int sayi = 10;

int *ptr;

Buradaki:

ptr

bir pointerdır.

Çünkü başında:

var.

════════════════════════════════════════════════════════════════════

▓▓▓ POINTER'A ADRES ATAMA

int sayi = 10;

int *ptr;

ptr = &sayi;

Artık:

ptr

sayi değişkeninin adresini tutuyor.

Şema:

sayi = 10

Adres = 1000

ptr = 1000

════════════════════════════════════════════════════════════════════

▓▓▓ POINTER'I YAZDIRMA

#include <stdio.h>

int main()
{
int sayi = 10;

int *ptr;

ptr = &sayi;

printf("%p", ptr);

return 0;
}

ÇIKTI

0x61ff08

Adres yazdırılır.

════════════════════════════════════════════════════════════════════

▓▓▓ * OPERATÖRÜNÜN İKİ ANLAMI

Yeni başlayanların en çok karıştırdığı konu.

Birinci anlam:

int *ptr;

Pointer tanımlamak.

İkinci anlam:

*ptr

Adresteki değere ulaşmak.

Aynı sembol.

Farklı görev.

════════════════════════════════════════════════════════════════════

▓▓▓ POINTER İLE DEĞERE ULAŞMA

#include <stdio.h>

int main()
{
int sayi = 10;

int *ptr;

ptr = &sayi;

printf("%d", *ptr);

return 0;
}

ÇIKTI

10

Neden?

Çünkü:

ptr

sayi'nin adresini tutuyor.

*ptr

ise o adresteki değeri getiriyor.

════════════════════════════════════════════════════════════════════

▓▓▓ OLAYI TAM OTURTALIM

int sayi = 50;

int *ptr = &sayi;

Bellek:

Adres Değer

1000 50

ptr içinde:

1000

saklanıyor.

Şimdi:

*ptr

dediğimiz zaman:

"Git 1000 adresine bak"

demiş oluyoruz.

Sonuç:

50

════════════════════════════════════════════════════════════════════

▓▓▓ POINTER İLE DEĞER DEĞİŞTİRME

#include <stdio.h>

int main()
{
int sayi = 10;

int *ptr = &sayi;

*ptr = 99;

printf("%d", sayi);

return 0;
}

ÇIKTI

99

Neden?

Çünkü:

*ptr

doğrudan sayi değişkenini değiştirdi.

════════════════════════════════════════════════════════════════════

▓▓▓ POINTER'IN GÜCÜ

Normalde:

sayi = 50;

değişkenine erişmek gerekir.

Pointer sayesinde:

*ptr = 50;

diyerek de değiştirebiliriz.

Bu özellik:

işletim sistemlerinde

oyun motorlarında

sürücülerde

gömülü sistemlerde

çok kullanılır.

════════════════════════════════════════════════════════════════════

▓▓▓ POINTER VE FONKSİYONLAR

Örnek:

void degistir(int x)
{
x = 100;
}

int main()
{
int sayi = 5;

degistir(sayi);

printf("%d", sayi);
}

ÇIKTI

5

Birçok kişi:

100

bekler.

Ama sonuç:

5

olur.

Çünkü fonksiyon değişkenin kopyasını aldı.

════════════════════════════════════════════════════════════════════

▓▓▓ GERÇEK DEĞERİ DEĞİŞTİRMEK

İşte pointer burada devreye girer.

#include <stdio.h>

void degistir(int *x)
{
*x = 100;
}

int main()
{
int sayi = 5;

degistir(&sayi);

printf("%d", sayi);

return 0;
}

ÇIKTI

100

Artık gerçek değişken değişti.

════════════════════════════════════════════════════════════════════

▓▓▓ ADIM ADIM İNCELEYELİM

degistir(&sayi);

Burada adres gönderiyoruz.

Fonksiyon:

int *x

ile adresi alıyor.

Sonra:

*x = 100;

diyor.

Yani:

"Gönderilen adresteki değeri 100 yap."

Sonuç:

sayi = 100

════════════════════════════════════════════════════════════════════

▓▓▓ POINTER VE DİZİLER

Hatırlayalım:

int sayilar[3] = {10,20,30};

Bellekte yan yana tutulurlar.

Şöyle düşünebiliriz:

Adres Değer

1000 10
1004 20
1008 30

Diziler pointerlarla çok yakın ilişkilidir.

════════════════════════════════════════════════════════════════════

▓▓▓ DİZİ ADI ASLINDA ADRESTİR

Örnek:

int sayilar[3] = {10,20,30};

sayilar

aslında ilk elemanın adresidir.

Yani:

sayilar

ile

&sayilar[0]

aynı şeyi temsil eder.

════════════════════════════════════════════════════════════════════

▓▓▓ POINTER ARİTMETİĞİ

Örnek:

int sayilar[3] = {10,20,30};

int *ptr = sayilar;

printf("%d\n", *ptr);

ÇIKTI

10

Şimdi:

ptr++;

yapalım.

Artık:

ptr

ikinci elemana geçti.

printf("%d\n", *ptr);

ÇIKTI

20

Bir kez daha:

ptr++;

ÇIKTI

30

════════════════════════════════════════════════════════════════════

▓▓▓ NULL POINTER

Bazen pointer henüz bir adres göstermiyordur.

Bu durumda:

int *ptr = NULL;

kullanılır.

NULL:

"Hiçbir yeri göstermiyorum."

anlamına gelir.

════════════════════════════════════════════════════════════════════

▓▓▓ EN TEHLİKELİ HATALARDAN BİRİ

int *ptr;

printf("%d", *ptr);

Çok tehlikelidir.

Çünkü:

ptr

nereye işaret ediyor bilmiyoruz.

Rastgele bir adres olabilir.

Program çökebilir.

════════════════════════════════════════════════════════════════════

▓▓▓ GÜVENLİ KULLANIM

int *ptr = NULL;

if(ptr != NULL)
{
printf("%d", *ptr);
}

Bu daha güvenlidir.

════════════════════════════════════════════════════════════════════

▓▓▓ MİNİ PROJE #1

İKİ SAYIYI POINTER İLE TAKAS ETME

#include <stdio.h>

void takas(int *a, int *b)
{
int gecici;

gecici = *a;
*a = *b;
*b = gecici;
}

int main()
{
int x = 10;
int y = 20;

takas(&x,&y);

printf("%d %d", x, y);

return 0;
}

ÇIKTI

20 10

════════════════════════════════════════════════════════════════════

▓▓▓ MİNİ PROJE #2

POINTER İLE DİZİ TOPLAMI

#include <stdio.h>

int main()
{
int sayilar[5] = {1,2,3,4,5};

int *ptr = sayilar;

int toplam = 0;

for(int i=0; i<5; i++)
{
toplam += *(ptr+i);
}

printf("%d", toplam);

return 0;
}

ÇIKTI

15

════════════════════════════════════════════════════════════════════

▓▓▓ MİNİ PROJE #3

POINTER İLE EN BÜYÜK SAYI

int sayilar[5] = {5,10,80,25,40};

int *ptr = sayilar;

int enBuyuk = *ptr;

for(int i=1; i<5; i++)
{
if(*(ptr+i) > enBuyuk)
{
enBuyuk = *(ptr+i);
}
}

printf("%d", enBuyuk);

ÇIKTI

80

════════════════════════════════════════════════════════════════════

⚠ YENİ BAŞLAYANLARIN HATALARI

HATA #1

int ptr;

Pointer sanmak.

Doğrusu:

int *ptr;

════════════════════════════════════════════════════════════════════

HATA #2

ptr = sayi;

Adres yerine değer atamak.

Doğrusu:

ptr = &sayi;

════════════════════════════════════════════════════════════════════

HATA #3

printf("%d", ptr);

Değeri beklemek.

Bu adres yazdırır.

Değer için:

printf("%d", *ptr);

kullanılır.

════════════════════════════════════════════════════════════════════

HATA #4

NULL olmayan pointer kontrolü yapmadan kullanmak.

Bu program çökmesine neden olabilir.

════════════════════════════════════════════════════════════════════

✓ BÖLÜM ÖZETİ

Bu bölümde:

✓ Bellek adresleri

✓ Pointer nedir

✓ & operatörü

✓ * operatörü

✓ Pointer tanımlama

✓ Pointer ile değer okuma

✓ Pointer ile değer değiştirme

✓ Fonksiyonlara adres gönderme

✓ Pointer ve diziler

✓ Pointer aritmetiği

✓ NULL pointer

✓ Gerçek hayat kullanım alanları

konularını öğrendik.

Bir sonraki bölümde DİNAMİK BELLEK YÖNETİMİ (malloc, calloc, realloc, free) konusuna geçeceğiz. Bu konu pointer bilgisini gerçek güce dönüştüren aşamadır.
 
╔════════════════════════════════════════════════════════════════════╗
║ C PROGRAMLAMA DİLİ EĞİTİM SERİSİ #9 ║
║ POINTERLAR (İŞARETÇİLER) ║
║ (Mala Anlatır Gibi) ║
╚════════════════════════════════════════════════════════════════════╝

Bu noktaya kadar geldiysek artık C'nin gerçekten C olmaya başladığı yere geldik.

Birçok kişi:

"Dizileri öğrendim."

"Fonksiyonları öğrendim."

"Stringleri öğrendim."

der.

Sonra Pointer konusuna gelir.

Ve beyninden duman çıkmaya başlar.

Aslında Pointer konusu zor değildir.

Yanlış anlatıldığı için zor görünür.

Bugün Pointer mantığını kafana çivi gibi çakacağız.

════════════════════════════════════════════════════════════════════

▓▓▓ BİLGİSAYARDA HER ŞEYİN ADRESİ VARDIR

Evini düşün.

Bir arkadaşın sana gelmek istiyor.

Sadece:

"Türkiye'deyim"

dersen bulamaz.

Adres gerekir.

Örnek:

Ankara
Çankaya
Sokak
No

Bilgisayar da aynı şekilde çalışır.

Bellekte duran her verinin bir adresi vardır.

Örnek:

int sayi = 10;

Bellekte:

Adres Değer

1000 10

gibi tutulabilir.

Gerçekte adresler farklıdır.

Ama mantık budur.

════════════════════════════════════════════════════════════════════

▓▓▓ POINTER NEDİR?

Pointer:

Bir değişkenin değerini değil

adresini tutan değişkendir.

Tekrar okuyalım.

Normal değişken:

10

saklar.

Pointer:

10'un bulunduğu adresi saklar.

════════════════════════════════════════════════════════════════════

▓▓▓ & OPERATÖRÜ

Bir değişkenin adresini öğrenmek için:

&

kullanılır.

Örnek:

#include <stdio.h>

int main()
{
int sayi = 10;

printf("%p", &sayi);

return 0;

}

ÇIKTI

0x61ff08

Buna benzer bir şey görürsün.

Çünkü adresler sistemden sisteme değişir.

════════════════════════════════════════════════════════════════════

▓▓▓ İLK POINTER

int sayi = 10;

int *ptr;

Buradaki:

ptr

bir pointerdır.

Çünkü başında:

var.

════════════════════════════════════════════════════════════════════

▓▓▓ POINTER'A ADRES ATAMA

int sayi = 10;

int *ptr;

ptr = &sayi;

Artık:

ptr

sayi değişkeninin adresini tutuyor.

Şema:

sayi = 10

Adres = 1000

ptr = 1000

════════════════════════════════════════════════════════════════════

▓▓▓ POINTER'I YAZDIRMA

#include <stdio.h>

int main()
{
int sayi = 10;

int *ptr;

ptr = &sayi;

printf("%p", ptr);

return 0;
}

ÇIKTI

0x61ff08

Adres yazdırılır.

════════════════════════════════════════════════════════════════════

▓▓▓ * OPERATÖRÜNÜN İKİ ANLAMI

Yeni başlayanların en çok karıştırdığı konu.

Birinci anlam:

int *ptr;

Pointer tanımlamak.

İkinci anlam:

*ptr

Adresteki değere ulaşmak.

Aynı sembol.

Farklı görev.

════════════════════════════════════════════════════════════════════

▓▓▓ POINTER İLE DEĞERE ULAŞMA

#include <stdio.h>

int main()
{
int sayi = 10;

int *ptr;

ptr = &sayi;

printf("%d", *ptr);

return 0;
}

ÇIKTI

10

Neden?

Çünkü:

ptr

sayi'nin adresini tutuyor.

*ptr

ise o adresteki değeri getiriyor.

════════════════════════════════════════════════════════════════════

▓▓▓ OLAYI TAM OTURTALIM

int sayi = 50;

int *ptr = &sayi;

Bellek:

Adres Değer

1000 50

ptr içinde:

1000

saklanıyor.

Şimdi:

*ptr

dediğimiz zaman:

"Git 1000 adresine bak"

demiş oluyoruz.

Sonuç:

50

════════════════════════════════════════════════════════════════════

▓▓▓ POINTER İLE DEĞER DEĞİŞTİRME

#include <stdio.h>

int main()
{
int sayi = 10;

int *ptr = &sayi;

*ptr = 99;

printf("%d", sayi);

return 0;
}

ÇIKTI

99

Neden?

Çünkü:

*ptr

doğrudan sayi değişkenini değiştirdi.

════════════════════════════════════════════════════════════════════

▓▓▓ POINTER'IN GÜCÜ

Normalde:

sayi = 50;

değişkenine erişmek gerekir.

Pointer sayesinde:

*ptr = 50;

diyerek de değiştirebiliriz.

Bu özellik:

işletim sistemlerinde

oyun motorlarında

sürücülerde

gömülü sistemlerde

çok kullanılır.

════════════════════════════════════════════════════════════════════

▓▓▓ POINTER VE FONKSİYONLAR

Örnek:

void degistir(int x)
{
x = 100;
}

int main()
{
int sayi = 5;

degistir(sayi);

printf("%d", sayi);
}

ÇIKTI

5

Birçok kişi:

100

bekler.

Ama sonuç:

5

olur.

Çünkü fonksiyon değişkenin kopyasını aldı.

════════════════════════════════════════════════════════════════════

▓▓▓ GERÇEK DEĞERİ DEĞİŞTİRMEK

İşte pointer burada devreye girer.

#include <stdio.h>

void degistir(int *x)
{
*x = 100;
}

int main()
{
int sayi = 5;

degistir(&sayi);

printf("%d", sayi);

return 0;
}

ÇIKTI

100

Artık gerçek değişken değişti.

════════════════════════════════════════════════════════════════════

▓▓▓ ADIM ADIM İNCELEYELİM

degistir(&sayi);

Burada adres gönderiyoruz.

Fonksiyon:

int *x

ile adresi alıyor.

Sonra:

*x = 100;

diyor.

Yani:

"Gönderilen adresteki değeri 100 yap."

Sonuç:

sayi = 100

════════════════════════════════════════════════════════════════════

▓▓▓ POINTER VE DİZİLER

Hatırlayalım:

int sayilar[3] = {10,20,30};

Bellekte yan yana tutulurlar.

Şöyle düşünebiliriz:

Adres Değer

1000 10
1004 20
1008 30

Diziler pointerlarla çok yakın ilişkilidir.

════════════════════════════════════════════════════════════════════

▓▓▓ DİZİ ADI ASLINDA ADRESTİR

Örnek:

int sayilar[3] = {10,20,30};

sayilar

aslında ilk elemanın adresidir.

Yani:

sayilar

ile

&sayilar[0]

aynı şeyi temsil eder.

════════════════════════════════════════════════════════════════════

▓▓▓ POINTER ARİTMETİĞİ

Örnek:

int sayilar[3] = {10,20,30};

int *ptr = sayilar;

printf("%d\n", *ptr);

ÇIKTI

10

Şimdi:

ptr++;

yapalım.

Artık:

ptr

ikinci elemana geçti.

printf("%d\n", *ptr);

ÇIKTI

20

Bir kez daha:

ptr++;

ÇIKTI

30

════════════════════════════════════════════════════════════════════

▓▓▓ NULL POINTER

Bazen pointer henüz bir adres göstermiyordur.

Bu durumda:

int *ptr = NULL;

kullanılır.

NULL:

"Hiçbir yeri göstermiyorum."

anlamına gelir.

════════════════════════════════════════════════════════════════════

▓▓▓ EN TEHLİKELİ HATALARDAN BİRİ

int *ptr;

printf("%d", *ptr);

Çok tehlikelidir.

Çünkü:

ptr

nereye işaret ediyor bilmiyoruz.

Rastgele bir adres olabilir.

Program çökebilir.

════════════════════════════════════════════════════════════════════

▓▓▓ GÜVENLİ KULLANIM

int *ptr = NULL;

if(ptr != NULL)
{
printf("%d", *ptr);
}

Bu daha güvenlidir.

════════════════════════════════════════════════════════════════════

▓▓▓ MİNİ PROJE #1

İKİ SAYIYI POINTER İLE TAKAS ETME

#include <stdio.h>

void takas(int *a, int *b)
{
int gecici;

gecici = *a;
*a = *b;
*b = gecici;
}

int main()
{
int x = 10;
int y = 20;

takas(&x,&y);

printf("%d %d", x, y);

return 0;
}

ÇIKTI

20 10

════════════════════════════════════════════════════════════════════

▓▓▓ MİNİ PROJE #2

POINTER İLE DİZİ TOPLAMI

#include <stdio.h>

int main()
{
int sayilar[5] = {1,2,3,4,5};

int *ptr = sayilar;

int toplam = 0;

for(int i=0; i<5; i++)
{
toplam += *(ptr+i);
}

printf("%d", toplam);

return 0;
}

ÇIKTI

15

════════════════════════════════════════════════════════════════════

▓▓▓ MİNİ PROJE #3

POINTER İLE EN BÜYÜK SAYI

int sayilar[5] = {5,10,80,25,40};

int *ptr = sayilar;

int enBuyuk = *ptr;

for(int i=1; i<5; i++)
{
if(*(ptr+i) > enBuyuk)
{
enBuyuk = *(ptr+i);
}
}

printf("%d", enBuyuk);

ÇIKTI

80

════════════════════════════════════════════════════════════════════

⚠ YENİ BAŞLAYANLARIN HATALARI

HATA #1

int ptr;

Pointer sanmak.

Doğrusu:

int *ptr;

════════════════════════════════════════════════════════════════════

HATA #2

ptr = sayi;

Adres yerine değer atamak.

Doğrusu:

ptr = &sayi;

════════════════════════════════════════════════════════════════════

HATA #3

printf("%d", ptr);

Değeri beklemek.

Bu adres yazdırır.

Değer için:

printf("%d", *ptr);

kullanılır.

════════════════════════════════════════════════════════════════════

HATA #4

NULL olmayan pointer kontrolü yapmadan kullanmak.

Bu program çökmesine neden olabilir.

════════════════════════════════════════════════════════════════════

✓ BÖLÜM ÖZETİ

Bu bölümde:

✓ Bellek adresleri

✓ Pointer nedir

✓ & operatörü

✓ * operatörü

✓ Pointer tanımlama

✓ Pointer ile değer okuma

✓ Pointer ile değer değiştirme

✓ Fonksiyonlara adres gönderme

✓ Pointer ve diziler

✓ Pointer aritmetiği

✓ NULL pointer

✓ Gerçek hayat kullanım alanları

konularını öğrendik.

Bir sonraki bölümde DİNAMİK BELLEK YÖNETİMİ (malloc, calloc, realloc, free) konusuna geçeceğiz. Bu konu pointer bilgisini gerçek güce dönüştüren aşamadır.
+ e.s
 
Geri
En Üst