c - variadic function - 参数【个数】可变函数
参考
https://en.cppreference.com/w/c/variadic
https://en.cppreference.com/w/c/language/variadic
参数可变函数
The declaration of a variadic function uses an ellipsis as the last parameter,
e.g. int printf(const char* format, ...);
See variadic arguments for additional detail on the syntax and automatic argument conversions.
参数可变函数声明时,最后一个 参数 使用 三个点好 来表示。
示例: int printf(const char * format, ... );
https://en.cppreference.com/w/c/language/variadic 里面介绍 可变参数和 参数类型转换。
参数类型转换
1、对于没有 函数原型 的函数的调用
2、对于 参数可变函数的调用(中的 可变参数部分),
这两种情况下,传递进入的参数都会进行 隐式转换
见 https://en.cppreference.com/w/c/language/conversion#Default_argument_promotions
Each argument of integer type undergoes integer promotion (see below), and each argument of type float is implicitly converted to the type double
每个 integer 类型的参数都 转换为int ; 每个 浮点 参数 都转换为 double 类型。
int add_nums(int count, ...); int sum = add_nums(2, 'c', true); // add_nums is called with three ints: (2, 99, 1)
处理可变参数
macro 下面这几个是 宏定义
va_start
va_arg
va_end
va_copy c99 中引入
type 下面这个是 类型定义
va_list
使用示例
#include <stdio.h>
#include <stdarg.h>
void simple_printf(const char* fmt, ...)
{
va_list args; // va_list 定义一个 变量,用于存放 信息
// va_start 宏-第一个参数是 va_list 定义的变量,第二个参数是 函数 可变参数前面的一个参数。
// va_start 和 va_end 一一对应
va_start(args, fmt);
while (*fmt != '\0') {
if (*fmt == 'd') {
int i = va_arg(args, int); // va_arg 第一个是 va_list 定义的变量,第二个是类型
printf("%d\n", i);
} else if (*fmt == 'c') {
// A 'char' variable will be promoted to 'int'
// A character literal in C is already 'int' by itself
int c = va_arg(args, int);
printf("%c\n", c);
} else if (*fmt == 'f') {
double d = va_arg(args, double);
printf("%f\n", d);
}
++fmt;
}
va_end(args); // va_end 宏只需要一个参数
}
int main(void)
{
simple_printf("dcff", 3, 'a', 1.999, 42.5);
}
va_copy 示例 - 求标准差
void va_copy(va_list dest, va_list src);
The va_copy macro copies src to dest.
va_end should be called on dest before the function returns or any subsequent re-initialization of dest (via calls to va_start or va_copy).
#include <stdio.h>
#include <stdarg.h>
#include <math.h>
double sample_stddev(int count, ...)
{
/* Compute the mean with args1. */
double sum = 0;
va_list args1;
va_start(args1, count);
va_list args2;
va_copy(args2, args1); /* copy va_list object */
for (int i = 0; i < count; ++i) {
double num = va_arg(args1, double);
sum += num;
}
va_end(args1);
double mean = sum / count;
/* Compute standard deviation with args2 and mean. */
double sum_sq_diff = 0;
for (int i = 0; i < count; ++i) {
double num = va_arg(args2, double);
sum_sq_diff += (num-mean) * (num-mean);
}
va_end(args2);
return sqrt(sum_sq_diff / count);
}
int main(void)
{
printf("%f\n", sample_stddev(4, 25.0, 27.3, 26.9, 25.7));
}
浙公网安备 33010602011771号