15.5关于C语言可变参数的几个问题
1、为什么编译器不让我定义一个没有固定参数项的可变参数函数?
标准C 要求用可变参数的函数至少有一个固定参数项, 这样你才可以使用va start()。所以编译器不会接受下面定义的函数:
int f(...)
{
...
}
参见问题15.9。
2、 我有个接受float 的可变参函数, 为什么va arg(argp, float) 不工作?
“参数默认晋级” 规则适用于在可变参数中的可变动部分: 参数类型为float 的总是晋级(扩展) 到double, char 和short int 晋级到int。所以va arg(arpg, float)是错误的用法。应该总是用va arg(arpg, double)。同理, 要用va arg(argp, int) 来取得原来类型是char, short 或int 的参数。基于相同理由, 传给va start() 的最后一个“固定” 参数项的类型不会被晋级。参见问题11.4 和15.2。
3、 va arg() 不能得到类型为函数指针的参数。
宏va arg() 所用的类型重写不能很好地操作于象函数指针这类过度复杂的类型。但是如果你用typedef 定义一个函数指针类型, 那就一切正常了。参见问题1.7。
参考资料: [ISO, Sec. 7.8.1.2]; [Rationale, Sec. 4.8.1.2]。
4、怎样实现一个可变参数函数, 它把参数再传给另一个可变参数函数?
通常来说, 你做不到。理想情况下, 你应该提供另一个版本的函数, 这个函数接受va list 指针类型的参数。类似于vfprintf(), 参见问题15.5。如果所有的参数必须完整的传给另一个函数, 或者你不能重写另一个函数为一个接受va list 指针类型参数的函数, 这并没有一个可移植的解决方法。也许可以通过求助于机器的汇编语言来实现。参见问题15.12。
5、怎样调用一个参数在执行是才建立的函数?
这没有一个保证工作或可移植的方法。如果你好奇, 可以问本文的编辑(Steve Summit), 他有一些古怪的点子, 也许你可以试试……也许你可以试着传一个无值型指针(void *) 数组, 而不是一个参数序列。被调用函数遍历这个数组, 就象main() 遍历argv 一样。当然这一切都建立在你能控制所有的调用函数上。参见问题19.35。