Özet - Değişken argümanlar
- C kursu
- Orta seviye
- Ders 81/116
- 5 dk
va_list ve vsnprintf'i birleştirerek bir log fonksiyonu yazarsın.
Özet - Değişken argümanlar
Bu grupta stdarg.h'ın dört aracını öğrendik: va_list, va_start, va_arg, va_end. Ayrıca vprintf ve vsnprintf ile printf benzeri fonksiyonlar yazdık.
Mini görev: sum_n ve max_n fonksiyonlarını tanımla; main'de sum_n(3, 10, 20, 30) ve max_n(3, 10, 20, 30) çağırıp tek bir printf ile yazdır. Bu, iki deseni birleştirir: biriktirme (sum, 0 ile başlar) ve tohumlu karşılaştırma (max, ilk argüman ile başlar). Her fonksiyon kendi va_list'ini açar ve kapatır; va_end asla atlanmaz. Çıktı: toplam 60, en büyük 30.
Uygulama sum_n ve max_n'yi birleştir
int sum_n(int count, ...) yaz: va_list, va_start(args, count), int total = 0;, for ile total += va_arg(args, int), va_end(args), return total. int max_n(int count, ...) yaz: ilk va_arg'ı max'a ata, for ile va_arg oku, if (v > max) max = v;, va_end, return max. main'de printf("toplam %d, en büyük %d\n", sum_n(3, 10, 20, 30), max_n(3, 10, 20, 30));.
Başlangıç kodu
#include <stdio.h>
#include <stdarg.h>
// sum_n: count adet int'i topla
// max_n: count adet int'in en büyüğü
// main: printf ile ikisini birden yazdır: "toplam %d, en büyük %d\n"
int main(void) {
// buraya yaz
return 0;
}Örnek çözüm
#include <stdio.h>
#include <stdarg.h>
int sum_n(int count, ...) {
va_list args;
va_start(args, count);
int total = 0;
for (int i = 0; i < count; i++) total += va_arg(args, int);
va_end(args);
return total;
}
int max_n(int count, ...) {
va_list args;
va_start(args, count);
int max = va_arg(args, int);
for (int i = 1; i < count; i++) {
int v = va_arg(args, int);
if (v > max) max = v;
}
va_end(args);
return max;
}
int main(void) {
printf("toplam %d, en büyük %d\n", sum_n(3, 10, 20, 30), max_n(3, 10, 20, 30));
return 0;
}Beklenen çıktı
toplam 60, en büyük 30
Değişken argümanlarda dikkat
Değişken argümanlar güçlü ama dikkat ister. Üç temel nokta: tür güvenliği yoktur (va_arg'a yanlış tür verirsen tanımsız davranış), argüman sayısı bilinmelidir (count veya format dizesinden), va_end asla atlanmaz.
va_arg(args, int) çağrısında argüman gerçekten int değilse çöp okursun; derleyici bunu denetlemez. Bu yüzden printf'in format belirteçleri ve argüman türleri eşleşmelidir. Argüman sayısını bilmek senin sorumluluğundur; count parametresi veya NULL sonlandırıcı (dizelerde) kullanılır. vsnprintf gibi güvenli varyantlar taşmayı önler; vsprintf yerine her zaman onu tercih et. Bu ilkeler, sağlam C kitaplıklarının temelidir.
Soru ve cevaplar
Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.
1 Desenleri eşleştir
| Kavram | Anlamı |
|---|---|
sum_n |
0 ile başlar |
max_n |
ilk argümanla başlar |
log_msg |
vprintf kullanır |
format_into |
vsnprintf kullanır |
2 Her va_start çağrısına karşılık ne yapılmalı?
- iki va_arg çağrısı
- bir va_end çağrısı Doğru cevap
- return yazmak
- printf çağırmak
Açıklama: Her va_start'a bir va_end eşlik etmelidir.