Issues and Solutions during compilation
Although you can read all the variable parameters by traversing the parameter list in the stack, since you do not know how many variable parameters are there, when should I end the traversal? If there are too many traversal parameters in the stack, it is very likely to read some invalid data.
Solution:. you can specify the number of parameters in the first starting parameter, then you can read all variable parameters in the loop; B. define an end mark. When calling a function, pass this mark in the last parameter. In this way, when traversing a variable parameter, you can end the traversal of the Variable Parameter Based on this mark;
The following is an example code:
// The first parameter defines the number of optional parameters, which is used to obtain the initial parameter content cyclically.
Void arg_cnt (int cnt ,...);
Int main (INT argc, char * argv [])
{
Int int_size = _ intsizeof (INT );
Printf ("int_size = % d/N", int_size );
Arg_cnt (4, 1, 2, 3, 4 );
Return 0;
}
Void arg_cnt (int cnt ,...)
{
Int value = 0;
Int I = 0;
Int arg_cnt = CNT;
Va_list arg_ptr;
Va_start (arg_ptr, CNT );
For (I = 0; I <CNT; I ++)
{
Value = va_arg (arg_ptr, INT );
Printf ("Value % d = % d/N", I + 1, value );
}
}Although the number of read parameters can be solved according to the above two methods, what should we do if the parameter types are not fixed? If we do not know the parameter type, there is no way to process the read parameters. solution: You can customize some possible parameter types. In this way, in the variable parameter list, you can change the type in the variable parameter list, and then read the variable parameter value according to the type, and perform accurate conversion. when passing parameters, you can pass the following parameters: Variable Parameter number, variable parameter Type 1, variable parameter value 1, variable parameter type 2, variable parameter value 2 ,....
Here is a complete example:
# Include <stdio. h>
# Include <stdarg. h>
Const int int_type = 100000;
Const int str_type = 100001;
Const int char_type = 100002;
Const int maid = 100003;
Const int float_type = 100004;
Const int double_type = 100005;
// The first parameter defines the number of optional parameters, which is used to obtain the initial parameter content cyclically.
// Variable parameters are transmitted in the form of arg_type, arg_value... to process different variable parameter types
Void arg_type (int cnt ,...);
// The first parameter defines the number of optional parameters, which is used to obtain the initial parameter content cyclically.
Void arg_cnt (int cnt ,...);
// Test the usage of va_start and va_arg and the address distribution of function parameters in the stack.
Void arg_test (int I ,...);
Int main (INT argc, char * argv [])
{
Int int_size = _ intsizeof (INT );
Printf ("int_size = % d/N", int_size );
Arg_test (0, 4 );
Arg_cnt (4, 1, 2, 3, 4 );
Arg_type (2, int_type, 222, str_type, "OK, hello World! ");
Return 0;
}
Void arg_test (int I ,...)
{
Int J = 0;
Va_list arg_ptr;
Va_start (arg_ptr, I );
Printf ("& I = % P/N", & I); // print the address of parameter I in the stack
Printf ("arg_ptr = % P/N", arg_ptr );
// Print the arg_ptr address after va_start,
// It should be higher than the address of parameter I in sizeof (INT) bytes
// Arg_ptr points to the address of the next parameter.
J = * (int *) arg_ptr );
Printf ("% d/N", I, j );
J = va_arg (arg_ptr, INT );
Printf ("arg_ptr = % P/N", arg_ptr );
// Print the address of arg_ptr after va_arg
// It should be higher than the sizeof (INT) byte before calling va_arg
// Arg_ptr points to the address of the next parameter.
Va_end (arg_ptr );
Printf ("% d/N", I, j );
}
Void arg_cnt (int cnt ,...)
{
Int value = 0;
Int I = 0;
Int arg_cnt = CNT;
Va_list arg_ptr;
Va_start (arg_ptr, CNT );
For (I = 0; I <CNT; I ++)
{
Value = va_arg (arg_ptr, INT );
Printf ("Value % d = % d/N", I + 1, value );
}
}
Void arg_type (int cnt ,...)
{
Int arg_type = 0;
Int int_value = 0;
Int I = 0;
Int arg_cnt = CNT;
Char * str_value = NULL;
Va_list arg_ptr;
Va_start (arg_ptr, CNT );
For (I = 0; I <CNT; I ++)
{
Arg_type = va_arg (arg_ptr, INT );
Switch (arg_type)
{
Case int_type:
Int_value = va_arg (arg_ptr, INT );
Printf ("Value % d = % d/N", I + 1, int_value );
Break;
Case str_type:
Str_value = va_arg (arg_ptr, char *);
Printf ("Value % d = % d/N", I + 1, str_value );
Break;
Default:
Break;
}
}
}
The above is my personal opinion. I hope you will correct and express your opinion on this. Thank you very much !!!