天天看点

C++函数参数带省略号

转载出处:C++函数参数中的省略号用法分析

    C++允许定义形参个数和类型不确定的函数。例如,C语言中的标准函数printf便使用这种机制。在声明不确定形参的函数时,形参部分可以使用省略号“…”代替。“…”告诉编译器,在函数调用时不检查形参类型是否与实参类型相同,也不检查参数个数。

例如:void ConnectData(int i,...)

在上面的代码中,编译器只检查第一个参数是否为整型,而不对其他参数进行检查。

对于可变参数的函数,需要进行特殊的处理。首先需要引用 <stdarg.h>头文件,然后利用va_list类型和va_start、va_arg、va_end 3个宏读取传递到函数中的参数值。

这几个宏的定义如下(在 ANSI C 中):

type va_arg( va_list arg_ptr, type );void va_end( va_list arg_ptr );void va_start(

说明如下:

【 va_start函数将参数arg_ptr设置为可变参数列表的第一个参数。参数arg_ptr的类型必须为va_list。参数prev_param是在可变参数列表之前的那一个参数。(也就是说在 ANSI C 中,如果一个函数有可变参数,那么在该可变参数前必须有一个明确定义的参数,否则无法调用函数 va_start ,例如函数 int add(int i,...)是合法的,而函数 int add(...)是不合法的。)】

【 va_arg函数将返回 arg_ptr 所指位置的值,并将 arg_ptr 指向下一个参数 】

【va_end函数将创建的指针置为无效】

两种代码示例:

第一种,如果需要调用va_arg来获取实参个数的话,则必须要在调用函数的时候在参数末尾传递一个表示结束的标志实参:

type va_arg( va_list arg_ptr, type );void va_end( va_list arg_ptr );void va_start(

#include <afx.h>
#include<cstdarg>
#include<iostream>
#include<string>
using namespace std;
CString add(CString args, ...)
{
	va_list arg_ptr;
	CString nArgValue;
	CString str = "";
	str+=args;
	va_start(arg_ptr,args);
	do 
	{
		nArgValue=va_arg(arg_ptr, CString);
		str+=nArgValue;
	} while (nArgValue!="");
	//自定义结束条件是输入参数为""
	va_end(arg_ptr);
	return str;
}
int main()
{
	CString a = "Aaa";
	cout<<add(a,a,a,a,"")<<endl;
	return 0;
}
           

第二种,不使用va_arg函数,这种方法不需要在末尾传递结束标志,但同时也不确定实参的类型和个数:

#include <afx.h>
#include<cstdarg>
#include<iostream>
#include<string>
using namespace std;
CString add(CString args, ...)
{
	va_list arg_ptr;
	int ret = 0;
	char m_str[MAX_PATH]={0};
	va_start(arg_ptr,args);
	ret= vsnprintf_s(m_str, MAX_PATH, args, arg_ptr);
	va_end(arg_ptr);
	m_str[ret]='\0';
	return m_str;
}
int _tmain(int argc, _TCHAR* argv[])
{
	CString a = "Aaa";
	cout<<add("%s,%s,%d",a,a,1)<<endl;
	return 0;
}
           

继续阅读