10_27 可变参数平均

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

我们的题目已经折服了多位外校同学,不过今天,它还是超越了自己,达到了新的巅峰


一、题目

示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。

讲真,暗魅闻花看不懂,所以破例直接先上代码。

#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基斯数提供了一些灵感,改天写下。
查了查,数组和可变参数还是有不少区别
L在前方原创
害,学习尚未成功,我辈仍需努力。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值