社区
工具平台和程序库
帖子详情
怎样获得可变参数函数中的参数的个数?(va_list)
wplian
2003-04-08 11:16:46
内容同标题
...全文
1702
7
打赏
收藏
怎样获得可变参数函数中的参数的个数?(va_list)
内容同标题
复制链接
扫一扫
分享
转发到动态
举报
AI
作业
写回复
配置赞助广告
用AI写文章
7 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
突击召唤师
2003-04-08
打赏
举报
回复
http://bbs.gxnu.edu.cn/cgi-bin/bbscon?board=Programming&file=M.965445434.A&num=177&title=149
http://bbs.gxnu.edu.cn/cgi-bin/bbscon?board=Programming&file=M.1002846622.A&num=343&title=288
看看吧,介绍得很详细的。
wplian
2003-04-08
打赏
举报
回复
我看过这四个宏定义了,va_list va_start va_args va_end
是根据给出的参数类型逐个的计算下一个参数所在的地址
本身并没有保存参数列表的内存大小,更何况调进的参数的类型各不相同
所以得到参数的个数似乎不太可能,当然传递参数个数及传递特定的结束符除外
楼上的老兄写的程序我虽然看的不大明白
不过总感觉与其本身的宏定义的意思差不多,我还是用上面两个比较方便的方法吧
多谢各位了,结帖
zhouzhaohan
2003-04-08
打赏
举报
回复
之所以要这么做实在是因为只有函数的调用者才有足够的信息知道到底有多少参数,而被调用的人却对此一无所知。
zhouzhaohan
2003-04-08
打赏
举报
回复
你也可以通过在参数中传递参数的个数,或者使用类似printf之类的格式字符串实现。
你用的是什么CPU,是不是intel?
如果是的话就好一点,我想到一种做法,但是可能不通用。至于有多么不通用,我也很难保证。
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
int test(int a,...)
{
int count;
int ra;
int instruction;
va_list marker;
va_start(marker,a);//也可以直接取地址
ra=(*(int *)((int)marker-8));//根据第一个参数的地址,在栈上取得函数返回地址
printf("Return address:%x ",ra);
instruction=(*(int *)(*(int *)((int)marker-8)));//取得返回地址的指令
printf("Instruction %x ",instruction);
count=((instruction&0xff0000)>>16)/4;//从指令中提取需要的信息,每个入口参数占4个字节,如果都是int的话。
printf("Count of argument %d ",count);
printf("\n");
}
void main()
{
test(1,2,3,4,5);
test(1,2,3,4);
test(1,2,3);
test(1,2);
test(1);
}
以上的做法基于了这样几种假定,但是我相对于同一个编译器而言,这些假定应该是一致的,否则这种做法也没有意义。
在调用函数时,caller将把参数压栈,在调用结束后,caller马上恢复栈,恢复是通过在esp寄存器上加上一定的数值,而这个数值就等于所有入口参数占的空间。同时恢复栈用的是一个固定的语句,addl num,%esp,因此就可以从这个语句中提取出我们需要的信息。而callee被调用后同样会压栈,而且一些固定信息会有固定的位置。函数的返回地址就属于这种情况。我们可以很容易在栈上栈到它,而这个地址存放的语句正是我们所需要的。
在我的机器上调用test(1,2,3,4,5)生成的汇编是:
pushl $0x05
pushl $0x04
pushl $0x03
pushl $0x02
pushl $0x01
call xxxxx
addl $0x14,%esp
上面的规律是可以利用的,来达到你的目的。
但是我想这可能和calling convention 和optimization也有一定关系。
zhouzhaohan
2003-04-08
打赏
举报
回复
mark
wplian
2003-04-08
打赏
举报
回复
其中一篇有一段是这样说的:
调用者在实际调用参数个数可变的函数时,要通过一定的方法指明实际参数的个数,例如把最后一个参数置为空字符串(系统调用execl()就是这样的)、-1或其他的方式。
对于“其他的方式”是什么意思呢?是仅仅修改最后一个参数的不同样式,还是有其他的解决方法?我不懂,望各位大侠能给我解释。
wplian
2003-04-08
打赏
举报
回复
TO 楼上老兄: 我非常感谢你提供的资料,但同时我也很遗憾,那里并没有我想要的东西。上面给的示例程序与MSDN上的大相径庭,在参数表后都要加上一个 0、-1 或 '\0'等作为结束标志,而我就是想不要这些东西同时又能判断已经读到参数列表的末尾,希望大家能给我解决的方法。
va
-
list
原理解释
va
_
list
原理解释,解释了关于
VA
_
LIST
的用法、
VA
_
LIST
在编译器
中
的处理、
VA
_
LIST
应该注意的问题、以及相关程序
C语言
可变
参数
函数
教程大家下载吧
C语言
可变
参数
函数
C语言
可变
参数
函数
C语言
可变
参数
函数
C语言
可变
参数
函数
C语言
可变
参数
函数
C语言
可变
参数
函数
C语言
可变
参数
函数
C语言
可变
参数
函数
C语言
可变
参数
函数
C语言
可变
参数
函数
C/C++定义
可变
参数
函数
,演示程序
C/C++定义
可变
参数
函数
,演示程序,教你怎么写一个
参数
可变的
函数
详解-C语言
可变
参数
-
va
-
list
和-vsnprintf及printf实现.pdf
详解-C语言
可变
参数
-
va
-
list
和-vsnprintf及printf实现.pdf
c语言
va
函数
讲解.
VA
函数
(
va
riable argument function),
参数
个数
可变
函数
,又称
可变
参数
函数
。C/C++编程
中
,系统提供给编程人员的
va
函数
很少。*printf()/*scanf() 系列
函数
,用于输入输出时格式化字符串;exec*()系列
函数
,用于在程序
中
执 行外部文件(main(int argc, char* argv[]算不算呢,与其说main()也是一个
可变
参数
函数
,倒不如说它是exec*()经过封装后的具备特殊功能和意义的函 数,至少在原理这一级上有很多相似之处)。由于
参数
个数
的不确定,使
va
函 数具有很大的灵活性,易用性,对没有使用过
可变
参数
函数
的编程人员很有诱惑 力;那么,该如何编写自己的
va
函数
,
va
函数
的运用时机、编译实现又是如何。 作者借本文谈谈自己关于
va
函数
的一些浅见。
工具平台和程序库
24,857
社区成员
27,330
社区内容
发帖
与我相关
我的任务
工具平台和程序库
C/C++ 工具平台和程序库
复制链接
扫一扫
分享
社区描述
C/C++ 工具平台和程序库
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章