|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
开学了,就要考证了233333 可能就没有那么多时间了..
----------------------------------------写了个printf函数,于是就有了以下的感觉------------------------------------------
嗯!!可变参数是什么呢?
不直接告诉你~和大家举个例子..
不可变的参数:
void foo(int i,int n)
{
;
}
可变参数:
void foo1(int i,...)
{
;
}
接下来对以上两个函数进行调用,在编译的时候,给出了如下的警告:
warning C4020: “foo”: 实参太多.
什么foo函数的实参太多
是的实参太多了;那foo1输入了那么多个实参为什么不会出现实参太多的警告呢?
嗯.......是因为我们在foo1的函数中使用了可变参数啦!
从上面我们可以看出: 可变参数可以输入定义之外的参数而非可变参数则不行。
好啦,我们知道了什么是可变参数,那么可变参数这个功能到底放在什么地方呢?
接下下我们一起去扒一扒;
可变参数这个功能有一个专门的头文件来包含,这个头文件相信大家都很熟悉:<stdarg.h>
那么我们来介绍一下va系类的宏吧!
PS:va系列的宏,有点深度...-- (va :variable arguments 可变的参数
1. va_list
typedef char* va_list;
哦哦哦,原来va_list只是char*的马甲,什么意思?说白了就是一个马甲,他的原型还是char*
2.va_start
这个是什么?懵逼!
额!我们在VS中用万能的F12看看吧..
#define va_start __crt_va_start 什么来的??再来个F12吧
#define __crt_va_start(ap, x) __crt_va_start_a(ap, x) 还是不懂;再来个F12吧
#define __crt_va_start_a(ap, v) ((void)(ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v)))
额!ADDRESSOF(v)和_INTSIZEOF(v)是什么来的在F12吧
#define _INTSIZEOF(n) ((sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1))
PS:此宏定义的作用是宏的开始!并指向下一个可变参数的参数
#define _ADDRESSOF(v) (&(v))
PS:此宏定义的作用是获取可变参数第一个参数的地址;
如果我们把这些都结合起来可以得到一下的结论:
接收第一个可变参数的地址,并指向下一个可变参数的地址
哈哈!原形毕露了把!
3.va_agr
#define va_arg __crt_va_arg
#define __crt_va_arg(ap, t) (*(t*)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)))
谔谔!这个宏定义的主要分析是(*(t*)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)))这个
那我们来一起分析一下吧!
第一个*是解引用;(t*)其实指的就是类型的转换;
关键点来了 ap += _INTSIZEOF(t),这里是把指针指向了下一个参数,
那 - _INTSIZEOF(t) 这个又是为什么呢?
上面我们的指针已经指向了下一个可变参数,这里又指向了一下个,
也就是说我们一共向后了2个参数,所以这里要放回一个虚值,而这个虚值正好就是上一个可变参数的地址
这个宏的作用是读取后面的可变参数
4.va_end
#define va_end __crt_va_end
#define __crt_va_end(ap) ((void)(ap = (va_list)0))
哦,这个嘛,一看就知道了,就是把清除指针嘛
下面向大家分享我在写printf的疑问
为什么在打印%s的时候va_agr的参数为什么要写char *,为什么不能呢个用va_arg的方式来指向%s的数组呢?
因为啊,我们在输入字符串额时候,只是复制了字符串的地址,而并不是把整个字符串复制到可变参数中,
所以当我们指向了一个字符串的时候,其实是指向了可变参数的地址,所以我们要把,可变参数地址内的字符串地址给
取出来,所以我们把它转换了char**,然后在对他进行解引用,从而得到了字符串的地址。。。
--------------------------------------------------------写完了 请大家多多指教--------------------------------------------------
|
|