在C中,我们如何强制varargs函数中的最后一个参数为终止null?

时间:2018-01-24 16:00:32

标签: c function variadic-functions default-arguments

在C ++中,我们可能会写这样的东西:

#include <cassert.h>
#include <cstdio.h>
#include <cstdarg.h>

void func(..., short end = 0) {

   // prevent caller from overriding default value with something other than null 
   assert(end == 0);

   va_list args;  

   short x;
   x = va_arg(args, short); 

   while (x != 0) {
       printf("%d", va_arg(args, short));
   }

   va_end(list);

   return;
}

但是,C不支持默认函数参数。有没有我可以强制func在其参数列表的末尾有一个尾随空字符?有没有办法在没有程序员明确地将终止空值传递给函数的情况下呢?

我们不希望看到如下调用:

int   x = 5;
float y = 6.4;
func(x, y, 0);

我们只想要func(x, y);

是否可以编写一个可以转换文本的宏,如

func(x, y);

进入通话:

func(x, y, 0);

如果没有宏,有没有办法做到这一点?

3 个答案:

答案 0 :(得分:6)

您无法强制varargs函数在C中具有特定的“last”值。

参数列表中需要有一些东西告诉函数有多少参数。标准库中的一些示例:

  • printf:格式字符串告诉函数有多少参数及其类型。
  • execl:需要多个const char *个参数,其中最后一个必须是NULL

因此,在调用varargs函数时,将一个“flag”参数作为最后一个参数是C中已知的编程范例。这不是你需要掩盖的内容。

话虽这么说,你可以使用宏来做你想做的事情:

#define FUNC(...) func(__VA_ARGS__, 0)

宏参数列表中的...捕获所有参数,__VA_ARGS__宏表示这些参数。

然后你可以像这样定义func

void func(short first, ...)

通过像这样的宏来调用它

FUNC(x, y);

答案 1 :(得分:3)

这不是C varargs的用途,因此很难让他们以这种方式工作。应该有一个强制性的前导参数,您可以从中推断出以下参数的数量和类型。格式字符串为printf系列函数填充此角色。您可以为参数数量取一个整数,并在函数名称中对类型进行编码。

funcs(int num, ...); // s for short

但这不会提供任何类型的执行。编译器仍然允许传递非短路。没有办法通过vararg强制执行类型。此时你不妨使用经典数组和计数习语。

funcs(int num, short const*);

答案 2 :(得分:0)

#define func(x,y,z) func(x,y)应该作为宏工作,但是你想要的是什么(具有相同函数名的不同数量的参数)在C中是不可能的。 您还可以使用一个函数,将包含参数和参数数量的数组作为整数传递,然后根据给定的参数数量,您可以执行不同的操作。