﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-JUST DO IT-随笔分类-C/C++</title><link>http://www.cppblog.com/xmoss/category/11260.html</link><description>我之所以在这里，只是因为我想要在这里</description><language>zh-cn</language><lastBuildDate>Mon, 20 Jul 2009 17:12:36 GMT</lastBuildDate><pubDate>Mon, 20 Jul 2009 17:12:36 GMT</pubDate><ttl>60</ttl><item><title>va_list 详解</title><link>http://www.cppblog.com/xmoss/archive/2009/07/20/90680.html</link><dc:creator>xmoss</dc:creator><author>xmoss</author><pubDate>Mon, 20 Jul 2009 15:44:00 GMT</pubDate><guid>http://www.cppblog.com/xmoss/archive/2009/07/20/90680.html</guid><wfw:comment>http://www.cppblog.com/xmoss/comments/90680.html</wfw:comment><comments>http://www.cppblog.com/xmoss/archive/2009/07/20/90680.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/xmoss/comments/commentRss/90680.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xmoss/services/trackbacks/90680.html</trackback:ping><description><![CDATA[<p>VA_LIST 是在C语言中解决变参问题的一组宏</p>
<p>他有这么几个成员：</p>
<p>1） va_list型变量：</p>
<p>#ifdef&nbsp; _M_ALPHA<br>typedef struct {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char *a0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* pointer to first homed integer argument */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int offset;&nbsp;&nbsp;&nbsp;&nbsp; /* byte offset of next parameter */<br>} va_list;<br>#else<br>typedef char *&nbsp; va_list;<br>#endif</p>
<p>2）_INTSIZEOF 宏，获取类型占用的空间长度，最小占用长度为int的整数倍：</p>
<p>#define _INTSIZEOF(n)&nbsp;&nbsp; ( (sizeof(n) + sizeof(int) - 1) &amp; ~(sizeof(int) - 1) )</p>
<p>3）VA_START宏，获取可变参数列表的第一个参数的地址（ap是类型为va_list的指针，v是可变参数最左边的参数）：</p>
<p>#define va_start(ap,v)&nbsp; ( ap = (va_list)&amp;v + _INTSIZEOF(v) )</p>
<p>4）VA_ARG宏，获取可变参数的当前参数，返回指定类型并将指针指向下一参数（t参数描述了当前参数的类型）：</p>
<p>#define va_arg(ap,t)&nbsp;&nbsp;&nbsp; ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )</p>
<p>5）VA_END宏，清空va_list可变参数列表：</p>
<p>#define va_end(ap)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ( ap = (va_list)0 )</p>
<p>VA_LIST的用法：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; （1）首先在函数里定义一具VA_LIST型的变量，这个变量是指向参数的指针；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; （2）然后用VA_START宏初始化变量刚定义的VA_LIST变量；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; （3）然后用VA_ARG返回可变的参数，VA_ARG的第二个参数是你要返回的参数的类型（如果函数有多个可变参数的，依次调用VA_ARG获取各个参数）；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; （4）最后用VA_END宏结束可变参数的获取。<br>使用VA_LIST应该注意的问题：<br>&nbsp;&nbsp; （1）可变参数的类型和个数完全由程序代码控制,它并不能智能地识别不同参数的个数和类型；<br>&nbsp;&nbsp; （2）如果我们不需要一一详解每个参数，只需要将可变列表拷贝至某个缓冲，可用vsprintf函数；<br>&nbsp;&nbsp; （3）因为编译器对可变参数的函数的原型检查不够严格,对编程查错不利.不利于我们写出高质量的代码；</p>
<p>小结：可变参数的函数原理其实很简单，而VA系列是以宏定义来定义的，实现跟堆栈相关。我们写一个可变参数的C函数时，有利也有弊,所 以在不必要的场合，我们无需用到可变参数，如果在C++里，我们应该利用C++多态性来实现可变参数的功能，尽量避免用C语言的方式来实现。<br>本文参考：<a href="http://hi.baidu.com/kang_liang/blog/item/168c9059a9a1ca2d2934f05f.html">http://hi.baidu.com/kang_liang/blog/item/168c9059a9a1ca2d2934f05f.html</a></p>
<img src ="http://www.cppblog.com/xmoss/aggbug/90680.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xmoss/" target="_blank">xmoss</a> 2009-07-20 23:44 <a href="http://www.cppblog.com/xmoss/archive/2009/07/20/90680.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>