ImageVerifierCode 换一换
格式:DOC , 页数:5 ,大小:34.50KB ,
资源ID:3766203      下载积分:20 文钱
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,省得不是一点点
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.wenke99.com/d-3766203.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: QQ登录   微博登录 

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(可变参数函数说明.doc)为本站会员(11****ws)主动上传,文客久久仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知文客久久(发送邮件至hr@wenke99.com或直接QQ联系客服),我们立即给予删除!

可变参数函数说明.doc

1、前言:本文在很大程度上改编自网友 kevintz 的“C 语言中可变参数的用法”一文,在行文之前先向这位前辈表示真诚的敬意和感谢。 一、什么是可变参数 我们在 C 语言编程中有时会遇到一些参数个数可变的函数,例如 printf()函数,其函数原型为: int printf( const char* format, .); 它除了有一个参数 format 固定以外,后面跟的参数的个数和类型是可变的(用三个点“” 做参数占位符),实际调用时可以有以下的形式: printf( “%d “,i); printf( “%s “,s); printf( “the number is %d ,string

2、is:%s “, i, s); 以上这些东西已为大家所熟悉。但是究竟如何写可变参数的 C 函数以及这些可变参数的函数编译器是如何实现,这个问题却一直困扰了我好久。本文就这个问题进行一些探讨,希望能对大家有些帮助. 二、写一个简单的可变参数的 C 函数 先看例子程序。该函数至少有一个整数参数,其后占位符,表示后面参数的个数不定. 在这个例子里,所有的输入参数必须都是整数,函数的功能只是打印所有参数的值. 函数代码如下: /示例代码 1:可变参数函数的使用 #include “stdio.h “ #include “stdarg.h “ void simple_va_fun(int start,

3、.) va_list arg_ptr; int nArgValue =start; int nArgCout=0; /可变参数的数目 va_start(arg_ptr,start); /以固定参数的地址为起点确定变参的内存起始地址。 do +nArgCout; printf( “the %d th arg: %dn “,nArgCout,nArgValue); /输出各参数的值 nArgValue = va_arg(arg_ptr,int); /得到下一个可变参数的值 while(nArgValue != -1); return; int main(int argc, char* argv)

4、simple_va_fun(100,-1); simple_va_fun(100,200,-1); return 0; 下面解释一下这些代码 从这个函数的实现可以看到,我们使用可变参数应该有以下步骤: 由于在程序中将用到以下这些宏: 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 中,所以用到可变参数的程序应该

5、包含这个头文件. 函数里首先定义一个 va_list 型的变量,这里是 arg_ptr,这个变 量是存储参数地址的指针.因为得到参数的地址之后,再结合参数的类型,才能得到参数的值。 然后用 va_start 宏初始化中定义的变量 arg_ptr,这个宏的第二个参数是可变参数列表的前一个参数,即最后一个固定参数. 然后依次用 va_arg 宏使 arg_ptr 返回可变参数的地址,得到这个地址之后,结合参数的类型,就可以得到参数的值。 设定结束条件,这里的条件就是判断参数值是否为-1。注意被调的函数在调用时是不知道可变参数的正确数目的,程序员必须自己在代码中指明结束条件。至于为什么它不会知道参数

6、的数目,读者在看完这几个宏的内部实现机制后,自然就会明白。(二)可变参数在编译器中的处理 我们知道 va_start,va_arg,va_end 是在 stdarg.h 中被定义成宏的, 由于 1)硬件平台的不同 2)编译器的不同,所以定义的宏也有所不同,下面看一下 VC+6.0 中 stdarg.h 里的代码(文件的路径为 VC 安装目录下的vc98includestdarg.h) typedef char * va_list; #define _INTSIZEOF(n) (sizeof(n) + sizeof(int) - 1) 使 ap 不再 指向堆栈,而是跟 NULL 一样.有些直接定

7、义为(void*)0), 这样编译器不会为 va_end 产生代码,例如 gcc 在 linux 的 x86平台就是这样定义的. 在这里大家要注意一个问题:由于参数的地址用于 va_start 宏,所以参数不能声明为寄存器变量或作为函数或数组类型. 关于 va_start, va_arg, va_end 的描述就是这些了,我们要注意的 是不同的操作系统和硬件平台的定义有些不同,但原理却是相似的. (三)可变参数在编程中要注意的问题 因为 va_start, va_arg, va_end 等定义成宏,所以它显得很愚蠢, 可变参数的类型和个数完全在该函数中由程序代码控制,它并不能智能 地识别不同参

8、数的个数和类型. 有人会问:那么 printf 中不是实现了智能识别参数吗?那是因为函数 printf 是从固定参数 format 字符串来分析出参数的类型,再调用 va_arg 的来获取可变参数的.也就是说,你想实现智能识别可变参数的话是要通过在自己的程序里作判断来实现的. 例如,在 C 的经典教材the c programming language的 7.3 节中就给出了一个 printf 的可能实现方式,由于篇幅原因这里不再叙述。 (四)小结: 1、标准 C 库的中的三个宏的作用只是用来确定可变参数列表中每个参数的内存地址,编译器是不知道参数的实际数目的。 2、在实际应用的代码中,程序员

9、必须自己考虑确定参数数目的办法,如 在固定参数中设标志 printf 函数就是用这个办法。后面也有例子。 在预先设定一个特殊的结束标记,就是说多输入一个可变参数,调用时要将最后一个可变参数的值设置成这个特殊的值,在函数体中根据这个值判断是否达到参数的结尾。本文前面的代码就是采用这个办法. 无论采用哪种办法,程序员都应该在文档中告诉调用者自己的约定。 3、实现可变参数的要点就是想办法取得每个参数的地址,取得地址的办法由以下几个因素决定: 函数栈的生长方向 参数的入栈顺序 CPU 的对齐方式 内存地址的表达方式 结合源代码,我们可以看出 va_list 的实现是由决定的,_INTSIZEOF(n)

10、 的引入则是由决定的,他和又一起决定了 va_start 的实现,最后 va_end 的存在则是良好编程风格的体现,将不再使用的指针设为 NULL,这样可以防止以后的误操作。 4、取得地址后,再结合参数的类型,程序员就可以正确的处理参数了。理解了以上要点,相信稍有经验的读者就可以写出适合于自己机器的实现来。下面就是一个例子用模板可以实现 template T sum(T a, T2 b, .) 可以实现的,吧上边的代码一改 template T t_max(T start,T2 next.) T result = 0; va_list arg_ptr; T nArgValue =start; va_start(arg_ptr,start); /以固定参数的地址为起点确定变参的内存起始地址。 do result += nArgValue; cout (-1); return; 调用时 cout (1, 2, 1, 2, -1); 就可以T t_max(T start,T2 next.) - T t_max(T start,T2 next,.) nArgValue = va_arg(arg_ptr,int); /得到下一个可变参数的值 - nArgValue = static_cast (va_arg(arg_ptr,int); /得到下一个可变参数的值

Copyright © 2018-2021 Wenke99.com All rights reserved

工信部备案号浙ICP备20026746号-2  

公安局备案号:浙公网安备33038302330469号

本站为C2C交文档易平台,即用户上传的文档直接卖给下载用户,本站只是网络服务中间平台,所有原创文档下载所得归上传人所有,若您发现上传作品侵犯了您的权利,请立刻联系网站客服并提供证据,平台将在3个工作日内予以改正。