一个关于的问题

wanghao2979 2007-11-02 09:07:17
#include <iostream>
#include <stdarg.h>
using namespace std;
va_list data(int n,...)
{
va_list p;
va_start(p,n);
return p;
}
void fun(va_list p)
{
cout << va_arg(p,int);
}
int main()
{
fun(data(1,1));
system("pause");
return 0;
}
这个程序是这样的
把一个叠代器指针从va_list data中的 p
传入到 fun()函数中去
当p 在va_list data函数中return 的时候还是正常的值
1
但是在传入到fun()的过程中p 的值变了 我不知道为什么
大家还看看
...全文
190 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
laomai 2007-11-05
  • 打赏
  • 举报
回复
呵呵,我以前分析过可变参数的实现。
具体可见http://blog.csdn.net/laomai/archive/2005/02/01/276274.aspx
这里再节选一下
二)可变参数在编译器中的处理
va_start,va_arg,va_end是在stdarg.h中被定义成宏的,在VC++6.0中stdarg.h里的代码为(文件的路径为VC安装目录下的\vc98\include\stdarg.h)

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 )
下面我们解释这些代码的含义:
1、首先把va_list被定义成char*,这是因为在我们目前所用的PC机上,字符指针类型可以用来存储内存单元地址。而在有的机器上va_list是被定义成void*的
2、定义_INTSIZEOF(n)主要是为了某些需要内存的对齐的系统.这个宏的目的是为了得到最后一个固定参数的实际内存大小。
3、va_start的定义为 &v+_INTSIZEOF(v) ,这里&v是最后一个固定参数的起始地址,再加上其实际占用大小后,就得到了第一个可变参数的起始内存地址。所以运行va_start(ap, v)以后,ap指向第一个可变参数在的内存地址,
(4) va_arg里的任务就是根据指定的参数类型取得本参数的值,并且把指针调到下一个参数的起始地址。
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
这个宏做了两个事情,
①用用户输入的类型名对参数地址进行强制类型转换,得到用户所需要的值
②计算出本参数的实际大小,将指针调到本参数的结尾,也就是下一个参数的首地址,以便后续处理。

所以楼主看到的1应该是第二个参数值。程序运行结果没问题。

wanghao2979 2007-11-03
  • 打赏
  • 举报
回复
我用的vs2005.net编译器

不同的编译器有不同的结果
lomanchen 2007-11-03
  • 打赏
  • 举报
回复
当然指向的是下一个啦
data()里
va_start(p,n); //这个n你都知道了,还要来干嘛?
wanghao2979 2007-11-03
  • 打赏
  • 举报
回复
我按你的方法做了
不成功
chenyi3315 2007-11-02
  • 打赏
  • 举报
回复
data()里
va_start(p,n); //这时候p已经指向第二个参数了 ,1

fun()里
cout < < va_arg(p,int); //这里输出的是p的下面一个int参数值,当然变了

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