C语言 不指定参数数量的可变参数函数



我正在学习C编程语言,我发现非常有趣的一件事是可变参数函数的实现。我目前正在尝试打印传递到函数中的每个值,但我只得到了一部分参数。

我尝试运行一些我在网上找到的参数平均数示例以及求和算法(如下所示)。

#include <stdio.h>
#include <stdarg.h>
int sum(int count, ...)
{
va_list args;
va_start(args, count);
int total = 0;
for (int i = 0; i < count; i++) {
int num = va_arg(args, int);
total += num;
printf("Value #%d: %dn", i, num);
}
va_end(args);
return total;
}
int main()
{
int result = sum(1, 2, 3, 4, 5);
printf("The result is: %dn", result);
}

上面的代码仅打印:

Value #0: 2
The result is: 2

我认为这是因为for循环使用第一个参数作为索引的最大值。但。。。

我这里的问题是,如果没有必要在格式化字符串中传递要替换的参数数量,printf如何工作? 是因为在后台,C 运行时会计算格式化字符串中声明了多少个格式说明符?这是我的猜测。

没有办法找出实际提供了多少参数。

printf()从格式字符串中找出来。格式字符串中的每个%运算符都对应于一个参数(这是一种简化),它处理尽可能多的参数来填充每个参数。

所以如果你写:

printf("%d %sn", intvar, stringvar);

它知道必须有 2 个附加参数:一个用于%d,另一个用于%s

某些函数使用的另一种方法是指示最后一个参数的哨兵值。

execl("program", "arg0", "arg1", "arg2", (char *)NULL);

execl()处理参数,直到到达NULL值。

如果将可变参数函数调用为:

int result = sum(5 /*count*/, 1, 2, 3, 4, 5);

通过添加初始5(计数),它将完成您期望的操作,但为了好玩,请尝试使用更大的数字(例如 6 或 10)调用它,看看会发生什么。他们很容易出错。

可变参数函数几乎唯一好的案例是为您的应用量身定制的 printf 变体。 我长期以来最喜欢的是die(),它采用 printf 样式的格式字符串(和参数),将其发送到标准错误,附加换行符,然后退出程序。

#include <stdlib.h>
#include <stdarg.h>
void die(const char *format, ...)
{
va_list args;
va_start(args, format);
vprintf(stderr, format, args);
va_end(args);
fprintf(stderr, "n");
exit(EXIT_FAILURE);
}

然后将其放在头文件中以使用它:

extern void die(const char *format, ...)
__attribute__((noexit))         // function never exits
__attribute__((printf(1, 2)));  // looks like printf, format is arg1

现在你可以打电话给die("Program failed because %s", reason);,它可以保释程序,而不会有很多麻烦和大惊小怪。由于使用__attribute__,编译器(至少是GNU)知道如何验证格式字符串的参数。

相关内容

  • 没有找到相关文章

最新更新