C++ 变长参数列表函数的用法

对变长参数的访问是通过下面三个宏实现的:

  1. void va_start(  
  2.    va_list arg_ptr,  
  3.    prev_param   
  4. ); // (ANSI version)   
  5.    
  6. type va_arg(  
  7.    va_list arg_ptr,   
  8.    type   
  9. );   
  10.    
  11. void va_end(  
  12.    va_list arg_ptr   
  13. );   

参数 
type: 待获取参数的数据类型; 
arg_ptr: 指向参数列表的 va_list 类型指针(va_list 是 char* 的别名); 
prev_param: 第一个可选参数(用 "..." 标识的参数属可选参数)之前, 并与之相邻的参数的名称. 在 ANSI 版本的宏中, 该参数是必须的. 
 
头文件 

<stdio.h> 和 <stdarg.h> 
 
说明
 
1. va_start 使 arg_ptr 指向传递给函数可选参数列表中的第一个参数; 
2. va_start 必须在第一次使用 va_arg 前使用; 
3. va_arg 从 arg_ptr 指向的位置获取一个 type 类型的值. 调用结束后, arg_ptr 偏移 sizeof(type) 个字节指向下一个参数的位置. 注意, 在 VS2008withSP1 中, arg_ptr 偏移量大于等于 4. 当 sizeof(type) < 4 时, arg_ptr 偏移 4 个字节; 
4. 取完所有参数后, 调用 va_end 可将 arg_ptr 置为 NULL.

代码

  1. // Build with VS2008withSP1, /W4   
  2. #include <cstdio>   
  3. #include <cstdarg>   
  4.    
  5.    
  6. void foo(char arg, char* arg2, ...)  
  7. {  
  8.     printf_s("sizeof(double)        = %d/r/n"sizeof(double));   
  9.     printf_s("sizeof(unsigned char) = %d/r/n"sizeof(unsigned char));   
  10.     printf_s("sizeof(int)           = %d/r/n"sizeof(int));   
  11.     printf_s("sizeof(short)         = %d/r/n"sizeof(short));   
  12.     printf_s("sizeof(long long)     = %d/r/n"sizeof(long long));   
  13.    
  14.     printf_s("/r/n");   
  15.    
  16.     printf_s("arg  = %c/r/n", arg);   
  17.     printf_s("arg2 = %s/r/n", arg2);   
  18.    
  19.     va_list arg_ptr;                   // !   
  20.     va_start(arg_ptr, arg2);           // !   
  21.                                        // arg_ptr: 0x003ffba0   
  22.    
  23.     double arg3 = va_arg(arg_ptr, double);   
  24.     printf_s("arg3 = %f/r/n", arg3);   // arg_ptr: 0x003ffba8 == 0x003ffba0 + sizeof(double)   
  25.    
  26.     unsigned char arg4 = va_arg(arg_ptr, unsigned char);   
  27.     printf_s("arg4 = %c/r/n", arg4);   // arg_ptr: 0x003ffbac != 0x003ffba8 + sizeof(unsigned char)   
  28.                                        //          0x003ffbac == 0x003ffba8 + 4   
  29.    
  30.     int arg5 = va_arg(arg_ptr, int);   
  31.     printf_s("arg5 = %d/r/n", arg5);   // arg_ptr: 0x003ffbb0 != 0x003ffbac + sizeof(int)   
  32.    
  33.     short arg6 = va_arg(arg_ptr, short);   
  34.     printf_s("arg6 = %hd/r/n", arg6);  // arg_ptr: 0x003ffbb4 != 0x003ffbb0 + sizeof(short)   
  35.                                        //          0x003ffbb4 == 0x003ffbb0 + 4   
  36.    
  37.     long long arg7 = va_arg(arg_ptr, long long);   
  38.     printf_s("arg7 = %lld/r/n", arg7); // arg_ptr: 0x003ffbbc == 0x003ffbb4 + sizeof(long long)   
  39.    
  40.     va_end(arg_ptr);                   // !   
  41.                                        // arg_ptr: 0x00000000   
  42. }  
  43.    
  44.    
  45. int main()  
  46. {  
  47.     foo('A'"ABCDEF", 3.14, 'B', 2147483647, 32767, 9223372036854775807);   
  48.    
  49.     return 0;   
  50. }  

输出

  1. sizeof(double)        = 8  
  2. sizeof(unsigned char) = 1  
  3. sizeof(int)           = 4  
  4. sizeof(short)         = 2  
  5. sizeof(long long)     = 8  
  6.   
  7. arg  = A  
  8. arg2 = ABCDEF  
  9. arg3 = 3.140000  
  10. arg4 = B  
  11. arg5 = 2147483647  
  12. arg6 = 32767  
  13. arg7 = 9223372036854775807  

参考

http://msdn.microsoft.com/zh-cn/library/kb57fad8.aspx

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值