2

如何将许多参数传递给 C 函数?假设我有这个功能:

void f(int n, char* a, char* b, ...)

我想要一个未定义数量的 char* 参数。我该怎么做?

4

2 回答 2

5

您需要的是可变数量的参数函数,您可以阅读:9.9。可变数量的论点是一个很好的论文教程。

一个简短的四点理论将帮助您理解我的代码:

  1. <stdarg.h>必须包含头文件,他引入了一种新类型,称为 va_list,以及对这种类型的对象进行操作的三个函数,称为va_start, va_arg, and va_end.
  2. va_start:是一个宏,设置为可选参数arg_ptr列表的开头ap
  3. va_arg:确实是使用这个保存的堆栈指针,并为提供的类型提取正确的字节数
  4. va_end:是一个要重置的宏ap,在检索到所有参数后,va_end将指针重置为 NULL。

这个理论还不够,但下面的示例(根据您的需要)将帮助您理解基本的工作流程/和步骤:(每 4 个步骤阅读评论

//Step1: Need necessary header file
#include <stdarg.h>     
void f(int first, char* a, char* b, ...){   
    va_list ap;  // vlist variable
    int n;       // number 
    char aa,     
    int i;
    float f;
   //print fix numbers of arguments
    printf("\n %d, %s, %s\n", first, a, b);

   //Step2: To initialize `ap` using right-most argument that is `b` 
    va_start(ap, b); 

   //Step3: Now access vlist `ap`  elements using va_arg()
     n = va_arg(ap, int); //first value in my list gives number of ele in list 
     while(n--){
       aa = (char)va_arg(ap, int); // notice type, and typecast
       i = va_arg(ap, int);
       f = (float)va_arg(ap, double);   
       printf("\n %c %d %f \n", aa,i, f);
    }

    //Step4: Now work done, we should reset pointer to NULL
    va_end(ap); 
}
int main(){
    char* a = "Aoues";
    char* b = "Guesmi";
    f(2, a, b, 3, 'a', 3, 6.7f, 'b', 5, 5.5f, 'A', 0, 0.1);
    //         ^ this is `n` like count in variable list
    return 1;
}

谁运行:

~$ ./a.out 
 2, Aoues, Guesmi
 a 3 6.700000 
 b 5 5.500000 
 A 0 0.100000 

我的代码的简要说明将对未来的用户有所帮助:

  1. 实际上函数是固定数量的参数,后跟可变数量的参数。函数最右边的参数(char* b在我们函数中的固定参数列表中f())仅用于初始化可行列表ap
  2. first 上面的函数f()读取的n值是3读取 main 中的注释)。在f(), 中 while(n--)执行 3 次,每次在循环中使用va_arg()宏我们检索三个值。
  3. 如果你注意到我读了前两个,ints然后是 a double,我发送的位置char, int, float在我调用 f() 的 main 中通知)。这是因为在可变参数列表的情况下自动类型提升。(从上面的 lisk 中详细阅读)

她是 MSDN 中另一个有用的链接:va_arg、va_end、va_start

如果您需要更多帮助,请告诉我

于 2013-04-05T09:59:21.973 回答
0

使用可变参数(自己查一下,被调用者用来读取参数的东西在stdarg.h)。

请注意,被调用者无法自动确定实际传递的参数数量。因此,例如它可能是n,您只需要相信调用者会n正确。

于 2013-04-05T09:46:09.300 回答