Menu
CoddyTech

Jenerik Sarmalayıcı

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

Tek başına bir void* her türlü veriyi saklayabilir, ancak kritik bir kusuru vardır: hangi türü tuttuğunu takip edemezsiniz. Gerçekten kullanışlı genel amaçlı kapsayıcılar oluşturmak için veri işaretçisini tür bilgileriyle eşleştirmemiz gerekir. Genel Kapsayıcı deseni burada devreye girer.

Fikir basit: bir void* işaretçiyi depolanan türü tanımlayan bir enum ile bir araya getiren bir struct oluşturun. Bu şekilde wrapper, içeriğini nasıl yorumlayacağını her zaman bilir.

typedef enum {
    TYPE_INT,
    TYPE_STRING
} DataType;
typedef struct {
    void* data;
    DataType type;
} Wrapper;

Veri depolarken, gerçek değer için bellek ayırır ve türünü kaydedersiniz. Veriyi alırken, dönüştürmeden önce türü kontrol edersiniz:

Wrapper wrap_int(int value) {
    int* p = malloc(sizeof(int));
    *p = value;
    return (Wrapper){ .data = p, .type = TYPE_INT };
}
void print_wrapper(Wrapper* w) {
    if (w->type == TYPE_INT) {
        printf("%d\n", *(int*)w->data);
    } else if (w->type == TYPE_STRING) {
        printf("%s\n", (char*)w->data);
    }
}

Bu desen, C dilinde tür güvenli genel amaçlı kapsayıcılar oluşturmanın temelidir. Enum, çalışma zamanında tür etiketi görevi görerek kodunuzun depolanan verilerin nasıl işleneceğine dair güvenli kararlar vermesini sağlar.

challenge icon

Görev

Kolay

Daha sonra verileri güvenli bir şekilde alıp yazdırabilmemiz için, bir tamsayı veya bir dize depolayabilen ve tuttuğu türü izleyen, tür güvenli bir genel sarmalayıcı sistemi oluşturalım.

Kodunuzu üç dosya arasında düzenleyeceksiniz:

  • wrapper.h: TYPE_INT ve TYPE_STRING değerlerine sahip bir DataType enum'u tanımlayın. Ardından, bir void* veri işaretçisini DataType alanıyla bir araya getiren bir Wrapper struct'ı tanımlayın. Sarmalayıcıları oluşturmak ve içeriklerini yazdırmak için işlev prototiplerini bildirin.
  • wrapper.c: Sarmalayıcı işlevselliğini uygulayın:
    • wrap_int: bir tamsayı alır, bunun için bellek ayırır, değeri depolar ve uygun tür etiketiyle bir Wrapper döndürür
    • wrap_string: bir dize (char*) alır, bellek ayırır ve dizeyi kopyalar; ardından dize türü etiketiyle bir Wrapper döndürür
    • print_wrapper: tür etiketini kontrol eder ve verileri uygun şekilde yazdırır (tamsayı olduğu gibi, dize olduğu gibi)
    • free_wrapper: sarmalayıcının içindeki dinamik olarak ayrılmış belleği serbest bırakır
  • main.c: Her şeyi bir araya getirin. Bir değerle birlikte bir tür göstergesi (i tamsayı, s dize için) okuyun. Uygun sarmalayıcıyı oluşturun, içeriğini yazdırın ve belleği serbest bırakın.

Programınız iki girdi alacaktır:

  1. Bir tür göstergesi: tamsayı için i veya dize için s
  2. Sarmalanacak değer

Girdiler i ve 42 olduğunda örnek çıktı:

42

Girdiler s ve Hello olduğunda örnek çıktı:

Hello

Girdiler i ve -100 olduğunda örnek çıktı:

-100

Girdiler s ve Generic Programming olduğunda örnek çıktı:

Generic Programming

Başlık dosyanızda include guard kullanmayı unutmayın. Dize kopyalama işlemi için, strlen ve strcpy kullanarak dize ve null sonlandırıcı için yeterli alan ayırın.

Kendin dene

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

int main() {
    char type;
    scanf("%c", &type);
    getchar(); // yeni satırı tüket
    
    Wrapper w;
    
    if (type == 'i') {
        int value;
        scanf("%d", &value);
        // TODO: wrap_int kullanarak bir tamsayı sarmalayıcı oluştur
        
    } else if (type == 's') {
        char str[256];
        fgets(str, sizeof(str), stdin);
        // Varsa sondaki yeni satırı kaldır
        str[strcspn(str, "\n")] = '\0';
        // TODO: wrap_string kullanarak bir dize sarmalayıcı oluştur
        
    }
    
    // TODO: print_wrapper kullanarak sarmalayıcı içeriğini yazdır
    
    // TODO: free_wrapper kullanarak sarmalayıcı belleğini serbest bırak
    
    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