变参函数解释

方一诺 2013-03-15 10:14:39
有这样的一个变参函数的实现,尚且不能明白自定的是什么意思;请高手指点,万分感谢!!

#include<stdio.h>

#define va_list void* //va_list相当于一个指针
#define va_end(arg) // 什么意思???
#define va_arg(arg,type) *(type*)arg; //为什么有个 分号????
arg = (char*)arg+sizeof(type) ; //这一步又是什么意思???
#define va_start(arg,start) arg=(va_list)(((char*)&start))+sizeof(start)) // ??

int accumlate(int nr,...)
{
int i=0;
int result=0;
va_list=NULL;
va_start(arg,nr);

for (i=0; i<nr; ++i)
{
result += va_arg(arg,int);
}
va_end(arg);
return rusult;
}

int main(int argc, char* argv[])
{
printf("%d\n",accumlate(1,100));
printf("%d\n",accumlate(2,100,200));
printf("%d\n",accumlate(3,100,200,300));
return 0;
}

解释一下程序,谢谢!
...全文
96 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
Athenacle_ 2013-03-15
  • 打赏
  • 举报
回复

 #define va_end(arg)  // 空的宏,木有效果
 #define va_arg(arg,type)     *(type*)arg;   
                              //一条解引用语句而已。。你确定没有少了一个反斜杠?
                              arg = (char*)arg+sizeof(type) ; 
                              //把arg化为字符指针,加上一个sizeof,去栈上取值。

 #define va_start(arg,start) arg=(va_list)(((char*)&start))+sizeof(start))
           //取得start的地址,加上sizeof(start),取得start后面一个参数的地址,赋值给arg
 
1. va系列的东西都是平台相关的,不必太过纠结 2. printf族函数是不定参数的。解析字符串,每碰到一个%d等token,调用一次va_arg,进行格式化,调用底层函数输出。 3. 由于不定参数函数都是_cdecl的,所以,可以保证自右向左压栈。 4. 由于不定参数函数无法进行类型检查,所以,必发生提升。char->int;short->int;float->double等 5. 尽量减少使用不定参数函数。
starytx 2013-03-15
  • 打赏
  • 举报
回复
这个函数的功能就是按照第一个参数指定的个数,来累加后边输入的各个数,最后返回累加的结果,最后程序的输出就是: 100 300 600 你明白这va_xxx这几个东西怎么用就行了,printf的实现应该和这个差不多吧,会用就行了
方一诺 2013-03-15
  • 打赏
  • 举报
回复
有这样的一个变参函数的实现,尚且不能明白自定的是什么意思;请高手指点,万分感谢!! #include<stdio.h> #define va_list void* //va_list相当于一个指针 #define va_end(arg) // 什么意思??? #define va_arg(arg,type) *(type*)arg; //为什么有个 分号???? arg = (char*)arg+sizeof(type) ; //这一步又是什么意思??? #define va_start(arg,start) arg=(va_list)(((char*)&start))+sizeof(start)) // ?? int accumlate(int nr,...) { int i=0; int result=0; va_list arg=NULL; va_start(arg,nr); for (i=0; i<nr; ++i) { result += va_arg(arg,int); } va_end(arg); return rusult; } int main(int argc, char* argv[]) { printf("%d\n",accumlate(1,100)); printf("%d\n",accumlate(2,100,200)); printf("%d\n",accumlate(3,100,200,300)); return 0; } 解释一下程序,谢谢! 还有,,能解释一下 printf(...)这个函数的内部实现吗? 谢谢。
starytx 2013-03-15
  • 打赏
  • 举报
回复
#define是宏定义,这个就不多说了 va_list arg; //arg是传入的参数的指针,访问传入的可变参数都要通过它进行。 va_start(arg,nr); //初始化参数指针,nr就传入函数的最后一个强制性参数 result += va_arg(ap,int); //va_arg()宏通过arg指针从可选参数列表中提取下一个值,并转换为int类型作为result的增量 va_end(arg); //不再使用可选参数,做一些清理工作。
ForestDB 2013-03-15
  • 打赏
  • 举报
回复
网上有很多解析变参函数的实现原理。
赵4老师 2013-03-15
  • 打赏
  • 举报
回复
对学习编程者的忠告: 眼过千遍不如手过一遍! 书看千行不如手敲一行! 手敲千行不如单步一行! 单步源代码千行不如单步对应汇编一行!

64,662

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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