C++中可变参数的函数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++中可变参数的函数相关的知识,希望对你有一定的参考价值。

#include<iostream>
#include<STDARG.H>
using namespace std;
void OutputInfo(int num,...) //¶¨ÒåÒ»¸öÊ¡ÂԺŵIJÎÊý

va_list arguments; //¶¨Òåva_listÀàÐͱäÁ¿
va_start(arguments,num);
while(num--) //¶ÁÈ¡ËùÓвÎÊýµÄÊý¾Ý

char* pchDate=va_arg(arguments,char*); //»ñÈ¡×Ö·û´®Êý¾Ý
int iDate=va_arg(arguments,int); //»ñÈ¡ÕûÐÍÊý¾Ý
cout<<pchDate<<endl; //Êä³ö×Ö·û´®
cout<<iDate<<endl; //Êä³öÕûÊý

va_end(arguments);

void main()

OutputInfo(2,"Beijing",2008,"Olympic Games",2008); //µ÷ÓÃOututInfoº¯Êý

书上就着一个例子,有没有更简明的 ?不是很理解啊

参考技术A // crt_va.c
/* The program below illustrates passing a variable
* number of arguments using the following macros:
* va_start va_arg va_end
* va_list va_dcl (UNIX only)
*/

#include <stdio.h>
#define ANSI /* Comment out for UNIX version */
#ifdef ANSI /* ANSI compatible version */
#include <stdarg.h>
int average( int first, ... );
#else /* UNIX compatible version */
#include <varargs.h>
int average( va_list );
#endif

int main( void )

/* Call with 3 integers (-1 is used as terminator). */
printf( "Average is: %d\n", average( 2, 3, 4, -1 ) );

/* Call with 4 integers. */
printf( "Average is: %d\n", average( 5, 7, 9, 11, -1 ) );

/* Call with just -1 terminator. */
printf( "Average is: %d\n", average( -1 ) );


/* Returns the average of a variable list of integers. */
#ifdef ANSI /* ANSI compatible version */
int average( int first, ... )

int count = 0, sum = 0, i = first;
va_list marker;

va_start( marker, first ); /* Initialize variable arguments. */
while( i != -1 )

sum += i;
count++;
i = va_arg( marker, int);

va_end( marker ); /* Reset variable arguments. */
return( sum ? (sum / count) : 0 );

#else /* UNIX compatible version must use old-style definition. */
int average( va_alist )
va_dcl

int i, count, sum;
va_list marker;

va_start( marker ); /* Initialize variable arguments. */
for( sum = count = 0; (i = va_arg( marker, int)) != -1; count++ )
sum += i;
va_end( marker ); /* Reset variable arguments. */
return( sum ? (sum / count) : 0 );

#endif
参考技术B 这东西基本上没什么用处了。
va_list arguments;
va_start
你去查api去吧。能找到这俩函数的定义!本回答被提问者采纳

访问冲突 可变参数宏/函数 C++

【中文标题】访问冲突 可变参数宏/函数 C++【英文标题】:Access violation Variadic macro/function C++ 【发布时间】:2013-06-03 23:40:15 【问题描述】:

我正在尝试使用一些最终以 printf 调用结束的可变参数宏和函数为我的项目创建一个日志记录系统。但是 printf 给了我一个访问冲突错误,我不知道为什么。

让我们从我的宏开始吧:

#ifdef _DEBUG
#define LogError(fmt, ...) Logger::Log(LOG_ERROR,fmt,__VA_ARGS__);
#define LogTrace(fmt, ...) Logger::Log(LOG_TRACE,fmt,__VA_ARGS__);
#define LogWarn(fmt, ...) Logger::Log(LOG_WARN,fmt,__VA_ARGS__);
#else
#define LogError(fmt, ...)   
#define LogTrace(fmt, ...)   
#define LogWarn(fmt, ...)  
#endif

如您所见,如果定义了 _DEBUG,宏将解析为对 Logger::Log 的调用,并传递所有参数。

这是我的 Logger::Log 函数:

void Logger::Log(LogType type, char* fmt, ...) 
     va_list args;
    va_start (args, fmt);
    std::string preFix = "";
    if (type==LOG_ERROR) preFix = "Error: ";
    else if (type==LOG_WARN) preFix = "Warn: ";
    else if (type==LOG_TRACE) preFix = "Trace: ";
    else preFix = "Unknown: ";

    printf(preFix.append(fmt).c_str(), args);
    va_end(args);

它确实会根据日志的类型为格式字符串添加一个字符串前缀,然后将可变数量的参数传递给 printf,然后发生访问冲突。

这是使用导致程序崩溃的宏的实现。

LogTrace("Adding file to asset file. Asset name: %s, File: %s", fName.c_str(), assetName.c_str());

根据宏:这应该解析为:

Logger:Log(LOG_WARN,"Adding file to asset file. Asset name: %s, File: %s", <string1>, <string2>);

应该在Log 函数中传递给 printf。使用断点,我看到格式字符串被正确传递和前缀,但我似乎无法调试看到可变数量的参数被正确传递给 Log 函数。

我是否正确地将可变数量的参数传递给宏、函数和 printf? 如果看起来我已经正确完成了所有操作,我该如何调试以查看变量参数是如何传递的? 任何帮助将不胜感激。

【问题讨论】:

【参考方案1】:

我在发布问题后立即发现了问题... printf 应该是 vprintf 以使可变数量的参数正常工作。

【讨论】:

以上是关于C++中可变参数的函数的主要内容,如果未能解决你的问题,请参考以下文章

C++可变参数使用总结

在 C++ 中的可变长度函数中放置默认值参数的位置?

C++:具有可变参数的 Hacky 参数模式

C++可变参数的另一种实现

Python C++ API - 具有可变数量参数的重载函数

编译器跳过 C++ 中的可变参数模板/函数 [关闭]