提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
我们的题目已经折服了多位外校同学,不过今天,它还是超越了自己,达到了新的巅峰
一、题目
讲真,暗魅闻花看不懂,所以破例直接先上代码。
#include <stdio.h>
#include <stdarg.h>
double avg(int n,...)
{
int count=0,sum=0,i;
va_list arg_ptr;
va_start(arg_ptr,n);
i=va_arg(arg_ptr,int);
while(n>0)
{
n--;
sum+=i;
count++;
i=va_arg(arg_ptr,int);
}
va_end(arg_ptr);
return(count>0?(double)sum/count:0);
}
int main(void)
{
int a,b,c,d,e;
double m;
scanf("%d %d %d %d %d",&a,&b,&c,&d,&e);
m=avg(2,a,b)-avg(3,c,d,e);
printf("%.4lf",m);
return 0;
}
急,代码也看不懂。
二、stdarg.h
使用
查了好多博客,以下是我比较能看得懂的:
CSDN:
读史以明鉴:C语言可变参数(stdarg.h包含)详解
shanhuhauus:stdarg.h头文件详解
MagicEcho123C:语言头文件stdarg.h的使用
MSDN:
va_arg, va_copy, va_end, va_start
下面是我从博客里总结的:
1.函数的建立double avg(int n,...)
注:parmN表示省略号……
即代码中double avg(int n,...)
n表示……中参数的个数。
同时,
2.函数体
例如:
该示例中:
调用时语句为prt(3,1,2,3.0)
,其中3表示有三个数(故输出中num=3);
函数中:
1.变量va_list 指针名
;
创建一个适用于 va_start()、va_arg() 和 va_end() 这三个宏存储信息的类型
2.宏va_start(指针名,形参个数);
初始化刚定义的va_list
变量,使其指向第一个可变参数的地址(不同版本规则不一定相同)
来自MSDN的说明:
3.宏va_arg(指针名,类型);
(与赋值有区别)
(1)用a = va_arg(list,int);
表示将prt(3,1,2,3.0)
中的下一位(此时即为第一位:1)的值转换为int
形式后转移(赋值)至a,
(2)用b = va_arg(list,int)
表示将prt(3,1,2,3.0)
中的下一位(此时即为第二位:2)的值转换为int
形式后转移(赋值)至b,
(3)用c = va_arg(list,double)
表示将prt(3,1,2,3.0)
中的下一位(此时即为第二位:2)的值转换为double
形式后转移(赋值)至c;
(注意:传入的参数类型必须与宏参数的类型相匹配。 如a在声明时为int型,则转移也应用int。 但是 如果a是double型, 这行代码可能会出错。 这里不会像赋值那样 把 double 类型自动转换成int类型。)
4.va_copy(va_list dest,va_list src);
dest
指向要从 src
中初始化的参数列表的指针;
src
指向要复制到 dest
的参数初始化列表的指针;
即进行指针与指针之间的操作
5. 宏va_end(指针名);
清理该指针:释放动态分配用于储存参数的内存
注:被va_end(指针名)
清理后只有通过 va_start(指针名,形参个数)
重新初始化该指针后才能使用该指针
3.读代码
下面我们回到本题,读代码
#include <stdio.h>
#include <stdarg.h>
double avg(int n,...)//创建一个可变参数函数
{
int count=0,sum=0,i;
va_list arg_ptr; //创建一个适用于va套餐的指针arg_ptr
va_start(arg_ptr,n); //初始化刚定义的指针arg_ptr,使其指向第一个可变参数的地址
i=va_arg(arg_ptr,int); //将下一位(此时即为第一位:1)的值转换为`int`形式后转移(赋值)至i
while(n>0) //当……中的数字个数大于0时进入循环
{
n--; //用来出循环
sum+=i; //加上此时i对应的值
count++;
i=va_arg(arg_ptr,int); //将下一位的值转换为`int`形式后转移(赋值)至i
}
va_end(arg_ptr); //清理该指针:释放动态分配用于储存参数的内存
return(count>0?(double)sum/count:0); //三木操作符
//如果count>0,即输入数字个数大于0,则输出sum/count,表示均值
//如果count<=0,则输出0
}
int main(void)
{
int a,b,c,d,e;
double m;
scanf("%d %d %d %d %d",&a,&b,&c,&d,&e);
m=avg(2,a,b)-avg(3,c,d,e);
printf("%.4lf",m);
return 0;
}
总结
stdarg.h
到底有什么用处
首先,在不确定参数个数时,就可以使用可变参数。这似乎给我上一篇10_25基斯数提供了一些灵感,改天写下。
查了查,数组和可变参数还是有不少区别
害,学习尚未成功,我辈仍需努力。