Menu
Coddy logo textTech

İlk Üye Kuralı

Coddy'nin C Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 29 / 61.

Bir struct'ı başka bir struct'ın ilk üyesi olarak gömdüğünüzde güçlü bir şey gerçekleşir: dış struct'ın bellek adresi, ilk üyesinin bellek adresiyle aynıdır. Bu, C standardı tarafından garanti edilir.

Önceki örneğimizi ele alalım:

typedef struct {
    int id;
} Parent;

typedef struct {
    Parent parent;  // İlk üye
    int grade;
} Child;

Bir Child değişkeni oluşturduğunuzda, Parent üyesi Child'ın belleğinin tam başlangıcında yer alır. Bu, Child'a yönelik bir işaretçinin, onun Parent üyesine yönelik bir işaretçiyle tamamen aynı adresi gösterdiği anlamına gelir.

Child c;
Child* child_ptr = &c;
Parent* parent_ptr = (Parent*)child_ptr;  // Güvenli cast!

Her iki işaretçi de aynı adresi tutar. Bu, bir Child* işaretçisini Parent* bekleyen herhangi bir işleve aktarmanı sağlar:

void print_id(Parent* p) {
    printf("ID: %d\n", p->id);
}

// main içinde:
Child c;
c.parent.id = 42;
print_id((Parent*)&c);  // Mükemmel çalışır

Bu teknik, C'de kalıtımın temelidir. Temel tür için yazılmış bir işlev, temel tür önce gömüldüğü sürece herhangi bir türetilmiş tür üzerinde çalışabilir. Bellek düzenleri tamamen uyumlu olduğundan dönüşüm güvenlidir.

challenge icon

Görev

Kolay

Basit bir hayvan hiyerarşisi oluşturarak ilk üye kuralını keşfedelim. Bir temel Animal yapısı ve türetilmiş bir Dog yapısı oluşturacak, ardından Dog işaretçisinin güvenli bir şekilde Animal işaretçisine dönüştürülebileceğini göstereceksin.

Uygulayacağın temel fikir şu: Animal, Dog yapısının ilk üyesi olduğunda, her iki yapı da aynı başlangıç bellek adresini paylaşır. Bu, işaretçiyi dönüştürerek bir Dog* değerini Animal* bekleyen herhangi bir işleve geçirebileceğin anlamına gelir.

Kodunu üç dosyada düzenleyeceksin:

  • animal.h: Her iki yapıyı include guard'larıyla tanımla. Animal yapın tek bir alana sahip olmalı: legs (bacak sayısını temsil eden bir tamsayı). Dog yapın, Animal yapısını ilk üye olarak içermeli ve bir name alanı (50 karakterlik bir karakter dizisi) eklemeli. Ayrıca print_animal parametresi alan bir Animal* işlevi bildir.
  • animal.c: print_animal işlevini uygula. Bu işlev temel türle çalışır. Yalnızca Animal hakkında bilgi sahibidir ve hayvanın kaç bacağı olduğunu yazdırır.
  • main.c: Bir Dog değişkeni oluştur ve alanlarını (hem içindeki hayvanın bacak sayısını hem de köpeğin adını) doldur. Ardından Dog* değerini Animal* değerine dönüştürüp print_animal işlevine geçirerek ilk üye kuralını göster. Eksiksiz resmi göstermek için köpeğin adını ayrıca yazdır.

İki girdi alacaksın: köpeğin adı (bir dize) ve bacak sayısı (bir tamsayı).

Çıktın şöyle görünmeli:

Dog: Buddy
Legs: 4

Burada Buddy köpeğin adı, 4 ise bacak sayısıdır. Önce köpeğin adını main.c içinden yazdır, ardından bacakları görüntülemek için dönüştürülmüş işaretçiyle print_animal işlevini çağır.

Bu, temel tür için (Animal) yazılmış bir işlevin, işaretçi dönüştürme yoluyla türetilmiş bir türle (Dog) sorunsuzca çalışabileceğini gösterir: C dilinde kalıtımın temeli budur.

Kendin dene

#include <stdio.h>
#include <string.h>
#include "animal.h"

int main() {
    // Girdiyi oku
    char name[50];
    int legs;
    scanf("%s", name);
    scanf("%d", &legs);
    
    // TODO: Bir Dog değişkeni oluştur
    
    // TODO: strcpy kullanarak köpeğin adını ayarla
    
    // TODO: Bacak sayısını ayarla (gömülü Animal üzerinden eriş)
    
    // TODO: Köpeğin adını şu formatta yazdır: "Dog: <name>"
    
    // TODO: Dog*'ı Animal*'a cast et ve print_animal'ı çağır
    // Bu, ilk üye kuralını gösterir!
    
    return 0;
}
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler

Kendi başına pratik yap: Online C derleyicisi