Implementation of Variable Parameter List
When learning C language, do you think that printf is a God-like function like me? He can accept different numbers and different types of parameters. How does he implement it?
Let's take a look at its source code:
Printf source code:
int printf(const char *fmt,...){int res; va_list arg;va_start(arg,fmt);res = vprintf(fmt,arg);va_end(arg);return res;}
It uses a variable parameter list. The variable parameter list has the following two disadvantages:
1) The length of the variable parameter list cannot be determined, which is also the reason why printf provides wildcards;
2) The type check is not available. problems may occur during the copy process of the real Parameter Vector parameter. Generally, it is recommended to pass only the basic data type.
One type: va_list; three macros: va_start;
First, we will introduce a function implemented by using the variable parameter list)
# Include
# Include
Using namespace std;/* variable parameter list to calculate the sum of uncertain numbers and */int sum (int n, int v1 ,...) {va_list arg; va_start (arg, v1); int sum = v1; for (int I = 0; I
1. va_list
1) Usage:
int sum(int n,int v1,...){va_list arg;。。。。。。。}
As shown above, a va_list variable arg is defined, which can be used as a pointer to save the variable parameter list. In actual use, if you reference the variable parameter list as an array, the va_list is equivalent to its iterator.
This macro is just a definition. What makes it really meaningful is the following macros.
2) Implementation: Actually, it is only a char * type pointer, because the type cannot be determined here, so it is easy to move the char type pointer with size 1.
2. va_start
1) usage:
int sum(int n,int v1,...){va_list arg;va_start(arg,v1);。。。。。。}
This macro requires two parameters. The first is the va_list defined above, and the second is the parameter before the variable parameter list.
It directs the va_list variable to the first address of the variable parameter list. This is the initialization of va_list in the general sense.
2) Implementation:
#define va_start ( ap, v ) ( ap = (va_list)&v + _INTSIZEOF(v) )
It is easy to understand, that is, to point the ap to the address after v.
3) Note:
According to the specification, the parameter in va_start must be the last parameter, that is, the parameter earlier than..., otherwise there may be problems. Especially in windows and linux, function parameters are in different stack order, which may cause portability problems.
3. va_arg
1) usage:
int tmp = va_arg(arg,int);
There are also two parameters. The first one is the variable arg that has been initialized by va_list and the second is the type. For example, if the first parameter in the Variable Parameter List is of the int type, the int type is passed.
This function implements a function similar to the iterator. Its return value is the int type value pointed to by the current itor (the type is described by the second parameter), and The itor is moved, point to the next parameter in the Variable Parameter List.
4. va_end
1) usage:
va_end(arg);
2) Implementation:This macro is actually an empty implementation, which improves the readability of the code and facilitates subsequent extension.
5. missing ....
As an iterator, the most important link missing is the final judgment. Unfortunately, it is impossible to provide it here. Let's just end it with a NULL string.