在下面的例子中,我想把数组的内容传递给一个接收变量的函数。
换句话说,我想通过值将foo
的内容传递给printf
,从而在堆栈上传递这些参数。
#include <stdarg.h>
#include <stdio.h>
void main()
{
int foo[] = {1,2,3,4};
printf("%d, %d, %d, %d\n", foo);
}
我知道这个例子看起来很愚蠢,因为我可以使用printf("%d, %d, %d, %d\n", 1,2,3,4);
。想象一下,我调用的是void bar(char** a, ...)
,而数组是我从RS232接收的...
编辑
换句话说,我想避免这样:
#include <stdarg.h>
#include <stdio.h>
void main()
{
int foo[] = {1,2,3,4};
switch(sizeof(foo))
{
case 1: printf("%d, %d, %d, %d\n", foo[0]); break;
case 2: printf("%d, %d, %d, %d\n", foo[0], foo[1]); break;
case 3: printf("%d, %d, %d, %d\n", foo[0], foo[1], foo[2]); break;
case 4: printf("%d, %d, %d, %d\n", foo[0], foo[1], foo[2], foo[3]); break;
...
}
}
5条答案
按热度按时间4smxwvx51#
我想把foo的内容按值传递给printf,这样就可以在堆栈上传递这些参数。
你不能通过值传递数组,不能通过“普通”函数调用传递,也不能通过varargs传递(基本上,这只是一种不同的读取堆栈的方式)。
当你使用数组作为函数的参数时,被调用的函数 * 接收到的 * 是一个指针。
最简单的例子是char数组,也称为“string”。
strcpy()
“看到”的不是两个数组,而是两个指针:(This这就是为什么数组的 size 只有在数组 * 声明 * 的作用域中才是已知的。一旦传递它,它就只是一个指针,没有地方放置大小信息。)
将数组传递给varargs函数时也是如此:在堆栈上结束的是指向数组(的第一个元素)的 * 指针 *,而不是整个数组。
您 * 可以 * 通过引用传递数组 * 并在被调用的函数中 * 使用它做有用的事情,如果:
1.传递数组 *(指向数组的指针)和元素计数 *(考虑
argc
/argv
),或者1.呼叫方和被呼叫方就固定大小达成一致,或
1.调用者和被调用者同意以某种方式“终止”数组。
标准
printf()
为"%s"
和字符串(以'\0'
结尾)执行最后一个操作,但是不具备使用int[]
数组执行此操作的能力,如您的示例所示。因此,您必须编写自己的自定义printme()
。在任何情况下,你都不会“按值”传递数组。如果你仔细想想,对于更大的数组,将所有元素复制到堆栈中没有多大意义。
at0kjp5o2#
如前所述,你不能直接在
va_arg
中通过值传递数组。如果它被打包在struct
中,这是可能的。它是不可移植的,但是当实现已知时,你可以做一些事情。这里举个例子,可能会有帮助。
将打印以下内容(
HEXDUMP()
是我的调试函数之一,它的作用显而易见)。在使用gcc 5.1编译的Linux x86_64和使用gcc 3.4编译的Solaris SPARC9上进行测试
我不知道它是否有用,但它可能是一个开始。正如可以看到的,在函数
va_arg
中使用最大的struct数组允许处理更小的数组,如果大小已知的话。但是要小心,它可能充满了未定义的行为(例如,如果调用的函数的结构体数组大小小于4int,则它在Linux x86_64上不起作用,因为该结构体是通过寄存器传递的,不是作为堆栈上数组,而是在您的嵌入式处理器上,它可能会工作)。72qzrwbm3#
简短回答:不,你做不到,这不可能。
稍长的回答:好吧,也许你能做到,但这是非常棘手的。你基本上是试图用一个直到运行时才知道的参数列表来调用函数。有一些库可以帮助你动态地构造参数列表并用它们来调用函数;一个库是libffi:https://sourceware.org/libffi/。
另请参见C FAQ列表中的问题15.13:How can I call a function with an argument list built up at run time?
另请参阅这些先前的Stackoverflow问题:
C late binding with unknown arguments
How to call functions by their pointers passing multiple arguments in C?
Calling a variadic function with an unknown number of parameters
qyyhg6bp4#
看这个例子,从我的代码中。这是一个简单的方法。
dbg_chr(uint8_t字节)将字节丢弃到USART并启用发送器。
使用示例:
amrnrhlw5#
如上所述,变量参数可以作为结构封装数组传递:
经过测试,可与gnu C编译器配合使用