9.1 Esnek Argümanlı Fonksiyonlar
9.1 Esnek Argümanlı Fonksiyonlar
Aşağıdaki gibi üçüncü dereceden bir polinom düşünelim:
P(x) = a + bx + cx2 + dx3
burada a, b, c, d katsayıları gerçel sayı sabitleridir. Bu polinomu temsil eden en basit fonksiyon şöyle tanımlanabilir.
1 2 3 4 5 |
double p(double x, double a, double b, double c, double d) { double p = a + b*x + c*x*x + d*x*x*x; return p; } |
Buna göre, x = 1.7 için, P(x) = 1 – 2x değerini hesaplamak için bu fonksiyon aşağıdaki gibi çağırılmalıdır:
1 |
sonuc = p(1.7, 1.0, -2.0, 0.0, 0.0); |
Burada, kullanılmayan katsayılar için 0.0 değeri mutlaka fonksiyona geçirilmelidir. Kullanılmayan argumanlar geçirilmeden de fonksiyonu çağırmak mümkündür. C++, Fortran 90 gibi dillerde olduğu gibi, C Programlama Dili, kullanıcılarına argümanları esnek olarak geçirme imkanı verir. Bunun anlamı, belli kurallar sağlandığında, p() fonksiyonu aşağıdaki gibi çağrılabilmesidir:
1 2 |
/* x n a b */ sonuc = p(1.7, 2, 1.0, -2.0); |
Esnek argümanlar için iki temel kural vardır:
- Esnek argümanlar kullanımı isteğe bağlıdır.
- Esnek argümanları oluşturan küme ardışık olarak listeye eklenmelidir.
Bu türden argümanlar, aşağıdaki gibi, fonksiyonun parametre listesi kısmında ... ile belirtilir.
1 2 3 4 |
double p(double x, int n, ...) { } |
Esnek Argumanlı Fonksiyon tanımlaması yapabilmek için stdarg.h kütüphanesinde üç tane makro fonksiyon tanımlanmıştır. Bu fonksiyonlar Tablo 9.1’de listelenmiştir.
Tablo 9.1: stdarg.h’te tanımlı tip ve makro fonksiyonlar
Tip / Fonksiyon | Açıklama |
va_list | ardışık esnek argümalar için tip belirleyici |
va_start(ap, n) | va_list tipinde bildirilmiş ap göstericisi için bellekten n elemanlı yer ayırır. |
va_arg(ap, tip) | Veri tipi tip ile belirlenmiş küme elemanlarına eriştirir. |
va_end(ap) | va_list tipinde bildirilmiş ap göstericisi için bellekten bölgeyi boşaltır. |
Bu kurallar ışığında, p() fonksiyonunun genel kullanımı Program 9.1’de gösterilmiştir. p(), kendisine parametre olarak gelen x, n ve ai katsayılarına göre
P(x,n) = a0 + a1x + a2x2 + … + anxn
polinomu hesaplar. ai (i = 0, 1, 2, …, n) katsayları esnek argüman olarak bildirilmiştir.
Program 9.1: Sonu -1 ile biten kümeyi ekrana yazar
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
/* 09prg01.c: Polinom hesabı */ #include <stdarg.h> #include <stdio.h> #include <math.h> /* fonksiyon örneği */ double p(double, int, ...); int main(void){ double x = 1.7; printf("x = %lf icin:\n",x); printf("p(x, 1, 1.0) = %lf\n", p(x, 1, 1.0)); printf("p(x, 2, 1.0, -2.0) = %lf\n", p(x, 2, 1.0, -2.0)); printf("p(x, 3, 1.0, -2.0, 0.2) = %lf\n", p(x, 3, 1.0, -2.0, 0.2)); printf("p(x, 4, 1.0, -2.0, 0.2, 1.1) = %lf\n", p(x, 4, 1.0, -2.0, 0.2, 1.1)); printf("p(x, 5, 1.0, -2.0, 0.2, 1.1, -0.6) = %lf\n", p(x, 5, 1.0, -2.0, 0.2, 1.1, -0.6)); return 0; } /* Verilen x, n ve ai katsayıları için, P(x,n) = a0 + a1*x + a2*x^2 + ... + an*x^n polinomu hesaplar. a0, a1, ..., an katsayları esnek arguman olarak bildirilmiştir. */ double p(double x, int n, ...) { double a, t = 0.0; int i; /* arguman göstericisi; ag va_list tipinde */ va_list ag; /* ag için bellekten n adet hücre ayır */ va_start(ag, n); for(i=0; i<n; i++) { /* herbir argumanı sırasıyla al */ a = va_arg(ag, double); /* polinomun değerini hesapla */ t += a*pow(x,i); } /* belleği boşalt */ va_end(ag); return t; } |
ÇIKTI
1 2 3 4 5 6 |
x = 1.700000 icin: p(x, 1, 1.0) = 1.000000 p(x, 2, 1.0, -2.0) = -2.400000 p(x, 3, 1.0, -2.0, 0.2) = -1.822000 p(x, 4, 1.0, -2.0, 0.2, 1.1) = 3.582300 p(x, 5, 1.0, -2.0, 0.2, 1.1, -0.6) = -1.428960 |
Program 9.2’de, argümanları esnek olarak bildirilmiş topla(int n, ...) fonksiyonu, n tane tamsayının sayının toplamını hesaplar.
Program 9.2: n tane sayının toplamını hesaplar
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
/* 09prg02.c n tane sayının toplamının hesaplanması */ #include <stdarg.h> #include <stdio.h> int topla(int, ...); int main(void) { printf("topla(2, 11,22) = %d\n", topla(2, 11,22)); printf("topla(3, 11,22,33) = %d\n", topla(3, 11,22,33)); printf("topla(4, 11,22,33,44) = %d\n", topla(4, 11,22,33,44)); printf("topla(5, 11,22,33,44,55) = %d\n", topla(5, 11,22,33,44,55)); printf("topla(6, 11,22,33,44,55,66) = %d\n", topla(6, 11,22,33,44,66,66)); return 0; } /* Esnek argumanla tanımlanmış n tane tamsayının sayının toplamını gönderir */ int topla(int n, ...) { va_list ap; int i, top = 0; va_start(ap, n); for (i=1; i<=n; i++) top += va_arg(ap, int); va_end(ap); return top; } |
ÇIKTI
1 2 3 4 5 |
topla(2, 11,22) = 33 topla(3, 11,22,33) = 66 topla(3, 11,22,33,44) = 110 topla(5, 11,22,33,44,55) = 165 topla(6, 11,22,33,44,55,66) = 242 |
Argüman sayısı bilidirilmeden de bir küme üzerinde işlem yapılabilir. Ancak bu durumda kümenin boyutu başka bir yöntemle hesaplanmalıdır. Program 9.3’de, argümanları esnek olarak bildirilmiş argyaz(int arg, ...) fonksiyonu, son elemanı -1 olan bir kümenin elemanlarını ekrana yazar. Kümenin sonu (yani boyutu) -1 ile belirlenmiş olur.
Program 9.3: Sonu -1 ile biten kümeyi ekrana yazar
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
/* 09prg03.c: Esnek argumanların yazdırılması */ #include <stdio.h> #include <stdarg.h> /* herbiri int tipinde ve sonu -1 ile biten kümeyi ekrana yazar */ void argyaz(int arg, ...) { va_list ap; int i; va_start(ap, arg); for (i = arg; i != -1; i = va_arg(ap, int)) printf("%d ", i); va_end(ap); putchar('\n'); } int main(void) { argyaz(5, 2, 14, 84, 97, 15, 24, 48, -1); argyaz(84, 51, -1); argyaz(-1); argyaz(1, -1); return 0; } |
ÇIKTI
1 2 3 4 |
5 2 14 84 97 15 24 48 84 51 1 |