【C++の相关概念】<stdarg.h>

<stdarg.h>主要用于参数个数未知(即参数个数可变)时获取函数中的参数。

va_list类型
typedef char *va_list;
_INTSIZEOF(n)变量
#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
//保证字节数为int的整数倍

va_start宏,获取可变参数列表的第一个参数的地址(list是类型为va_list的指针,param1是可变参数最左边的参数):
#define va_start(list,param1) ( list = (va_list)&param1+ _INTSIZEOF(param1) )

void test(char *para1,char *param2,char *param3, char *param4)
{
    
    	//此时test函数的栈空间布局:
	//由高处往低处生长
      va_list list;
      ......
      va_start(list,param1);
      ......
      return;
}
//栈空间的整体布局与list指针指向如下

在这里插入图片描述

va_arg宏,获取可变参数的当前参数,返回指定类型并将指针指向下一参数(mode参数描述了当前参数的类型):
#define va_arg(list,mode) ( (mode *) ( list += _INTSIZEOF(mode) ) )[-1]

va_end宏,清空va_list可变参数列表:
#define va_end(list) ( list = (va_list)0 )

#include <stdio.h>
#include <stdarg.h>

void var_test(const char *format, ...)
{
    
    
    va_list list;
    va_start(list,format);
    
    char *ch;
    while(1)
    {
    
    
         ch = va_arg(list, char *);

         if(strcmp(ch,"") == 0)
         {
    
        
               printf("\n");
               break;
         }
         printf("%s ",ch);
     }
     va_end(list);
}

int main()
{
    
    
    var_test("test","this","is","a","test","");
    return 0;
}

在这里插入图片描述
与va相关的打印函数

int vprintf(const char *format, va_list ap);
int vfprintf(FILE *stream, const char *format, va_list ap);
int vdprintf(int fd, const char *format, va_list ap);
int vsprintf(char *str, const char *format, va_list ap);
int vsnprintf(char *str, size_t size, const char *format, va_list 
#include <stdio.h>
#include <stdarg.h>

char buf[1024];
void var_test(const char *format, ...)
{
    
    
	va_list list;
	va_start(list, format);
	int len;

	len =  vsprintf_s(buf, format, list);
	va_end(list);
}

int main()
{
    
    
	var_test("%s %s %d %s","this", "is", 1, "test");
	cout << buf << endl;
	return 0;
}

在这里插入图片描述
参数个数未知的函数define

//最简单的定义
#define my_print1(...) printf(__VA_ARGS__)
//搭配va_list的format使用
#define my_print2(format, ...) printf(format, __VA_ARGS__)
//##:若可变参数的个数为0时
//这里printf参数列表中的的##会把前面多余的","去掉
//否则会编译出错,建议使用后面这种,使得程序更加健壮。
#define my_print3(format, ...) printf(format, ##__VA_ARGS__)

猜你喜欢

转载自blog.csdn.net/weixin_45005811/article/details/114783451