函数可变参数列表的应用和原理

在网上看到各位前辈关于这部分的介绍有些是过于简洁,有些则是过于晦涩,有的代码拿出来甚至在编译器上跑不过去,所以在这里讲一下自己对于可变参数的认识,若有不正确的地方,欢迎各位网友指出来,以便不断修正这块的内容。

————————————————————————————————————
我们平常在使用函数传参时,往往会传进去固定的参数,我在这里举一个设计函数求几个数最大值的栗子:

#include<stdio.h>
#include<windows.h>
int my_max(int x,int y,int z)
{int max=0;if(x>y)max=x;elsemax=y;if(max>z)return max;elsereturn max=z;
}
int main()
{int a=12;int b=21;int c=121;printf("a=%d,b=%d,c=%d\n",a,b,c);printf("max=%d",my_max(a,b,c));system("pause");return 0;
}

从这个例子中我们可以看到他的局限性就在于,传进去的参数的个数是固定的,也就是这个my_max函数只能用于求三个数的最大数,以后若是想要求更多数的最大数,就不得不重新设计函数。所以,我们可以应用函数可变参数来避免这一局限性,下面我用可变参数的方式再写一遍这个函数:

#include<stdarg.h>
//交换两个变量的值
void swap(int *x,int *y)
{*X^=*y;*y^=*x;*x^=*y;
}
int my_max(int values,...)//注意此处的逗号后面是三个英文句号!
{int i=0;int max=0;va_list varg;//注意此处的varg是一个随意起的变量名va_start(varg,values);for(;i<values;i++){int num=0;num=va_arg(varg,int);if(max<num)swap(&max,&num);}va_end(varg);return max;
}

这个函数在调用的时候是这样传参的:

my_max(n_values,x,y,z……);


下面我来解释一下函数可变参数用法原理
——————————————————————————

va_list定义了一个指针(即varg), 而在c语言中,函数调用时,参数是从右向左依次压入栈中的(每个函数在调用的时候都会形成一个帧栈结构),所以这个指针依次可以指向所有的函数,直至结束。知道了这个,就不难理解为什么可以依次遍历函数的参数了。

再来看va_start(),这个是获取函数可变参数里的第一个参数,从此处我们也可以想到,被调用函数的参数列表里,至少要有一个命名参数。如果 连一个命名参数也没有,那么就无法使用va_start()了 。

最后一定要记得va_end(),来关闭这个指针。

在应用可变参数的时候还要注意这两个问题

——————————————————————————
1. 在调用函数时,要自己加上参数的数量,因为这些宏无法判断实际存在的参数的数量,如果你没加,那么编译器就会报错。
2. 一定要注意传进去参数的类型是否符合你所想要的,因为这些宏无法自己判断每个参数的类型,结果是不可预知的。

C语言_函数可变参数列表相关推荐

  1. c语言中的函数可变参数列表相关的三个宏

    在stdarg.h头文件中声明了一个类型va_list和3个与函数可变参数列表有关的宏:va_start.va_arg.va_end. #include<stdarg.h> //包含宏相关 ...

  2. c语言理解参数,c语言中对可变参数列表的简单理解

    函数原型中一般情况下参数的数目是固定的,但是如果想在不同的时候接收不定数目的参数时该怎么办呢?c语言提供了可变参数列表来实现. 可变参数列表是通过宏来实现的,这些宏定义在stdarg.h的头文件中.头 ...

  3. python 函数参数列表_Python 函数可变参数列表*args和**kwargs

    许多语言都支持可变参数列表,python也不例外.python的可变参数列表有点不太一样,有两种类型的可变参数列表,一种是元组,一种是字典. 一,元组参数列表: (1)函数定义形式:def func( ...

  4. php函数可变参数列表,PHP函数可变参数列表的具体实现方法介绍

    也许对于PHP初级程序员来说,对于PHP函数并不能完全熟练的掌握.我们今天为大家介绍的PHP函数可变参数列表的实现方法主要是利用func_get_args(). func_num_args().fun ...

  5. C语言中函数的参数列表为空和void的区别

    C标准和C++标准在main函数上是有区别的,所以我分别详细来介绍他们. 对于C语言: C89标准的main()函数是可接受的,尽管现在建议是使用C99的标准.C99标准只定义了如下两种可接受的函数原 ...

  6. 【C/C++开发】C语言实现函数可变参数

    函数原型: int printf(const char *format[,argument]...)        返 回 值: 成功则返回实际输出的字符数,失败返回-1.  函数说明:        ...

  7. C语言中函数可变参数解析

    大多数时候,函数中形式参数的数目通常是确定的,在调用时要依次给出与形式参数对应的所有实际参数.但在某些情况下希望函数的参数个数可以根据需要确定.典型的例子有 大家熟悉的函数printf().scanf ...

  8. c++函数可变参数列表foo(int a, ...){}中的省略号“...”

    int add(int num,...) /*求和函数*/ {va_list args;int sum=0;va_start(args,num);for(int i=0;i<num;i++)su ...

  9. 编写可变参数函数 c语言,C语言中编写可变参数函数

    通过stdarg.h头文件为函数提供了定义可变参数列表的能力.声明一个可变参数的函数类似: void f1(int n,...); 其中n表示参数列表个数,而用省略号来表示未知参数列表.stdarg. ...

最新文章

  1. mailx(mail)配置outlook SMTP方式发送邮件
  2. moco 搭建接口mock环境入门
  3. 倒计时 2 天 | 解锁生鲜电商的战“疫”秘密
  4. Homebrew软件包管理器中发现RCE漏洞,小心你的Mac和Linux
  5. pyqt5 qlabel无法显示图片_实战PyQt5: 011-单选框控件QRadioButton
  6. BootStrap 用法
  7. 重磅!教育部撤销518个高校专业
  8. requests与bs4编码
  9. python实现客户端之间的通信_基于Python的服务端多线程与多客户端的通信过程
  10. 分享一个Xshell注册码
  11. wdr7660虚拟服务器设置,TP-Link TL-WDR7660无线桥接怎么设置?
  12. 6.1色彩的概念和对比和调和
  13. 通过路由器端口映射实现外网IP访问内网服务器
  14. web3js开发技术
  15. Deep Learning Hierarchical Representations for Image Steganalysis【Ye-Net:图像隐写分析的深度学习层次表示】
  16. Airflow Timezone
  17. 抖音电子画册教程html,抖音爆火文字视频制作教程
  18. Windows下安装Nexus私服及更新索引
  19. 1NF | 2NF | 3NF的区分以及什么是函数依赖、部分函数依赖、值传递依赖(最详细的讲解1NF、2NF、3NF的关系)
  20. 阿里资深HR和你聊聊技术面试

热门文章

  1. 2020年书法落款_2020鼠年书法落款怎么写?
  2. 【车辆计数】基于matlab GUI背景差分法道路行驶多车辆检测【含Matlab源码 1911期】
  3. UICC 之 USIM 详解全系列——USIM鉴权函数说明以及鉴权向量结构
  4. AirtestIDE1.2.13的安卓手机设置自动初始化功能
  5. 微信直播应该如何引流呢
  6. c语言循环卖n西瓜 几天卖完,C++循环结构23道题含答案.docx
  7. 易支付程序对接固码支付
  8. 2017第17届CBME中国孕婴童展、童装展会刊(参展商名录)
  9. 邓凡平WIFI学习笔记4:WiFi Simple configuration
  10. 百度传课-php2小时超音速入门