Giriş
Variadic Function değişken sayıda parametre alabilen metod anlamına gelir.
Variadic Function değişken sayıda parametre alabilen metod anlamına gelir.
Variadic Function Tarihçesi
Açıklaması şöyle. İlginç bir şekilde C diline girmeden önce C++'ta kullanılmış.
Açıklaması şöyle. İlginç bir şekilde C diline girmeden önce C++'ta kullanılmış.
To add to the other answers, the func(arg, ...) syntax first developed in C++, and then was incorporated into the ANSI C standard, sometime between 1984 and 1988.
Variadic Parametreler Nasıl Geçilirler
Bu konuda C++ standardı bir açıklama getirmiyor. Derleyiciler kendi çözümlerini üretmişler. Cevapta stack kullanılması açıklanmış.
Non-POD Type
non-pod tiplerin - örneğin bir sınıf - variadic parametre olarak geçilmesi tanımsız davranış. Yani yapılmaması gerekir. Açıklaması şöyle
Önce bir metod tanımlarız. Şöyle yaparız.
+ int
İmzası şöyle
Şöyle yaparız.
Aynı metod için listeyi temizlememiz gerekir. Açıklaması şöyle
Parametreye va_arg ile şöyle erişiriz.
vsnprintf
vsnprintf yazısına taşıdım.
vfprintf
Şu satırı dahil ederiz.
Variadic Function yerine array geçmek daha kolay olabilir.
C++
C++'ta Variadic Function'ların bence yeri yok. Artık kullanılmamalı. st::array, std::vector, std::initializer_list ve hatta variadic template bile kullanılabilir.
Bu konuda C++ standardı bir açıklama getirmiyor. Derleyiciler kendi çözümlerini üretmişler. Cevapta stack kullanılması açıklanmış.
Non-POD Type
non-pod tiplerin - örneğin bir sınıf - variadic parametre olarak geçilmesi tanımsız davranış. Yani yapılmaması gerekir. Açıklaması şöyle
You cannot pass non-POD types to C-style variadic functions
Macrolar
va_list, va_start, va_end,va_arg macroları için şu satırı dahil ederiz.#include <stdarg.h>
va_list macrosuÖnce bir metod tanımlarız. Şöyle yaparız.
void setList(int count, ...) {
...
}
Metodun içinde parametreleri okumak için bir liste oluştururuz. Şöyle yaparız.void setList( int count, ... ) {
va_list numbers;
va_start (numbers, count);
...
va_end (numbers);
}
va_start macrosu va_list değişkenine yazdığı için va_list memset ile sıfırlamaya gerek yok. Şu kod fazladan iş yapıyor.va_list args;
memset(&args, 0, sizeof(va_list));
va_start(args, xxx);
...
va_end(args);
va_start macrosu - va_list İmzası şöyle
void va_start(va_list ap, last);
Açıklaması şöyle.Açıklaması şöyle.The va_start() macro initializes ap for subsequent use by va_arg() and va_end(), and must be called first.
2 The va_start macro shall be invoked before any access to the unnamed arguments.Şöyle yaparız.
3 The va_start macro initializes ap for subsequent use by the va_arg and va_end macros. Neither the va_start nor va_copy macro shall be invoked to reinitialize ap without an intervening invocation of the va_end macro for the same ap .
void setList(int count, ... ) {
va_list numbers;
va_start (numbers, count);
...
va_end (numbers);
}
va_start macrosu - va_list + char *Şöyle yaparız.
void debug(int msglevel, const char *fmt, ...)
{
va_list va;
va_start(va, fmt);
vfprintf(stderr, fmt, va);
va_end(va);
}
va_end macrosuAynı metod için listeyi temizlememiz gerekir. Açıklaması şöyle
va_arg macrosu - intEach invocation of va_start() must be matched by a corresponding invocation of va_end() in the same function.
Parametreye va_arg ile şöyle erişiriz.
for(int n = 0; n < count; n++)
int num = va_arg(numbers, int);
Bazı Önemli Variadic Metodlar
printf
printf yazısına taşıdım.printf
vsnprintf
vsnprintf yazısına taşıdım.
vfprintf
Şu satırı dahil ederiz.
#include <cstdio>
Şöyle yaparız.void debug(int msglevel, const char *fmt, ...)
{
va_list va;
va_start(va, fmt);
vfprintf(stderr, fmt, va);
va_end(va);
}
Array GeçmekVariadic Function yerine array geçmek daha kolay olabilir.
C++
C++'ta Variadic Function'ların bence yeri yok. Artık kullanılmamalı. st::array, std::vector, std::initializer_list ve hatta variadic template bile kullanılabilir.
Hiç yorum yok:
Yorum Gönder