var_start,var_arg,var_end相关总结.docxVIP

  1. 1、本文档共4页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  5. 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  6. 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  7. 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  8. 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
var_start,var_arg,var_end相关总结

(一)一个可变参数函数的例子 下面我们来探讨如何写一个简单的可变参数的C函数。写可变参数的?C函数要在程序中用到以下这些宏: void?va_start(?va_list?arg_ptr,?prev_param?); type?va_arg(?va_list?arg_ptr,?type?);? void?va_end(?va_list?arg_ptr?);? va在这里是variable-argument(可变参数)的意思。? 这些宏定义在stdarg.h中,所以用到可变参数的程序应该包含这个?头文件。下面我们写一个简单的可变参数的函数,改函数至少有一个整数?参数,第二个参数也是整数,是可选的.函数只是打印这两个参数的值.。 void?simple_va_fun(int?i,?...)? { va_list?arg_ptr;? int?j=0;? va_start(arg_ptr,?i);? j=va_arg(arg_ptr,?int);? va_end(arg_ptr);? printf(%d?%d\n,?i,?j);? return;? }? 我们可以在我们的头文件中这样声明我们的函数: extern?void?simple_va_fun(int?i,?...);? 我们在程序中可以这样调用: simple_va_fun(100);? simple_va_fun(100,200);? 从这个函数的实现可以看到,我们使用可变参数应该有以下步骤: 1)首先在函数里定义一个va_list型的变量,这里是arg_ptr,这个变?量是指向参数的指针; 2)然后用va_start宏初始化变量arg_ptr,这个宏的第二个参数是第?一个可变参数的前一个参数,是一个固定的参数.; 3)然后用va_arg返回可变的参数,并赋值给整数j.?va_arg的第二个?参数是你要返回的参数的类型,这里是int型; 4)最后用va_end宏结束可变参数的获取.然后你就可以在函数里使?用第二个参数了。如果函数有多个可变参数的,依次调用va_arg获?取各个参数。 ? 如果我们用下面三种方法调用的话,都是合法的,但结果却不一样: 1)???????simple_va_fun(100);? 结果是:100?-123456789(会变的值)? 2)???????simple_va_fun(100,200);? 结果是:100?200? 3)???????simple_va_fun(100,200,300);? 结果是:100?200? 我们看到第一种调用有错误,第二种调用正确,第三种调用尽管结果?正确,但和我们函数最初的设计有冲突。下面一节我们探讨出现这些结果的原因和可变参数在编译器中是如何处理的.。 ? (二)可变参数在编译器中的处理? 我们知道va_start,va_arg,va_end是在stdarg.h中被定义成宏的,由于 1)硬件平台的不同? 2)编译器的不同,所以定义的宏也有所不同,下?面以VC++中stdarg.h里x86平台的宏定义摘录如下(\号表示折行): typedef?char?*?va_list;? #define?_INTSIZEOF(n)?\? ((sizeof(n)+sizeof(int)-1)~(sizeof(int)?-?1)?)? #define?va_start(ap,v)?(?ap?=?(va_list)v?+?_INTSIZEOF(v)?)? #define?va_arg(ap,t)?\? (?*(t?*)((ap?+=?_INTSIZEOF(t))?-?_INTSIZEOF(t))?)? #define?va_end(ap)?(?ap?=?(va_list)0?)? ? 定义_INTSIZEOF(n)主要是为了某些需要内存的对齐的系统。C语言的函?数是从右向左压入堆栈的,图(1)是函数的参数在堆栈中的分布位置。我?们看到va_list被定义成char*,有一些平台或操作系统定义为void*。再看va_start的定义,定义为v+_INTSIZEOF(v),而v是固定参数在堆栈的地址,所以我们运行va_start(ap,?v)以后,ap指向第一个可变参数在堆栈的地址,如图: 高地址|-----------------------------|? |函数返回地址?|? |-----------------------------|? |.......?|? |-----------------------------|? |第n个参数(第一个可变参数)?|? |-----------------------------|--va_start后ap指向? |第n-1个参数(最后一个固定参数)|? 低地址|---------

文档评论(0)

yan698698 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档