带三点省略号的参数调用

本文探讨了C++中的不定参数函数,如`catch(...)`和`printf()`,并介绍了`arg_list`模板类来处理不定参数。通过示例展示了如何使用`va_list`进行参数恢复和计算平均值。同时,提到了在Windows API中`__cdecl`和`__stdcall`调用约定的区别,以及在实际应用中的安全注意事项,如防止缓冲区溢出。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

常见的有catch(...)和  int   printf(const   char*,...);前者容易理解,省略号代表其他所有情况,后者吗..?
其实本质上应该都是 不定参数函数.它的调用方式是_cedel,也就是说由被调用都恢复堆栈。原理如下:
template   <class   FT,class   MT=FT>  
  class   arg_list{  
  public:  
  arg_list(FT   &ft):_ft(&ft),_count(0){va_start(_val,*_ft);}  
  MT   next(){_count++;return   va_arg(_val,MT);}  
  void   end(){va_end(_val);}  
  int   count(){return   _count;}  
  private:  
  FT*   _ft;  
  va_list   _val;  
  int   _count;  
  };  
  int   average(int   p,...){  
  int   sum=0,int   i=p,count=0;  
  arg_list<int>   arg(p);  
  while(i!=END_ARG)  
  sum+=i,i=arg.next();  
  arg.end();  
  return   sum/arg.count();  
  }   
  应用实例:
void Msg(TCHAR *szFormat, ...);
void Msg(TCHAR *szFormat, ...)
{
    TCHAR szBuffer[1024];  // Large buffer for long filenames or URLs
    const size_t NUMCHARS = sizeof(szBuffer) / sizeof(szBuffer[0]);
    const int LASTCHAR = NUMCHARS - 1;

    // Format the input string
    va_list pArgs;
    va_start(pArgs, szFormat);

    // Use a bounded buffer size to prevent buffer overruns.  Limit count to
    // character size minus one to allow for a NULL terminating character.
    _vsntprintf(szBuffer, NUMCHARS - 1, szFormat, pArgs);
    va_end(pArgs);

    // Ensure that the formatted string is NULL-terminated
    szBuffer[LASTCHAR] = TEXT('/0');

    MessageBox(NULL, szBuffer, TEXT("PlayCap Message"), MB_OK | MB_ICONERROR);
}
引申(摘自http://seraph-zhang.spaces.live.com/blog/cns!9f6aca94097e3f05!1220.entry):
__cdecl是C/C++语言所采用缺省调用规范,__stdcall是WINAPI采用的缺省调用规范,其区别在于__cdecl是由调用函数一方负责维护函数参数堆栈而__stdcall是由被调用一方维护函数参数堆栈,从assembly代码的角度考虑__cdecl调用规范最后返回时的RET指令并没有参数而__stdcall规范返回时RET指令必然带有指示函数返回时需要从堆栈中弹出多少个函数参变量这样一个参数,因为__stdcall由被调用一方负责维护堆栈那么也只有在RET之前退栈而不是RET之后,同时__cdecl和__stdcall在函数参数压栈的时候都是采用由右至左的顺序的。这样就引出几个特殊的问题,例如在C/C++中对于Main函数只能采用__cdecl这种调用规约;__cedel可用于参数个数发生变化的函数而__stdcall只能用于函数参数个数不变的情况等等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值