C/C++可变参数

来源:互联网 发布:java 包命名特殊符合 编辑:程序博客网 时间:2024/04/30 04:13

★函数:

使用VA_LIST宏组解决变参问题

         1、首先定义va_list型的变量,这个变量是指向参数的指针。

         2、然后用va_start宏初始化刚定义的va_list变量,这个宏的第二个参数是“第一个可变参数的前一个参数”
         3、再用va_arg得到可变参数,第二个参数是“可变参数”的类型
         4、最后用va_end宏结束可变参数的获取。如果有多个可变参数,依次调用va_list获取各个参数

[cpp:nogutter] view plaincopy
  1. DWORD CHXVMSystem::RunFuncition( DWORD dwRunMode,           // Run mode.  
  2.   
  3.                                  LPCTSTR lpszFunctionName,  // Function Name  
  4.                                  CVal * pvalResult,         // Return.  
  5.                                  int nTakeParamsCount,      // Count of Params  
  6.                                  ... )                      // Params list  
  7. {  
  8.      // Create Thread...  
  9.   
  10.      CHXVMThread thread = m_pThreadManager->CreateThread( dwRunMode );  
  11.   
  12.      LPVOID pStack = thread.GetStack();  
  13.   
  14.    // Push Params  
  15.   
  16.    va_list params;  
  17.    va_start( params, nTakeParamsCount );  
  18.   
  19.    forint i = 0; i < nTakeParamsCount; ++ i )  
  20.       (( CHXVMStack * ) pStack )->Push( * ( va_arg( params, CVal * )));  
  21.   
  22.    va_end( params );  
  23.     
  24.      (( CHXVMStack * ) pStack )->Push( CVal( nTakeParamsCount ));  
  25.   
  26.    // Call..  
  27.   
  28.      thread.SetEntry( lpszFunctionName );  
  29.      thread.BeiginRun();  
  30.   
  31.      if( dwRunMode & HXVM_RUNMODE_SYNC )  
  32.      {  
  33.           WaitForSingleObject( thread.hThread, -1 );  
  34.   
  35.           if( pvalResult )  
  36.   
  37.                 pvalResult = thread.GetExitCode();  
  38.      }  
  39.   
  40.      return 0;  
  41. }  

 

使用VA_LIST应该注意的问题:

        1、可变参数函数,必须通过某种方式事先预知传入参数的类型。可变参数函数的调用者,必须按照该方式传入对应类型的参数。一旦参数类型不匹配,将可能导致返回错误或无意义的数据,甚至栈被破坏。
        2、编译器对可变参数的函数的原型检查不够严格,不利于写出高质量代码。在非必要情况下,应当尽量采用C++重载、多态等方式实现函数,而尽量不要使用可变参数。

 

★宏

宏也可以带可变参数,如:

#define PRINT( format, ... )   printf( format, ## __VA_ARGS__ );

“##”不可以省略,如果省略,就不可以省略可变参数部分。比如:“PINTF("hello");”,无可变参数部分,解释PRINT宏时就会多出一个“,”号,导致编译出错。

或者可以这样定义:

#define PRINT( format, args... ) printf( format, ##agrs );