C++可变参数表基本内容探讨

C++编程语言可以被看做C语言的一个升级版本。既然是基于C语言的一个编程语言,当然具有C语言中的所有功能。那么还有那些不同之处呢?其中就有一个不同于其它语言的特性,即其支持C++可变参数表,典型的函数如printf、scanf等可以接受数量不定的参数。如:

成都创新互联公司是一家专业提供头屯河企业网站建设,专注与网站设计制作、成都网站建设、H5技术、小程序制作等业务。10年已为头屯河众多企业、政府机构等服务。创新互联专业的建站公司优惠进行中。

 
 
 
  1. printf ( "I love you" );   
  2. printf ( "%d", a );  
  3. printf ( "%d,%d", a, b );  

第一、二、三个printf分别接受1、2、3个参数,让我们看看printf函数的原型:

 
 
 
  1. int printf ( const char *format, ... );  

从函数原型可以看出,其除了接收一个固定的参数format以外,后面的参数用"…"表示。在C/C++语言中,"…"表示可以接受不定数量的参数,理论上来讲,可以是0或0以上的n个参数。

本文将对C++可变参数表的使用方法及C/C++支持可变参数表的深层机理进行探索。

C++可变参数表的用法

1、相关宏

标准C/C++包含头文件stdarg.h,该头文件中定义了如下三个宏:

 
 
 
  1. void va_start ( va_list arg_ptr, prev_param ); /* ANSI version */  
  2. type va_arg ( va_list arg_ptr, type );   
  3. void va_end ( va_list arg_ptr );  

在这些宏中,va就是variable argument(可变参数)的意思;arg_ptr是指向可变参数表的指针;prev_param则指可变参数表的前一个固定参数;type为可变参数的类型。va_list也是一个宏,其定义为typedef char * va_list,实质上是一char型指针。char型指针的特点是++、--操作对其作用的结果是增1和减1(因为sizeof(char)为1),与之不同的是int等其它类型指针的++、--操作对其作用的结果是增sizeof(type)或减sizeof(type),而且sizeof(type)大于1。

通过va_start宏我们可以取得C++可变参数表的首指针,这个宏的定义为:

 
 
 
  1. #define va_start ( ap, v ) ( ap = (va_list)&v + _INTSIZEOF(v) )  

显而易见,其含义为将最后那个固定参数的地址加上可变参数对其的偏移后赋值给ap,这样ap就是可变参数表的首地址。其中的_INTSIZEOF宏定义为:

 
 
 
  1. #define _INTSIZEOF(n) ((sizeof ( n ) + sizeof ( int ) - 1 )
     & ~( sizeof( int ) - 1 ) )  

va_arg宏的意思则指取出当前arg_ptr所指的可变参数并将ap指针指向下一可变参数,其原型为:

 
 
 
  1. #define va_arg(list, mode) ((mode *)(list =\  
  2. (char *) ((((int)list + (__builtin_alignof(mode)<=4?3:7)) &\  
  3. (__builtin_alignof(mode)<=4?-4:-8))+sizeof(mode))))[-1]  

 

对这个宏的具体含义我们将在后面深入讨论。

而va_end宏被用来结束C++可变参数表的获取,其定义为:

 
 
 
  1. #define va_end ( list )  

可以看出,va_end ( list )实际上被定义为空,没有任何真实对应的代码,用于代码对称,与va_start对应;另外,它还可能发挥代码的"自注释"作用。所谓代码的"自注释",指的是代码能自己注释自己。

下面我们以具体的例子来说明以上三个宏的使用方法。

2、一个简单的例子

 
 
 
  1. #include  
  2. /* 函数名:max  
  3. * 功能:返回n个整数中的最大值  
  4. * 参数:num:整数的个数 ...:num个输入的整数  
  5. * 返回值:求得的最大整数  
  6. */  
  7. int max ( int num, ... )  
  8. {  
  9. int m = -0x7FFFFFFF; /* 32系统中最小的整数 */  
  10. va_list ap;  
  11. va_start ( ap, num );  
  12. for ( int i= 0; i< num; i++ )  
  13. {  
  14. int t = va_arg (ap, int);  
  15. if ( t > m )  
  16. {  
  17. m = t;  
  18. }  
  19. }  
  20. va_end (ap);  
  21. return m;  
  22. }   
  23. /* 主函数调用max */  
  24. int main ( int argc, char* argv[] )  
  25. {   
  26. int n = max ( 5, 5, 6 ,3 ,8 ,5); /* 求5个整数中的最大值 */  
  27. cout << n;  
  28. return 0;  
  29. }  

 

函数max中首先定义了C++可变参数表指针ap,而后通过va_start ( ap, num )取得了参数表首地址(赋给了ap),其后的for循环则用来遍历可变参数表。这种遍历方式与我们在数据结构教材中经常看到的遍历方式是类似的。#t#

函数max看起来简洁明了,但是实际上printf的实现却远比这复杂。max函数之所以看起来简单,是因为:

(1) max函数可变参数表的长度是已知的,通过num参数传入;

(2) max函数可变参数表中参数的类型是已知的,都为int型。

而printf函数则没有这么幸运。首先,printf函数可变参数的个数不能轻易的得到,而可变参数的类型也不是固定的,需由格式字符串进行识别(由%f、%d、%s等确定),因此则涉及到C++可变参数表的更复杂应用。

分享名称:C++可变参数表基本内容探讨
分享链接:http://www.shufengxianlan.com/qtweb/news43/278943.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联