![]() |
1
10
你不能像你描述的那样做。 C调用约定是让调用者在堆栈上放置参数,但它不放置任何关于类型的信息,因此被调用者必须有方法找到它(至少是变量的大小)。
因此你 不得不 传递类型。 在某些情况下,您可以预测类型(例如:一个计数器后面跟着一些整数,等等),但通常是通过参数编码传递它。您可以像printf一样将其编码为格式字符串,jldupont描述的联合技巧也很常见。 但无论如何,你必须通过它。 您真的不能依赖底层的数据二进制表示,甚至不能依赖数据大小。即使程序在您编写时似乎可以工作,它也没有兼容性,并且可以与系统、编译器的任何更改,甚至在更改编译选项时中断。 让我们来看一个例子,在这个例子中,您传递的类型后面跟着参数(因此既不是联合技巧,也不是像printf这样的格式字符串)。它所做的是将传递的所有值转换为double并添加它们,但实际上没有什么用处,不是吗:
此示例使用
新的
c99中定义的stdarg variadic头。要使用它,您需要对函数至少有一个固定参数(在本例中,它是
|
![]() |
2
14
为每个参数使用void*(或类型化结构),并使用带有“type”参数(整数)的结构。包含实际值的指针/联合。 换句话说,每个参数都通过指向类型化结构的指针传递。此类型结构的每个实例都包含一个值。此“值”的类型包含在此类型结构中。 更好的例子:
我遇到的这种技巧的最新例子是dbus。 |
![]() |
3
3
不能像描述的那样对变量参数执行此操作,因为除非显式执行,否则编译后不会保留有关传递的参数类型的信息。即使传递参数变量的地址也不会告诉您这一点,因为表示字符串的内存中的位可以表示数字或其他东西。
要使varargs与变量类型一起工作,可以将类型信息存储在参数本身中(例如,如jldupont在其答案中所描述的那样),也可以将信息存储在非变量参数中(例如,格式字符串如
|
![]() |
4
1
应对 http://en.wikipedia.org/wiki/Stdarg.h :
这是你的职责
不能
只从参数中知道哪些参数是字符串。你会
需要
告诉你的函数以某种方式期望什么。这就是为什么
|
![]() |
5
0
试试你?intptr_t,在stdint.h中定义。这是一个整数,保证足够大以容纳指针。 您可能还想考虑当您传递一个浮点数时会发生什么;它被转换为并作为双精度数传递。如果您的程序需要一个int,这将破坏其堆栈视图。哎哟。编译器无法捕捉到这一点。 而您的函数,如定义的那样,有(除了在paramn中进行任何位编码,在这种情况下,它应该是一个枚举或位域,或者至少是无符号的)没有办法知道它接收到的参数类型,因此不太可能对它们做任何有用的事情。C的对象没有运行时类型信息。 你到底想做什么? |
![]() |
Iliketoproveit · MATLAB函数中的变量参数对 7 年前 |
![]() |
jetstream · 变量参数和函数指针向量 7 年前 |
![]() |
WrathOfFlame · 解压缩函数调用的参数数组 7 年前 |
![]() |
flawr · 如何编写输出参数数目可变的匿名函数? 7 年前 |
![]() |
Tyler Jackson · 子类中变量函数特化的定义 7 年前 |
|
Brave Shine · Lisp&rest参数和递归调用 7 年前 |