-
Sadrazamv4
ig:sadrazam_v4 tg: Sadrazam.spy
🚀 BAŞTAN SONA C DİLİ BÖLÜM-6: Pointers (İşaretçiler) ve Bellek Adresleme 📍
Selamlar! Serimizin 6. bölümüne hoş geldiniz.
Önceki bölümde fonksiyonları, prototipleri ve `Call by Reference` yapısıyla işaretçilere ilk adımı atmıştık. Bu bölümde ise C dilini diğer dillerden ayıran, donanıma hükmetmesini sağlayan ve geliştiricilerin en çok çekindiği ama kavrandığında mucizeler yaratan konusuna giriyoruz: **Pointers (İşaretçiler)**.
---
📌 1. Pointer (İşaretçi) Nedir? 🧠
Pointer; bir verinin değerini değil, o verinin bellekte saklandığı **RAM adresini (Memory Address)** tutan özel bir değişkendir.
### Neden Pointer Kullanırız?
⚡ **Doğrudan Bellek Erişimi:** İşletim sisteminin izin verdiği ölçüde bellek hücrelerine erişim sağlar.
🚀 **Yüksek Performans:** Büyük veri bloklarını (diziler, struct'lar) fonksiyonlara kopyalamak yerine adresini göndererek muazzam bir hız ve bellek tasarrufu sağlar.
🏗️ **Dinamik Bellek Yönetimi:** Çalışma zamanında (runtime) bellekten yer ayırmayı (`malloc`, `calloc`) mümkün kılar.
---
🗝️ 2. İki Temel Operatör: Adres (`&`) ve Dereference (`*`) 🔑
Pointer yapısını anlamak için şu iki operatörün görevini tam kavratmalıyız:
1. **Adres Operatörü (`&`):** Bir değişkenin önü alındığında, o değişkenin bellekteki **0x... formatındaki altıgen (hexadecimal) adresini** döner.
2. **Dereference / Indirection Operatörü (`*`):** Bir pointer değişkeninin önüne konulduğunda, o pointer'ın **işaret ettiği adresteki GERÇEK DEĞERE** ulaşılmasını sağlar.
### Pointer Tanımlama Syntax'ı:
`VeriTipi *pointerAdi;`
#include <stdio.h>
int main() {
int sayi = 42;
int *ptr; // int türünde veri adreslerini tutacak bir pointer tanımlıyoruz
ptr = &sayi; // 'sayi' değişkeninin bellek adresini ptr değişkenine atıyoruz
printf("sayi'nin Degeri : %d\n", sayi);
printf("sayi'nin Bellek Adresi (&): %p\n", (void*)&sayi);
printf("ptr'nin Tuttugu Adres : %p\n", (void*)ptr);
printf("ptr'nin Isaret Ettigi Deger (*ptr): %d\n", *ptr);
// Pointer üzerinden adresteki değeri değiştirme!
*ptr = 99;
printf("\n*ptr = 99 komutundan sonra sayi'nin yeni degeri: %d\n", sayi);
return 0;
}
---
🚫 3. NULL Pointer ve Wild Pointer Tehlikesi ⚠️
### Wild Pointer (Vahşi İşaretçi):
Tanımlanan ama henüz bir bellek adresi atanmamış pointer'dır. Rastgele bir bellek adresini gösterir. Bu adrese `*ptr` ile veri yazmaya çalışmak uygulamanın çökmesine (`Segmentation Fault`) yol açar!
int *ptr; // Wild Pointer!
// *ptr = 10; // TEHLİKELİ! Çökme garantisi!
### NULL Pointer:
Geçerli bir adresi göstermeyen, güvenli şekilde sıfırlanmış pointer'dır. Bir pointer tanımlandığında hemen bir adres atanmayacaksa mutlaka `NULL` değerine eşitlenmelidir.
#include <stdio.h>
int main() {
int *ptr = NULL; // Güvenli başlangıç
if (ptr != NULL) {
printf("Adresteki deger: %d\n", *ptr);
} else {
printf("Pointer henuz bir adresi isaret etmiyor! (NULL)\n");
}
return 0;
}
---
➕ 4. Pointer Aritmetiği (Pointer Arithmetic) 🧮
Pointer değişkenleri üzerinde toplama (`+`), çıkarma (`-`), artırma (`++`) veya eksiltme (`--`) işlemleri yapılabilir.
Ancak buradaki artış miktar sayısal 1 artış değil; pointer'ın türünün **`sizeof` boyutu kadar** adres kaydırılmasıdır!
• `int` pointer'ı (`4 byte`) 1 artırılırsa (`ptr++`), adres değeri **4 byte ileri** kayar.
• `char` pointer'ı (`1 byte`) 1 artırılırsa (`ptr++`), adres değeri **1 byte ileri** kayar.
#include <stdio.h>
int main() {
int sayilar[] = {10, 20, 30};
int *ptr = sayilar; // Dizi adı doğrudan ilk elemanın adresini temsil eder!
printf("1. Eleman Adresi: %p | Deger: %d\n", (void*)ptr, *ptr);
ptr++; // Adres int boyutu kadar (4 byte) ileri kaydı
printf("2. Eleman Adresi: %p | Deger: %d\n", (void*)ptr, *ptr);
ptr++; // Bir 4 byte daha ileri kaydı
printf("3. Eleman Adresi: %p | Deger: %d\n", (void*)ptr, *ptr);
return 0;
}
---
🔗 5. Pointer ve Dizi (Array) Özdeşliği 🤝
C dilinde bir dizinin adı, aslında o dizinin **ilk elemanının bellek adresini** tutan sabit bir pointer'dır!
`dizi` erişimi ile `*(dizi + i)` erişimi bellek seviyesinde **BIREBIR AYNI** şeydir.
#include <stdio.h>
int main() {
int arr[3] = {100, 200, 300};
for (int i = 0; i < 3; i++) {
// İndeks yöntemi vs Pointer aritmetiği yöntemi
printf("arr[%d] = %d <---> *(arr + %d) = %d\n", i, arr, i, *(arr + i));
}
return 0;
}
---
📝 Bölüm Özeti ve Gelecek Bölüm 🔮
Bu bölümde Pointer kavramını, `&` ve `*` operatörlerinin kullanımını, NULL pointer güvenliğini, Pointer Aritmetiğini ve Dizi-Pointer ilişkisini öğrendik.
👉 **Bölüm 7'de Bizi Ne Bekliyor?**
• Tek Boyutlu ve Çok Boyutlu Diziler (Arrays & Matrices)
• C Dilinde Metinler: **Karakter Dizileri (Strings)**
• `<string.h>` Kütüphanesi ve Fonksiyonları (`strlen`, `strcpy`, `strcmp`, `strcat`)
• `gets()`
Tehlikesi ve `fgets()` Kullanımı
Sorularınızı konu altından iletebilirsiniz. Bir sonraki bölümde görüşmek üzere! 💻✨
Selamlar! Serimizin 6. bölümüne hoş geldiniz.
Önceki bölümde fonksiyonları, prototipleri ve `Call by Reference` yapısıyla işaretçilere ilk adımı atmıştık. Bu bölümde ise C dilini diğer dillerden ayıran, donanıma hükmetmesini sağlayan ve geliştiricilerin en çok çekindiği ama kavrandığında mucizeler yaratan konusuna giriyoruz: **Pointers (İşaretçiler)**.
---
📌 1. Pointer (İşaretçi) Nedir? 🧠
Pointer; bir verinin değerini değil, o verinin bellekte saklandığı **RAM adresini (Memory Address)** tutan özel bir değişkendir.
### Neden Pointer Kullanırız?
⚡ **Doğrudan Bellek Erişimi:** İşletim sisteminin izin verdiği ölçüde bellek hücrelerine erişim sağlar.
🚀 **Yüksek Performans:** Büyük veri bloklarını (diziler, struct'lar) fonksiyonlara kopyalamak yerine adresini göndererek muazzam bir hız ve bellek tasarrufu sağlar.
🏗️ **Dinamik Bellek Yönetimi:** Çalışma zamanında (runtime) bellekten yer ayırmayı (`malloc`, `calloc`) mümkün kılar.
---
🗝️ 2. İki Temel Operatör: Adres (`&`) ve Dereference (`*`) 🔑
Pointer yapısını anlamak için şu iki operatörün görevini tam kavratmalıyız:
1. **Adres Operatörü (`&`):** Bir değişkenin önü alındığında, o değişkenin bellekteki **0x... formatındaki altıgen (hexadecimal) adresini** döner.
2. **Dereference / Indirection Operatörü (`*`):** Bir pointer değişkeninin önüne konulduğunda, o pointer'ın **işaret ettiği adresteki GERÇEK DEĞERE** ulaşılmasını sağlar.
### Pointer Tanımlama Syntax'ı:
`VeriTipi *pointerAdi;`
#include <stdio.h>
int main() {
int sayi = 42;
int *ptr; // int türünde veri adreslerini tutacak bir pointer tanımlıyoruz
ptr = &sayi; // 'sayi' değişkeninin bellek adresini ptr değişkenine atıyoruz
printf("sayi'nin Degeri : %d\n", sayi);
printf("sayi'nin Bellek Adresi (&): %p\n", (void*)&sayi);
printf("ptr'nin Tuttugu Adres : %p\n", (void*)ptr);
printf("ptr'nin Isaret Ettigi Deger (*ptr): %d\n", *ptr);
// Pointer üzerinden adresteki değeri değiştirme!
*ptr = 99;
printf("\n*ptr = 99 komutundan sonra sayi'nin yeni degeri: %d\n", sayi);
return 0;
}
---
🚫 3. NULL Pointer ve Wild Pointer Tehlikesi ⚠️
### Wild Pointer (Vahşi İşaretçi):
Tanımlanan ama henüz bir bellek adresi atanmamış pointer'dır. Rastgele bir bellek adresini gösterir. Bu adrese `*ptr` ile veri yazmaya çalışmak uygulamanın çökmesine (`Segmentation Fault`) yol açar!
int *ptr; // Wild Pointer!
// *ptr = 10; // TEHLİKELİ! Çökme garantisi!
### NULL Pointer:
Geçerli bir adresi göstermeyen, güvenli şekilde sıfırlanmış pointer'dır. Bir pointer tanımlandığında hemen bir adres atanmayacaksa mutlaka `NULL` değerine eşitlenmelidir.
#include <stdio.h>
int main() {
int *ptr = NULL; // Güvenli başlangıç
if (ptr != NULL) {
printf("Adresteki deger: %d\n", *ptr);
} else {
printf("Pointer henuz bir adresi isaret etmiyor! (NULL)\n");
}
return 0;
}
---
➕ 4. Pointer Aritmetiği (Pointer Arithmetic) 🧮
Pointer değişkenleri üzerinde toplama (`+`), çıkarma (`-`), artırma (`++`) veya eksiltme (`--`) işlemleri yapılabilir.
Ancak buradaki artış miktar sayısal 1 artış değil; pointer'ın türünün **`sizeof` boyutu kadar** adres kaydırılmasıdır!
• `int` pointer'ı (`4 byte`) 1 artırılırsa (`ptr++`), adres değeri **4 byte ileri** kayar.
• `char` pointer'ı (`1 byte`) 1 artırılırsa (`ptr++`), adres değeri **1 byte ileri** kayar.
#include <stdio.h>
int main() {
int sayilar[] = {10, 20, 30};
int *ptr = sayilar; // Dizi adı doğrudan ilk elemanın adresini temsil eder!
printf("1. Eleman Adresi: %p | Deger: %d\n", (void*)ptr, *ptr);
ptr++; // Adres int boyutu kadar (4 byte) ileri kaydı
printf("2. Eleman Adresi: %p | Deger: %d\n", (void*)ptr, *ptr);
ptr++; // Bir 4 byte daha ileri kaydı
printf("3. Eleman Adresi: %p | Deger: %d\n", (void*)ptr, *ptr);
return 0;
}
---
🔗 5. Pointer ve Dizi (Array) Özdeşliği 🤝
C dilinde bir dizinin adı, aslında o dizinin **ilk elemanının bellek adresini** tutan sabit bir pointer'dır!
`dizi` erişimi ile `*(dizi + i)` erişimi bellek seviyesinde **BIREBIR AYNI** şeydir.
#include <stdio.h>
int main() {
int arr[3] = {100, 200, 300};
for (int i = 0; i < 3; i++) {
// İndeks yöntemi vs Pointer aritmetiği yöntemi
printf("arr[%d] = %d <---> *(arr + %d) = %d\n", i, arr, i, *(arr + i));
}
return 0;
}
---
📝 Bölüm Özeti ve Gelecek Bölüm 🔮
Bu bölümde Pointer kavramını, `&` ve `*` operatörlerinin kullanımını, NULL pointer güvenliğini, Pointer Aritmetiğini ve Dizi-Pointer ilişkisini öğrendik.
👉 **Bölüm 7'de Bizi Ne Bekliyor?**
• Tek Boyutlu ve Çok Boyutlu Diziler (Arrays & Matrices)
• C Dilinde Metinler: **Karakter Dizileri (Strings)**
• `<string.h>` Kütüphanesi ve Fonksiyonları (`strlen`, `strcpy`, `strcmp`, `strcat`)
• `gets()`
Tehlikesi ve `fgets()` Kullanımı
Sorularınızı konu altından iletebilirsiniz. Bir sonraki bölümde görüşmek üzere! 💻✨
🔒 Bu içeriği görmek için giriş yapın