printf实现机制与可变长参数_第1页
printf实现机制与可变长参数_第2页
printf实现机制与可变长参数_第3页
printf实现机制与可变长参数_第4页
printf实现机制与可变长参数_第5页
已阅读5页,还剩20页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、无忧PPT整理发布printf()函数实现机制printf()函数调用的一般格式: printf(, );一般字符格式化规定字符可有可无printf()函数调用的一般格式: printf(, );可变参数列表可变参数列表printf实例1:#includeint main()printf(“Hello World!n”);return 0;传递一个参数!printf实例2:#includeint main()int i=3;printf(“%dn”,i);return 0;传递了两个参数!printf实例3:#includeint main()int i=3;printf(“%d %d %d

2、%dn”);return 0;printf实例4:#includeint main()int i=3,j=4;printf(“%dn”,i,j);return 0;问题:1.怎样让printf()函数知道传递了多少参数?2.printf()函数怎样访问这些参数?首先来看看函数的内存布局n函数参数内存位置n函数局部变量内存位置n函数内部malloc出的空间的位置printf()在在VC6.0中的库中的源代码:中的库中的源代码:int _cdecl printf ( const char *format, . ) va_list ap; int buffing; int retval; va_st

3、art(ap, format); _ASSERTE(format != NULL); _lock_str2(1, stdout); buffing =_stbuf(stdout); retval = _output(stdout,format,ap); _ftbuf(buffing, stdout); _unlock_str2(1, stdout); return(retval); int _cdecl printf ( const char *format, . ) _cdecl是是C和和C程序的缺省调用方式程序的缺省调用方式_cdecl调用约定:调用约定:1.参数从右到左依次入栈参数从右到

4、左依次入栈2.调用者负责清理堆栈调用者负责清理堆栈3.参数的数量类型不会导致编译阶段的错误参数的数量类型不会导致编译阶段的错误 (const char *format, .) 在形参列表里有这么一个在形参列表里有这么一个“.”,这个是可变这个是可变形参的一种写法。形参的一种写法。当传递参数的个数不确定时,就可以用这种方当传递参数的个数不确定时,就可以用这种方式来表示。式来表示。 以下为以下为VC+中中stdarg.h里里x86平台的宏定义平台的宏定义typedef char * va_list;#define va_start(va_list ap, format) ( ap = (va_li

5、st)& format+ _INTSIZEOF(format) ) /C Primer Plus Chapter 15 bit operation#define va_arg(va_list ap,type) ( *(type*)(ap += _INTSIZEOF(type)- _INTSIZEOF(type) )#define va_end(va_list ap) ( ap = (va_list)0 )va_start:为获取可变数目参数的函数的参数提供一种便捷手段。设置ap为指向传给函数参数列表中的第一个可选参数的指针,且该参数必须是va_list类型。format是在参数列表中第一个可选

6、参数前的必选参数。va_arg:返回由ap所指向的参数的值,且自增指向下一个参数的地址。type为当前参数的类型,用来计算该参数的长度,确定下一个参数的起始位置。它可以在函数中应用多次,直到得到函数的所有参数为止,但必须在宏va_start后面调用。va_end:在获取所有的参数后,设置指针ap为null。 栈示意图栈示意图参数参数n参数参数n-1Printf(参数参数1,参数,参数2,参数,参数n-1,参数,参数n,)参数参数2参数参数1低地址低地址高地址高地址Format指向参数指向参数1执行完执行完va_start后,后,ap指向指向参数参数2(即第一个可变参量)(即第一个可变参量)执行

7、完执行完va_arg后,后,ap指向下一个参数指向下一个参数printf()在在VC6.0中的库中的源代码:中的库中的源代码:int _cdecl printf ( const char *format, . ) va_list ap; int buffing; int retval; va_start(ap, format); _ASSERTE(format != NULL); _lock_str2(1, stdout); buffing =_stbuf(stdout); retval = _output(stdout,format,ap); _ftbuf(buffing, stdout);

8、 _unlock_str2(1, stdout); return(retval); retval = _output(stdout,format,ap); _output(stdout,format,ap)在在VC中,中,_output的定义相当复杂,光是变量的定义相当复杂,光是变量声明就有声明就有20多行,主体是一个大的循环体。多行,主体是一个大的循环体。 _output(stdout,format,ap)功能简化:功能简化:(伪代码)(伪代码)int _output(stdout,format,ap)char ch;while(ch = *format+) != _T(0) & chars

9、out = 0)if(ch!=%) 将将ch写入到文件写入到文件stdout中;中;continue;switch(*format):case c:将将ap所指向的内容以字符形式写入文件所指向的内容以字符形式写入文件stdout;ap指向下一个参数指向下一个参数;format+;break;case d:;format+;break;case f:;format+;break;return ;printf()在在VC6.0中的库中的源代码:中的库中的源代码:int _cdecl printf ( const char *format, . ) va_list ap; int buffing;

10、int retval; va_start(ap, format); _ASSERTE(format != NULL); _lock_str2(1, stdout); buffing =_stbuf(stdout); retval = _output(stdout,format,ap); _ftbuf(buffing, stdout); _unlock_str2(1, stdout); return(retval); 最后把文件内容输出到最后把文件内容输出到终端,是函数终端,是函数_ftbuf做的做的_ftbuf(buffing, stdout);printf()基本实现原理基本实现原理1.先声

11、明两个变量,一个是先声明两个变量,一个是“变参类型变参类型”,一,一个是整型(记录字符个数,留待返回)。个是整型(记录字符个数,留待返回)。2.根据固定参数确定变参起始位置根据固定参数确定变参起始位置3.调用其它函数,根据格式化串和变参起始位调用其它函数,根据格式化串和变参起始位置不断循环输出字符置不断循环输出字符(此过程将利用到此过程将利用到va_arg确定后面每个变参位置确定后面每个变参位置),直到参数栈底,直到参数栈底4.令令“变参类型变参类型”指向指向NULL,并返回字符个数并返回字符个数自己编写一个自己编写一个printf函数函数#include #include void myprintf(const char *format, .)va_list ap;char ch;va_start(ap, format);while(ch = *format+)if(ch!=?)putchar(ch);continue;switch(*format)case c:char ch1 = va_arg(ap, char);putchar(ch1);format+;break;自己编写一个自己编写一个printf函数函数case s:char *p = va_arg(a

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论