'Self' İşaretçisi
Coddy'nin C Journey'sinin Object Oriented Programming bölümünün bir parçası — ders 7 / 61.
Python veya Java gibi nesne yönelimli dillerde, object.method() çağırdığınızda, dil nesnenin kendisini metoda otomatik olarak aktarır. C'de, bunu ilk argüman olarak struct'a bir işaretçi (pointer) geçirerek manuel olarak yapmalıyız.
Bu işaretçi geleneksel olarak self (Python'dan ödünç alınmıştır) veya this (C++'dan) olarak adlandırılır. Fonksiyona, struct'ın verilerine erişim sağlar, böylece onları okuyabilir veya değiştirebilir:
typedef struct {
int health;
} Player;
void player_take_damage(Player *self, int amount) {
self->health -= amount;
}
self işaretçisi, fonksiyonun bir metot gibi davranmasını sağlayan şeydir; hangi oyuncunun değiştirileceğini bilir. O olmadan, fonksiyonun belirli bir struct örneğine erişmesinin hiçbir yolu olmazdı. Bu fonksiyonu çağırırken, struct'ınızın adresini geçersiniz:
Player hero = {100};
player_take_damage(&hero, 25);
// hero.health şu an 75
Değişiklik yapmak için (struct'ı doğrudan geçirmek yerine) bir pointer kullanmak esastır. Eğer struct'ı değer ile (by value) geçirseydiniz, fonksiyon bir kopya alırdı ve fonksiyon döndüğünde yapılan tüm değişiklikler kaybolurdu. Pointer, değişikliklerin orijinal struct üzerinde kalıcı olmasını sağlar.
Görev
KolayGeçen saniyeleri takip eden bir Timer modülü oluşturalım. Metot gibi davranan fonksiyonlar aracılığıyla bir struct'ın dahili durumunu değiştirmek için "self" pointer desenini kullanma pratiği yapacaksınız.
Üç dosya oluşturacaksınız:
timer.h: Tek birint secondsüyesine sahip birTimerstruct'ı bildirin. Ayrıca iki fonksiyon bildirin:timer_tick(bir Timer pointer'ı alır ve belirtilen sayıda saniye ekler) vetimer_reset(bir Timer pointer'ı alır ve saniyeleri tekrar sıfıra ayarlar).TIMER_Hsembolü ile include guard kullanın.timer.c: Her iki fonksiyonu da uygulayın.timer_tickfonksiyonu birTimer *selfve birint amountkabul etmeli, ardından miktarı zamanlayıcının saniyelerine eklemelidir.timer_resetfonksiyonu birTimer *selfkabul etmeli ve saniyelerini sıfıra ayarlamalıdır.main.c: Bir Timer oluşturun, üzerinde işlemler yapın ve sonuçları görüntüleyin.
İki tam sayı girdisi alacaksınız: zamanlayıcınız için initial seconds (başlangıç saniyesi) ve tick aracılığıyla amount to add (eklenecek miktar).
Ana dosyanızda:
- Bir
Timernesnesini başlangıç saniye değeriyle başlatın - Belirtilen miktarı eklemek için
timer_tickfonksiyonunu çağırın - Mevcut saniyeleri yazdırın
- Zamanlayıcıyı sıfırlamak için
timer_resetfonksiyonunu çağırın - Saniyeleri tekrar yazdırın (0 olmalıdır)
Sonuçları şu formatta yazdırın:
After tick: {seconds}
After reset: {seconds}Örneğin, 30 başlangıç değeri ve 15 saniye ekleme ile çıktı şöyle olacaktır:
After tick: 45
After reset: 0Kopya kağıdı
C'de, struct'lar üzerinde işlem yapan fonksiyonların, geleneksel olarak self veya this olarak adlandırılan bir pointer parametresi aracılığıyla struct örneğine açık erişime ihtiyacı vardır:
typedef struct {
int health;
} Player;
void player_take_damage(Player *self, int amount) {
self->health -= amount;
}
self pointer'ı, fonksiyonun struct verilerine erişmesine ve bunları değiştirmesine olanak tanır. Bu tür fonksiyonları çağırırken, struct'ınızın adresini geçirin:
Player hero = {100};
player_take_damage(&hero, 25);
// hero.health artık 75
Değişiklik yapmak için pointer kullanmak esastır; değer ile geçirmek (passing by value) bir kopya oluşturur ve fonksiyon döndüğünde değişiklikler kaybolur. Pointer, değişikliklerin orijinal struct'ta kalıcı olmasını sağlar.
Kendin dene
#include <stdio.h>
#include "timer.h"
int main() {
int initial_seconds, amount_to_add;
scanf("%d", &initial_seconds);
scanf("%d", &amount_to_add);
// TODO: Bir Timer oluşturun ve onu initial_seconds ile başlatın
// TODO: amount_to_add saniye eklemek için timer_tick fonksiyonunu çağırın
// TODO: Mevcut saniyeyi şu formatta yazdırın: "After tick: {seconds}"
// TODO: Zamanlayıcıyı sıfırlamak için timer_reset fonksiyonunu çağırın
// TODO: Saniyeyi tekrar şu formatta yazdırın: "After reset: {seconds}"
return 0;
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Object Oriented Programming bölümündeki tüm dersler
1Modüler Programlama Temelleri
Başlık DosyalarıInclude Guard'larKaynak DosyalarıStatik FonksiyonlarÖzet: Modüler Hesap Makinesi4Kapsülleme
Opaque Pointer KavramıOpaque Struct TanımlamaGetter ve Setter MetotlarıSetter Metotlarında DoğrulamaÖzet: Gizli Kutu2Nesneler ve Metotlar
Nesne Olarak Struct'lar'Self' İşaretçisiConst Doğruluğuİşaretçi vs DeğerYardımcı MetotlarÖzet: Point Manager5Proje: Basit Banka Hesabı
Proje KurulumuHesabın Oluşturulması3Nesne Yaşam Döngüsü
Constructor DeseniDestructor DeseniStack İlklendirmeDerin KopyalamaÖzet: String Wrapper6Kompozisyon Yoluyla Kalıtım
Struct Gömmeİlk Üye KuralıÜst Üyelere ErişimUpcastingÖzet: Şekil Hiyerarşisi