CodeBlanks Logo Icon CodeBlanks

Fonksiyonel mantık

  • C kursu
  • Orta seviye
  • Ders 114/116
  • 6 dk

Fonksiyon işaretçileri ve callback'lerle iş mantığı yazarsın.

Filtre ile sayma

Üçüncü ders, fonksiyon işaretçisi ile koşullu sayma ekler. TaskFilter typedef'i, bir görevin bir koşulu sağlayıp sağlamadığını sınayan fonksiyonların türünü tanımlar.

typedef int (*TaskFilter)(const Task *); ile filtre türünü tanımlarsın. is_high_priority fonksiyonu, öncelik 3 veya daha büyükse 1 döndürür. task_count_if fonksiyonu, listeyi gezer ve filtre ile her görevi sınar; koşulu sağlayanların sayısını döndürür. Bu desen, callback tabanlı soyutlamanın güzel bir örneğidir; aynı task_count_if fonksiyonu farklı filtrelerle çağrılabilir. Önceki dersin kodu bu dersin başlangıç koduna dahildir.

task_count_if uygulaması

task_count_if, bir TaskFilter alır ve listeyi gezerken her görevi bu filtre ile sınar. Koşulu sağlayan her görev için sayacı artırır.

Uygulama: int count = 0; const Task *cur = list; while (cur) { if (filter(cur)) count++; cur = cur->next; } return count;. Burada filter(cur), filtre fonksiyonunu çağırır; doğru dönerse sayar. Bu, fonksiyon işaretçisinin gücünü gösterir; task_count_if fonksiyonu filtre uygulamasını bilmez, yalnızca çağırır. Aynı fonksiyon, is_low_priority veya is_named_ödemeli gibi başka filtrelerle de kullanılabilir. Bu, gerçek kütüphanelerdeki qsort callback deseninin aynısıdır.

Uygulama Filtre ile sayma ekle

typedef int (*TaskFilter)(const Task *); tanımla. int is_high_priority(const Task *t) yaz; t->priority >= 3 döndür. int task_count_if(const Task *list, TaskFilter filter) yaz; listede dolaş, filtre ile say. main içinde iki görev ekle, task_print(g_list); çağır, int high = task_count_if(g_list, is_high_priority); ile say ve printf("yüksek: %d\n", high); yazdır.

Başlangıç kodu

main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct Task {
    char name[32];
    int priority;
    struct Task *next;
} Task;

Task *g_list = NULL;

Task *task_new(const char *name, int priority) {
    Task *t = malloc(sizeof(Task));
    strncpy(t->name, name, 31);
    t->name[31] = '\0';
    t->priority = priority;
    t->next = NULL;
    return t;
}

void task_push_front(Task **list, Task *t) {
    t->next = *list;
    *list = t;
}

void task_print(const Task *list) {
    const Task *cur = list;
    while (cur) {
        printf("%s: %d\n", cur->name, cur->priority);
        cur = cur->next;
    }
}

// TaskFilter türünü typedef ile tanımla
// is_high_priority fonksiyonunu yaz
// task_count_if fonksiyonunu yaz
// main'de yüksek öncelikli sayısını yazdır

int main(void) {
    task_push_front(&g_list, task_new("Ödeme", 1));
    task_push_front(&g_list, task_new("Paketle", 3));
    task_print(g_list);
    return 0;
}

Örnek çözüm

main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct Task {
    char name[32];
    int priority;
    struct Task *next;
} Task;

Task *g_list = NULL;

Task *task_new(const char *name, int priority) {
    Task *t = malloc(sizeof(Task));
    strncpy(t->name, name, 31);
    t->name[31] = '\0';
    t->priority = priority;
    t->next = NULL;
    return t;
}

void task_push_front(Task **list, Task *t) {
    t->next = *list;
    *list = t;
}

void task_print(const Task *list) {
    const Task *cur = list;
    while (cur) {
        printf("%s: %d\n", cur->name, cur->priority);
        cur = cur->next;
    }
}

typedef int (*TaskFilter)(const Task *);

int is_high_priority(const Task *t) {
    return t->priority >= 3;
}

int task_count_if(const Task *list, TaskFilter filter) {
    int count = 0;
    const Task *cur = list;
    while (cur) {
        if (filter(cur)) count++;
        cur = cur->next;
    }
    return count;
}

int main(void) {
    task_push_front(&g_list, task_new("Ödeme", 1));
    task_push_front(&g_list, task_new("Paketle", 3));
    task_print(g_list);
    int high = task_count_if(g_list, is_high_priority);
    printf("yüksek: %d\n", high);
    return 0;
}

Beklenen çıktı

Paketle: 3
Ödeme: 1
yüksek: 1

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 is_high_priority koşulunu tamamla

Soru
return t->priority >= ____;
Cevap
return t->priority >= 3;

Açıklama: t->priority >= 3 yüksek öncelik için eşiktir.

2 Filtre parçalarını eşle

Kavram Anlamı
TaskFilter Filtre türü
is_high_priority Yüksek öncelik
task_count_if Koşullu sayma
filter(cur) Callback çağrı

3 task_count_if neden fonksiyon işaretçisi alır?

  • Farklı filtrelerle çağrılabilsin diye Doğru cevap
  • Daha az bellek kullansın diye
  • Daha hızlı çalışsın diye
  • Derleyici uyarısı vermesin diye

Açıklama: Fonksiyon işaretçisi sayesinde aynı fonksiyon farklı filtrelerle kullanılır.

Orta seviye bölümündeki tüm dersler