可变参数函数(二)

函数样例:

#include<stdio.h>
#include<stdlib.h>
#include<stdarg.h>

double add(int n,...)
{
    int i = 0;
    double sum = 0;
    va_list argptr;
    va_start(argptr,n);
    for(i = 0 ; i < n; i++)
    {
        double d =  va_arg(argptr,double);
        printf("%d argument is %.3f\n",i,d);  //获取第i个double型的可变参数
        sum += va_arg(argptr,double);
    }
    va_end(argptr);
    return sum;
}

int main(int argc,char **argv)
{
    double sum = 0;
    float *p = malloc(argc * sizeof(float));
    int i;
    for(i = 1; i < argc; i++)
    {
        p[i] = atof(argv[i]);
        //printf("p[%d] = %.3f\n",i,p[i]);
    }

    sum = add(1,p[1]);
    printf("sum = %.3f\n",sum);
    sum = add(2,p[1],p[2]);
    printf("sum = %.3f\n",sum);
    sum = add(3,p[1],p[2],p[3]);
    printf("sum = %.3f\n",sum);

    free(p);
    return 0;
}

运行结果:

[email protected]:~/wangqinghe/DeBug/20190702$ gcc sum.c -o sum

[email protected]:~/wangqinghe/DeBug/20190702$ ./sum 10 20 30

0 argument is 10.000

sum = 0.000

0 argument is 10.000

1 argument is 0.000

sum = 20.000

0 argument is 10.000

1 argument is 30.000

2 argument is 0.000

sum = 20.000

测试:double d =  va_arg(argptr,double);是否只提取可变参数列表中double类型的数据

#include<stdio.h>
#include<stdlib.h>
#include<stdarg.h>

double add(int n,...)
{
    int i = 0;
    double sum = 0;
    va_list argptr;
    va_start(argptr,n);
    for(i = 0 ; i < n; i++)
    {
        double d =  va_arg(argptr,double);
        printf("%d argument is %.3f\n",i,d);
        sum += va_arg(argptr,double);
    }
    va_end(argptr);
    return sum;
}

int main(int argc,char **argv)
{
    double sum = 0;
    float *p = malloc(argc * sizeof(float));
    int i;
    for(i = 1; i < argc; i++)
    {
        if(0 == i % 2)
        {
            p[i] = atof(argv[i]);
            printf("float : p[%d] = %.3f\n",i,p[i]);
        }
    }

    sum = add(1,p[1]);
    printf("sum = %.3f\n",sum);
    sum = add(2,p[1],p[2]);
    printf("sum = %.3f\n",sum);
    sum = add(3,p[1],p[2],p[3]);
    printf("sum = %.3f\n",sum);

    free(p);
    return 0;
}

运行结果:

[email protected]:~/wangqinghe/DeBug/20190702$ ./sum 10 20 30 40 50 60 70

float : p[2] = 20.000

float : p[4] = 40.000

float : p[6] = 60.000

0 argument is 0.000

sum = 0.000

0 argument is 0.000

1 argument is 0.000

sum = 20.000

0 argument is 0.000

1 argument is 0.000

2 argument is 0.000

sum = 20.000

结论:可变参数的输入类型要和使用的一致。(暂定)。


函数介绍:

va_list

这是一个适用于 va_start()、va_arg() 和 va_end() 这三个宏存储信息的类型。

一般情况下va_list所定义变量为字符指针,即typedef char *va_list

该类型的变量用于存储参数的地址。因为得到参数的地址之后,再结合参数的类型,才能得到参数的值。

va_start

宏原型是:

void va_start(va_list ap, last_arg)

参数:

ap是一个 va_list 类型的对象,它用来存储通过 va_arg 获取额外参数时所必需的信息。

last_arg是最后一个传递给函数的已知的固定参数。

该宏与 va_arg 和 va_end 宏是一起使用的,且必须在使用 va_arg 和 va_end 之前被调用。

va_arg

宏原型是:

type va_arg(va_list ap, type) 

其作用是从ap开始取一个type型的值返回,并且自动将ap指向下一个参数。所以如果参数类型写错了,例如将char*写成char了,本来要取4个字节,结果只取了一个字节,ap本来要向后面移动4个字节,结果只移动了一个字节,后面的数据就全错了。

参数:

ap是一个 va_list 类型的对象,存储了有关额外参数和检索状态的信息。该对象应在第一次调用 va_arg 之前通过调用 va_start 进行初始化。

type这是一个类型名称。该类型名称是作为扩展自该宏的表达式的类型来使用的。

返回值:该宏返回下一个额外的参数,是一个类型为 type 的表达式。

注意:

va_arg宏的第2个参数不能被指定为char、short或者float类型。

因为char和short类型的参数会被转换为int类型,而float类型的参数会被转换为double类型。如果错误的指定了,将会在程序中引起麻烦。

例如,这样写肯定是不对的:

c = va_arg(ap,char);

因为我们无法传递一个char类型参数,如果传递了,它将会被自动转化为int类型。上面的式子应该写成:

c = va_arg(ap,int);

va_end

宏原型为:

 void va_end(va_list ap) 

参数:

ap是之前由同一函数中的 va_start 初始化的 va_list 对象。

其作用是作用是将ap设置为NULL,如果在从函数返回之前没有调用 va_end,则结果为未定义。

总结

使用可变长参数的步骤:

1.声明va_list变量;

2.使用va_start指定可变长参数的位置;

3.使用va_arg来获取参数值;

