Bootstrap

可变参数:va_list(),va_start(),va_arg(),va_end() 详细解析

目录

1、含义:

2、使用:

3、连续打印出自定义格式的文字:


1、含义:

(1)va_list是C语言中的一个宏定义,用于表示一个变长参数列表。它是一个指向变长参数列表的指针,可以通过宏va_startva_argva_end对变长参数列表进行访问和操作。在函数中需要接收不定数量的参数时,可以使用va_list来处理这些参数。

(2)va_start:是一个宏定义,用于在使用可变参数函数时获取可变参数的起始地址。
    它的作用是初始化一个va_list类型的变量,使其指向可变参数列表的第一个参数。
    va_start宏需要两个参数,分别是一个va_list类型的变量和可变参数的最后一个固定参数的地址。

(3)va_arg:是一个宏,用于获取可变参数列表中的下一个参数值;   

va_arg(ap, type)

        其中,ap 是 va_list 类型的可变参数列表指针,type 是要获取的参数的类型。va_arg 宏返回指定类型的参数值,并将可变参数列表指针 ap 向后移动到下一个参数。注意,调用 va_arg 宏之前必须先调用 va_start 宏初始化可变参数列表指针。 

(4)va_end:是一个宏,用于结束使用 va_start 和 va_arg 宏定义的可变参数列表。它的作用是清理 va_list 类型变量,以便该变量可以被再次使用。

2、使用:

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

void print_args(int num_args, ...) 
{
    va_list args;
    int i;

    va_start(args, num_args);  // 初始化args,指向可变参数列表的第一个参数

    for (i = 0; i < num_args; i++) 
    {
        printf("%d ", va_arg(args, int));  // 依次获取可变参数列表中的参数
    }

    va_end(args);  // 结束args的使用
}


int main() 
{
    print_args(3, 1, 2, 3);  // 输出:1 2 3
    return 0;
}

在上述示例中,print_args函数接受一个整数num_args和一个可变参数列表。在函数内部,使用va_list定义一个args变量,并使用va_start初始化args,指向可变参数列表的第一个参数。然后使用va_arg依次获取可变参数列表中的参数,并使用va_end结束args的使用。

3、连续打印出自定义格式的文字:

string format(const char * pFmt, ...)
{
#define FORMAT_MSG_BUFFER_SIZE (2048000)
	char szBuffer[FORMAT_MSG_BUFFER_SIZE + 1] = { 0 };
	va_list args;
	va_start(args, pFmt);
	vsnprintf(szBuffer, FORMAT_MSG_BUFFER_SIZE, pFmt, args);
	va_end(args);

	std::string strRet = szBuffer;
	return strRet;
}

(1)format函数是一个可变参数函数,第一个参数pFmt是一个格式化字符串,后面的参数可以是任意数量的参数,用于填充格式化字符串中的占位符。该函数将格式化字符串和参数组合成一个新的字符串并返回。 

        例如,如果格式化字符串为"Hello, %s! Today is %d/%d/%d.",后面的三个参数分别为"World"、"10"和"2021",那么该函数返回的字符串为"Hello, World! Today is 10/2021."。 

注意:在使用该函数时,需要注意保证格式化字符串和参数的类型和数量匹配,否则可能会导致程序崩溃或输出错误的结果。

(2)vsnprintf 是一个函数,用于将格式化的字符串输出到指定的缓冲区中,其参数列表中包含一个可变参数列表。与 printf 类似,vsnprintf 可以根据格式化字符串中的占位符,将后续参数转换成对应的字符串并输出到缓冲区中,但是与 printf 不同的是,vsnprintf 可以指定输出的最大长度,以避免缓冲区溢出的问题。

;