没有合适的资源?快使用搜索试试~ 我知道了~
C语言的可变参数表函数的设计.doc-综合文档
需积分: 6 1 下载量 195 浏览量
2021-05-22
05:32:23
上传
评论
收藏 269KB DOC 举报
温馨提示
试读
8页
C语言的可变参数表函数的设计.doc
资源推荐
资源详情
资源评论
首先在介绍可变参数表函数的设计之前,我们先来介绍一下最经典的可变参数表 printf 函数的实现原理。
一、printf 函数的实现原理
在 C/C++中,对函数参数的扫描是从后向前的。C/C++的函数参数是通过压入堆栈的方式来给函数传参
数的(堆栈是一种先进后出的数据结构),最先压入的参数最后出来,在计算机的内存中,数据有 2 块,
一块是堆,一块是栈(函数参数及局部变量在这里),而栈是从内存的高地址向低地址生长的,控制生长
的就是堆栈指针了,最先压入的参数是在最上面,就是说在所有参数的最后面,最后压入的参数在最下面 ,
结构上看起来是第一个,所以最后压入的参数总是能够被函数找到,因为它就在堆栈指针的上方。 printf
的第一个被找到的参数就是那个字符指针,就是被双引号括起来的那一部分,函数通过判断字符串里控制
参数的个数来判断参数个数及数据类型,通过这些就可算出数据需要的堆栈指针的偏移量了,下面给出
printf("%d,%d",a,b);(其中 a、b 都是 int 型的)的汇编代码
.section
.data
string out = "%d,%d"
push b
push a
push $out
call printf
你会看到,参数是最后的先压入栈中,最先的后压入栈中,参数控制的那个字符串常量是最后被压入的,
所以这个常量总是能被找到的。
二、可变参数表函数的设计
标准库提供的一些参数的数目可以有变化的函数。例如我们很熟悉的 printf,它需要有一个格式串,
还应根据需要为它提供任意多个“其他参数”。这种函数被称作“具有变长度参数表的函数”,或简称为“变参
数函数”。我们写程序中有时也可能需要定义这种函数。要定义这类函数,就必须使用标准头文件
<stdarg.h>,使用该文件提供的一套机制,并需要按照规定的定义方式工作。本节介绍这个头文件提供
的有关功能,它们的意义和使用,并用例子说明这类函数的定义方法。
C 中变长实参头文件 stdarg.h 提供了一个数据类型 va-list 和三个宏(va-start、va-arg 和 va-
end),用它们在被调用函数不知道参数个数和类型时对可变参数表进行测试,从而为访问可变参数提供
了方便且有效的方法。va-list 是一个 char 类型的指针,当被调用函数使用一个可变参数时,它声明一个
类型为 va-list 的变量,该变量用来指向 va-arg 和 va-end 所需信息的位置。下面给出 va_list 在 C 中的
源码:
typedef char * va_list;
void va-start(va-list ap,last#x)是一个宏,它使 va-list 类型变量 ap 指向被传递给函数的可变参数表中
的第一个参数,在第一次调用 va-arg 和 va-end 之前,必须首先调用该宏。 va-start 的第二个参数
last#x 是传递给被调用函数的最后一个固定参数的标识符。 va-start 使 ap 只指向 last#x 之外的可变参
数表中的第一个参数,很明显它先得到第一个参数内存地址,然后又加上这个参数的内存大小,就是下个
参数的内存地址了。下面给出 va_start 在 C 中的源码:
#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) ) //得到可变参
数中第一个参数的首地址
资源评论
weixin_38655484
- 粉丝: 4
- 资源: 909
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功