4.可选,使用va_end将va_list清零。

参考原文:https://blog.csdn.net/hmxz2nn/article/details/80445770

原文地址:https://www.cnblogs.com/wanghao-boke/p/11121054.html

时间: 2024-10-31 13:09:51

可变参数函数(二)的相关文章

C语言可变参数函数实现原理

一.可变参数函数实现原理 C函数调用的栈结构: 可变参数函数的实现与函数调用的栈结构密切相关,正常情况下C的函数参数入栈规则为__stdcall, 它是从右到左的,即函数中的最右边的参数最先入栈. 本文地址:http://www.cnblogs.com/archimedes/p/variable-parameter.html,转载请注明源地址. 例如,对于函数: void fun(int a, int b, int c) { int d; ... } 其栈结构为 0x1ffc-->d 0x200

娓娓道来c指针 (8)开发可变参数函数

(8)开发可变参数函数 在c语言中,可变参数的函数极其常见,如常用的printf().可变参数函数的一般形式如下: 返回值类型 函数名(类型1 参数1,类型2 参数2,...类型n 参数n,...); 如上所示,这是一个典型的可变参数样式,它共有n个确定的参数,最后的...表示可变参数的含义.必须指出...必须位于最后,并且它至少要有一个确定的参数,原因后面陈述. 为了开发可变参数的函数,需用到头文件stdarg.h.下面共给出两个实例,在实例中详细解释用法.一是求可变个整数的和:二是模仿pri

C语言学习020:可变参数函数

顾名思义,可变参数函数就是参数数量可变的函数,即函数的参数数量是不确定的,比如方法getnumbertotal()我们即可以传递一个参数,也可以传递5个.6个参数 1 #include <stdio.h> 2 #include <stdarg.h>//实现可变参数需要的头文件 3 4 int getnumbertotal(int args,...){//可变参数要放在普通参数(args)的后面:...表示有很多个参数 5 va_list l;//用来保存传给函数的其他参数 6 va

【C语言天天练(四)】可变参数函数

可变参数函数指可以接受可变数量参数的函数.比如printf函数就是一个可变参数函数. 要完成可变参数函数的编写,需要用到定义于stdarg.h头文件中的一个类型va_list和三个宏va_start.va_arg.va_end. 注意: 1.可变参数必须从头到尾按照顺序逐个访问.如果在访问几个可变参数后想半途中止,这是可以的.但是,如果想一开始就访问列表中的参数,那是不行的. 2.由于参数列表中的可变参数部分并没有原型,所以,所有作为可变参数传递给函数的值都将执行缺省参数类型提升. 3.参数列表

【转】C/C++中可变参数函数的实现

转自:http://www.cnblogs.com/cylee025/archive/2011/05/23/2054792.html 在C语言的stdarg.h头文件中提供了三个函数va_start, va_end,va_arg和一个类型va_list.利用它们,我们可以很容易实现一个可变参数的函数.首先简单介绍一下这三个函数. 假设现在有一个名为f的函数,其函数定义为: void f(int a, int b, ...) 那么,在函数的内部,为了获得这些可变参数,就需要利用到va_start.

ios开发-Object-C可变参数函数

简介 一个可变参数函数是指一个函数拥有不定的参数,即为一个函数可接收多个参数.有时我们会遇到一些算术问题需要用到,比如是计算传入参数的总和,字符串的连接或是其它操作过程,我们在 OC 里也经常使用,最经典的就是 NSLog( C 为 printf ) ,它可以指定格式的输出,格式化输出的内容. 现在我们先来看看普通函数的定义方法. 普通函数 一般我们定义的函数都是指定有多少个参数,如果是有三个参数,我们可以这样写. - (void)exampleObj:(NSString *)obj obj2:

C++ 11 可变参数模板和 boost::any 实现可变参数函数

1 class SqlHelper 2 { 3 public: 4 template <typename... Params> 5 static bool preparedExecute(sql::PreparedStatement* pstmt, Params... parameters) 6 { 7 return doPreparedExecute(pstmt, 1, parameters...); 8 } 9 10 private: 11 template <typename...

可变参数函数详解

可变参数函数又称参数个数可变函数(本文也简称变参函数),即函数参数数目可变.原型声明格式为: type VarArgFunc(type FixedArg1, type FixedArg2, -); 其中,参数可分为两部分:数目确定的固定参数和数目可变的可选参数.函数至少需要一个固定参数,其声明与普通函数参数相同:可选参数由于数目不定(0个或以上),声明时用"-"表示("-"用作参数占位符).固定参数和可选参数共同构成可变参数函数的参数列表. 由于参数数目不定,使用可

C++ 定义和使用可变参数函数

1 #include<iostream> 2 using namespace std; 3 void PrintAll(int n,...){ 4 int *ptr; 5 ptr = &n; 6 while(*ptr){ 7 cout<<*ptr<<endl; 8 ptr++; 9 } 10 } 11 int main(){ 12 PrintAll(3,4,5,0); 13 } 14 输出: 15 3 16 4 17 5 1.可变参数函数的函数头书写形式:typ

C语言可变参数函数详解示例

先看代码 printf("hello,world!");其参数个数为1个. printf("a=%d,b=%s,c=%c",a,b,c);其参数个数为4个. 如何编写可变参数函数呢?我们首先来看看printf函数原型是如何定义的.在linux下,输入man 3 printf,可以看到prinf函数原型如下: SYNOPSIS #include <stdio.h> int printf(const char *format, ...); 后面的三个点...