C
Fonksiyonel mantık
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.
Örnek çözümü göster
#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;
}
Kendini test et
-
is_high_priority koşulunu tamamla
return t->priority >= ____;
Cevabı göster
return t->priority >= 3;
-
Filtre parçalarını eşle
- TaskFilter
- Filtre türü
- is_high_priority
- Yüksek öncelik
- task_count_if
- Koşullu sayma
- filter(cur)
- Callback çağrı
-
task_count_if neden fonksiyon işaretçisi alır?
- Farklı filtrelerle çağrılabilsin diye
- Daha az bellek kullansın diye
- Daha hızlı çalışsın diye
- Derleyici uyarısı vermesin diye
Cevabı göster
Farklı filtrelerle çağrılabilsin diye — Fonksiyon işaretçisi sayesinde aynı fonksiyon farklı filtrelerle kullanılır.
Sıradaki ders: Dosya I/O