Variadic list comprehension...

Variable parameters in the C language are an interesting implementation. By implementing functions as variable parameters, the function can accept more than one arbitrary number of parameters (not fixed), such as the printf() function, etc.

The function parameters are pushed onto the stack from right to left, as shown in the following figure from top to bottom;

In the above figure, we want to read the variable part, how to read it?

First, the pointer char * points to the bottom, take the address of num, and cast it to char *, and add the size of the num type, then the pointer points to a, and then cast the pointer to int* and dereference, you can get the value of a content, and so on.

So to use a variable parameter list, the following conditions must be met:

(1) The type of each parameter must be known; it can be known by inputting %d, %c, etc.

(2) There must be a specific and clear parameter;

(3) Explicitly know how many parameters;

Let's look at an example:

Implement a function to find the average of any number of parameters;
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<stdarg.h>
int my_avg(int n, ...) //n represents several numbers
{
	va_list arg; // char * arg
	va_start(arg, n); //Let char * point to the variable part
	//equivalent to arg = (char*)#arg+=sizeof(num);
	int sum = 0;
	int count = n;
	//The next loop means extracting the contents of each variable part
	while (count){
		sum + = va_arg (arg, int);
		//equivalent to *((int *)arg);arg+=sizeof(int)
		count--;
	}
	va_end(arg); //arg = NULL for end
	return sum / n;
}
intmain()
{
	int a = 10;
	int b = 20;
	int c = 30;
	int avg1 = my_avg(2, a, b);
	int avg2 = my_avg(3, a, b, c);
	printf("avg1:%d\navg2:%d\n", avg1, avg2);
	system("pause");
	return 0;
}
  • Declare a variable arg of type va_list (equivalent to char*), which is used to access the undetermined part (variable part) of the parameter list .
  • The arg variable is initialized by calling va_start. Its first parameter is the variable name of va_list, and the second parameter is the last named parameter before the ellipsis . The initialization procedure sets the arg variable to point to the first argument of the variable argument section. Why is the red part? To facilitate direct positioning of variable parts.
  • In order to access the arguments, va_arg is used. This macro accepts two arguments: the va_list variable and the type of the next argument in the argument list. In this example all variadic parameters are integers. va_arg returns the value of this parameter and uses va_arg to point to the next variable parameter .
  • Finally, after accessing the last variable parameter, we need to call va_end.

[Restrictions on variable parameters]

Notice:

  • Variable parameters must be accessed one by one from beginning to end. This is fine if you want to stop halfway after accessing several variadic parameters. However, if you want to access something in the middle of the moisable parameter list in the first place, this is not possible.
  • There is at least one named parameter in the parameter list. You cannot use va_start without even a single named parameter.
  • These macros cannot directly determine the actual number of arguments from the arguments.
  • These macros cannot tell the type of each parameter.
  • If the wrong type is specified in va_arg, the consequences are unpredictable.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324734898&siteId=291194637