Source: http://www.vimer.cn/2009/12/cc%E5% AE %9E%E7%8E%B0%E5%A4%9A%E5%8F%82%E6%95%B0%E5%87%BD%E6%95%B0%E7%BC%96%E7%A8%8B.html
In C/C ++, we often need to implement functions like printf, that is, the number of parameters of the function is not fixed. In this case, we need to use this article.ArticleThe method mentioned.
First, we need to know how to define such functions. For example, I want to implement a function that supports fun ("% d", 1 );
The function is defined as follows:
VoidFun (Const Char* FMT ,...);
Here, the parameters cannot be listed one by one, so they are replaced by.... We will discuss how to solve them later.
Specifically, if you want to define the above function as a macro, you can write this macro as follows:
# DefineFun (FMT, argS...) Fun (FMT, # ARGs)
If you want the macro to automatically add line breaks, you can write as follows:
# DefineFun (FMT, argS...) Fun (FMT "\ n", # ARGs)
Okay, so we can solve the function definition problem, but how can we solve it?
C provides functions such as va_start, va_arg, and va_end, which are explained as follows:
Va_start points argp to the first optional parameter. Va_arg returns the current parameter in the parameter list and points argp to the next parameter in the parameter list. Va_end clears the argp pointer to null. The function can traverse these parameters multiple times, but all parameters must start with va_start and end with va_end.
This may not be very clear. Let's give an example.
1. If we want fun to implement the same functions as printf, we do not need to parse all the functions. We only need to pass the parameter as is to printf,CodeAs follows:
VoidFun (Const Char* FMT ,...)
{
Va_list AP;
Va_start (AP, FMT );//Point AP to the first parameter after FMT
Vfprintf (stderr, FMT, AP );
Va_end (AP );//Set AP to null
}
2. If we want to retrieve all input parameters, we need to use va_arg. The Code is as follows:
VoidFun (Const Char* FMT ,...)
{
Va_list AP;
Va_start (AP, FMT );//Point AP to the first parameter after FMT
IntValue = va_arg (AP,Int);//The premise is that we know that the first parameter is int type. The Pointer Points to the next parameter.
Printf ("Value [% d] \ n", Value );
Va_end (AP );//Set AP to null
}
As a matter of fact, it is not difficult to find out how we can traverse all the parameters, as long as the last parameter is specified as a special character, such as-1, then you can judge the value and stop it.
Void Fun ( Const Char * FMT ,...)
{
Va_list AP;
Va_start (AP, FMT ); // Point AP to the first parameter after FMT
Int Value;
Do {
Value = va_arg (AP, Int ); // The premise is that we know that the first parameter is int type. The Pointer Points to the next parameter.
Printf ( " Value [% d] \ n " , Value );
} While (Value! =- 1 );
Va_end (AP ); // Set AP to null
}
OK, so far, Variable Parameter Function writing should be very clear ~