Üst Üyelere Erişim
Coddy'nin C Journey'sinin Object Oriented Programming bölümünün bir parçası — ders 30 / 61.
Artık struct gömme (struct embedding) ve ilk üye kuralını (first member rule) anladığımıza göre, pratik tarafa odaklanalım: bir fonksiyon içinden gömülü üst öğenin (parent) verilerinin nasıl okunacağı ve değiştirileceği.
Bir fonksiyon bir Child struct'ı (veya ona işaret eden bir pointer) aldığında, üst öğenin (parent) üyelerine erişmek, gömülü struct üzerinden ilerlemeyi gerektirir. Sözdizimi, bir değerle mi yoksa bir pointer ile mi çalıştığınıza bağlıdır.
typedef struct {
int id;
int score;
} Parent;
typedef struct {
Parent parent;
char grade;
} Child;Child için bir pointer (işaretçi) kullanarak, ebeveyne ulaşmak için ok operatörünü, ardından üyelerine erişmek için nokta operatörünü kullanın:
void update_score(Child* c, int new_score) {
c->parent.score = new_score; // Önce ok, sonra nokta
}
void print_info(Child* c) {
printf("ID: %d, Score: %d\n", c->parent.id, c->parent.score);
}Bir değer (kopya ile geçilen) ile her yerde nokta kullanın:
void show_id(Child c) {
printf("ID: %d\n", c.parent.id); // Nokta sonra nokta
}Bu zincirleme erişim deseni — child->parent.member veya child.parent.member — C'nin kompozisyon modelinde kalıtılan verilerle bu şekilde etkileşim kurmanızı sağlar. Gerçek kalıtımdan biraz daha ayrıntılıdır, ancak türler arasındaki ilişki konusunda açık ve nettir.
Görev
KolayGömülü bir struct içindeki verilere nasıl erişileceğini ve bu verilerin nasıl değiştirileceğini gösteren bir öğrenci notlandırma sistemi oluşturalım. Bir Student yapısının gömülü bir Person içerdiği bir hiyerarşi oluşturacak, ardından çocuk üzerinden ebeveynin verileriyle çalışan fonksiyonlar yazacaksınız.
Kodunuzu üç dosya halinde düzenleyeceksiniz:
student.h: Struct hiyerarşinizi include guard'lar ile tanımlayın.name(50 karakterlik bir karakter dizisi) veage(bir tam sayı) içeren birPersonstruct'ı oluşturun. Ardından, ilk üyesi olarakPersonyapısını gömen ve birgradealanı (puanlarını temsil eden bir tam sayı) ekleyen birStudentstruct'ı tanımlayın. İki fonksiyon bildirin: BirStudent*ve yeni bir yaş değeri alanset_person_ageve birStudent*alıp tüm bilgileri görüntüleyenprint_student.student.c: Her iki fonksiyonu da uygulayın.set_person_agefonksiyonunuz, gömülüPersonstruct'ı içindeki yaşı değiştirmelidir; burası önce ok, sonra nokta sözdizimi (s->person.age) pratiği yapacağınız yerdir.print_studentfonksiyonunuz hem gömülü kişiden hem de öğrencinin kendisinden tüm alanlara erişmeli ve bunları görüntülemelidir.main.c: BirStudentdeğişkeni oluşturun ve tüm alanlarını başlatın. Ardından, gömülü kişinin yaşını güncellemek içinset_person_agefonksiyonunu kullanın ve sonucu görüntülemek içinprint_studentfonksiyonunu çağırın.
Dört girdi alacaksınız: öğrencinin adı (bir dize), başlangıç yaşı (bir tam sayı), notu (bir tam sayı) ve yeni yaşı (fonksiyonunuz aracılığıyla güncellenecek bir tam sayı).
Ana dosyanızda, öğrenciyi başlangıç değerleriyle oluşturun, ardından yaşı yeni değerle değiştirmek için set_person_age fonksiyonunu çağırın ve son olarak güncellenmiş bilgileri görüntülemek için print_student fonksiyonunu çağırın.
Çıktınız şu şekilde görünmelidir:
Name: Emma
Age: 21
Grade: 85Burada Emma isim, 21 güncellenmiş yaş (başlangıç yaşı değil) ve 85 nottur. Buradaki temel öğrenim, ebeveynin üyelerini hem okumak hem de yazmak için gömülü struct içinde gezinmektir.
Kopya kağıdı
Bir fonksiyondan gömülü üst yapı (parent struct) üyelerine erişmek için, bir işaretçiyle mi yoksa bir değerle mi çalıştığınıza bağlı olan zincirleme erişim sözdizimini kullanın.
Alt yapıya (child struct) yönelik bir işaretçi ile, gömülü üst yapıya ulaşmak için ok operatörünü, ardından üyelerine erişmek için nokta notasyonunu kullanın:
void update_score(Child* c, int new_score) {
c->parent.score = new_score; // Önce ok sonra nokta
}
void print_info(Child* c) {
printf("ID: %d, Score: %d\n", c->parent.id, c->parent.score);
}Bir değer ile (kopyalanarak aktarılan), baştan sona nokta notasyonunu kullanın:
void show_id(Child c) {
printf("ID: %d\n", c.parent.id); // Önce nokta sonra nokta
}Bu desen — child->parent.member veya child.parent.member — C'nin kompozisyon modelinde kalıtılan verilere açık erişim sağlar.
Kendin dene
#include <stdio.h>
#include <string.h>
#include "student.h"
int main() {
char name[50];
int initial_age, grade, new_age;
// Girdileri oku
fgets(name, 50, stdin);
name[strcspn(name, "\n")] = '\0'; // Yeni satır karakterini kaldır
scanf("%d", &initial_age);
scanf("%d", &grade);
scanf("%d", &new_age);
// TODO: Bir Student değişkeni oluştur
// TODO: Öğrencinin tüm alanlarını ilklendir
// - strcpy kullanarak ismi gömülü person'ın ismine kopyala
// - Gömülü person'ın yaşını initial_age olarak ayarla
// - Öğrencinin notunu (grade) ayarla
// TODO: Yaşı new_age olarak güncellemek için set_person_age fonksiyonunu çağır
// TODO: Sonucu görüntülemek için print_student fonksiyonunu çağır
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