函数可变参数列表的应用和原理(初稿)

来源:互联网 发布:centos 管理员登录 编辑:程序博客网 时间:2024/04/19 11:45

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

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

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

#include<stdio.h>#include<windows.h>int my_max(int x,int y,int z){    int max=0;    if(x>y)        max=x;    else        max=y;    if(max>z)        return max;    else        return 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语言中,函数调用时,参数是从右向左依次压入栈中的(这部分内容我另一篇关于c语言堆栈的介绍,里面会详细讲到),所以这个指针依次可以指向所有的函数,直至结束。知道了这个,就不难理解为什么可以依次遍历函数的参数了。

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

最后再调用va_end(),来关闭这个指针。

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

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

原创粉丝点击