精华内容
下载资源
问答
  • PAGE / NUMPAGES C语言参数个数可变函数浅析 VA函数variable argument function参数个数可变函数又称可变参数函数C/C++编程中系统提供给编程人员的va函数很少*printf)/*scanf)系列函数用于输入输出时格式化字符串...
  • VA函数(variable argument function),参数个数可变函数,又称可变参数函数。C/C++编程中,系统提供给编程人员的va函数很少。*printf()/*scanf()系列函数,用于输入输出时格式化字符串;exec*()系列函数,用于在...
  • 参数个数可变的函数(有点意思) 宏 va_start va_arg va_end //求任意个数的平均数 #include #include int average(int a,int b,...) { va_list parg; int sum = a + b; int value = 0; ...
    参数个数可变的函数(有点意思)



    va_start
    va_arg
    va_end


    //求任意个数的平均数
    #include<stdio.h>
    #include<stdarg.h>


    int average(int a,int b,...)
    {
    va_list parg;
    int sum = a + b;
    int value = 0;
    int count = 2;


    va_start(parg,b);   //从b之后的参数开始开始


    while ((value = va_arg(parg, int))!= -1)  //当指针移到参数-1时终止循环
    {
    printf("%d\n", value);
    sum += value;
    count++;
    }


    va_end(parg);
    return sum / count;
    }


    int main(void)
    {
    printf("%d\n", average(1,2,3,-1));
    return 0;
    }
    展开全文
  • 本文介绍一种用C语言实现参数个数可变的函数,感兴趣的朋友可以看看。
  • C语言可变参数个数

    2018-10-18 16:26:00
    宏里定义可变参数 https://blog.csdn.net/skyflying2012/article/details/38436711 GNU #define pr_debug(fmt,arg...) printk(KERN_DEBUG fmt, ##arg)   C99 #define dgbmsg(fmt,...) printf(fmt,__...

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

    void test(const char * format, ...);

    int main(void)
    {
    test("%d_%s", 6, "abc");
    return 0;
    }

    void test(const char * format, ...)
    {
    char buf[4069];
    va_list list;
    va_start(list, format);
    vsnprintf(buf, 4069, format, list);
    va_end(list);
    printf("%s\n", buf);
    }

     

    宏里定义可变参数

    https://blog.csdn.net/skyflying2012/article/details/38436711

    GNU

    #define pr_debug(fmt,arg...) printk(KERN_DEBUG fmt, ##arg)

     
    C99
    #define dgbmsg(fmt,...)     printf(fmt,__VA_ARGS__)

    转载于:https://www.cnblogs.com/mingzhang/p/9811310.html

    展开全文
  • VA函数(variable argument function),参数个数可变函数,又称可变参数函数。C/C++编程中,系统提供给编程人员的va函数很少。*printf()/*scanf()系列函数,用于输入输出时格式化字符串;exec*()系列函数...

    深入浅出可变参数函数的使用技巧本文主要介绍可变参数的函数使用,然后分析它的原理,程序员自己如何对它们实
    现和封装,最后是可能会出现的问题和避免措施。

    VA函数(variable argument function),参数个数可变函数,又称可变参数函数
    。C/C++编程中,系统提供给编程人员的va函数很少。*printf()/*scanf()系列函数
    ,用于输入输出时格式化字符串;exec*()系列函数,用于在程序中执行外部文件(
    main(int argc,char*argv[]算不算呢,与其说main()也是一个可变参数函数,倒不
    如说它是exec*()经过封装后的具备特殊功能和意义的函数,至少在原理这一级上有
    很多相似之处)。由于参数个数的不确定,使va函数具有很大的灵活性,易用性,对
    没有使用过可变参数函数的编程人员很有诱惑力;那么,该如何编写自己的va函数
    ,va函数的运用时机、编译实现又是如何。作者借本文谈谈自己关于va函数的一些
    浅见。

    一、 从printf()开始

    从大家都很熟悉的格式化字符串函数开始介绍可变参数函数。

    原型:int printf(const char * format, ...);

    参数format表示如何来格式字符串的指令,…

    表示可选参数,调用时传递给"..."的参数可有可无,根据实际情况而定。

    系统提供了vprintf系列格式化字符串的函数,用于编程人员封装自己的I/O函数。


    int vprintf / vscanf(const char * format, va_list ap); // 从标准输入/输出
    格式化字符串

    int vfprintf / vfsacanf(FILE * stream, const char * format, va_list ap);
    // 从文件流

    int vsprintf / vsscanf(char * s, const char * format, va_list ap); // 从
    字符串

    // 例1:格式化到一个文件流,可用于日志文件

    FILE *logfile;

    int WriteLog(const char * format, ...)

    {

    va_list arg_ptr;

    va_start(arg_ptr, format);

    int nWrittenBytes = vfprintf(logfile, format, arg_ptr);

    va_end(arg_ptr);

    return nWrittenBytes;

    }

    // 调用时,与使用printf()没有区别。

    WriteLog("%04d-%02d-%02d %02d:%02d:%02d  %s/%04d logged out.",

    nYear, nMonth, nDay, nHour, nMinute, szUserName, nUserID);

     

    同理,也可以从文件中执行格式化输入;或者对标准输入输出,字符串执行格式化

    在上面的例1中,WriteLog()函数可以接受参数个数可变的输入,本质上,它的实现
    需要vprintf()的支持。如何真正实现属于自己的可变参数函数,包括控制每一个传
    入的可选参数。

    二、 va函数的定义和va宏

    C语言支持va函数,作为C语言的扩展--C++同样支持va函数,但在C++中并不推荐使
    用,C++引入的多态性同样可以实现参数个数可变的函数。不过,C++的重载功能毕
    竟只能是有限多个可以预见的参数个数。比较而言,C中的va函数则可以定义无穷多
    个相当于C++的重载函数,这方面C++是无能为力的。va函数的优势表现在使用的方
    便性和易用性上,可以使代码更简洁。C编译器为了统一在不同的硬件架构、硬件平
    台上的实现,和增加代码的可移植性,提供了一系列宏来屏蔽硬件环境不同带来的
    差异。

    ANSI C标准下,va的宏定义在stdarg.h中,它们有:va_list,va_start(),va_ar
    g(),va_end()。

    // 例2:求任意个自然数的平方和:

    int SqSum(int n1, ...)

    {

    va_list arg_ptr;

    int nSqSum = 0, n = n1;

    va_start(arg_ptr, n1);

    while (n > 0)

    {

        nSqSum += (n * n);

        n = va_arg(arg_ptr, int);

    }

    va_end(arg_ptr);

    return nSqSum;

    }

    // 调用时

    int nSqSum = SqSum(7, 2, 7, 11, -1);

     

    可变参数函数的原型声明格式为:

    type VAFunction(type arg1, type arg2, … );

    参数可以分为两部分:个数确定的固定参数和个数可变的可选参数。函数至少需要
    一个固定参数,固定参数的声明和普通函数一样;可选参数由于个数不确定,声明
    时用"…"表示。固定参数和可选参数公同构成一个函数的参数列表。

    借助上面这个简单的例2,来看看各个va_xxx的作用。

    va_list arg_ptr:定义一个指向个数可变的参数列表指针;

    va_start(arg_ptr, argN):使参数列表指针arg_ptr指向函数参数列表中的第一个
    可选参数,说明:argN是位于第一个可选参数之前的固定参数,(或者说,最后一
    个固定参数;…之前的一个参数),函数参数列表中参数在内存中的顺序与函数声
    明时的顺序是一致的。如果有一va函数的声明是void va_test(char a, char b, c
    har c, …),则它的固定参数依次是a,b,c,最后一个固定参数argN为c,因此就是
    va_start(arg_ptr, c)。

    va_arg(arg_ptr, type):返回参数列表中指针arg_ptr所指的参数,返回类型为ty
    pe,并使指针arg_ptr指向参数列表中下一个参数。

    va_copy(dest, src):dest,src的类型都是va_list,va_copy()用于复制参数列表
    指针,将dest初始化为src。

    va_end(arg_ptr):清空参数列表,并置参数指针arg_ptr无效。说明:指针arg_pt
    r被置无效后,可以通过调用va_start()、va_copy()恢复arg_ptr。每次调用va_st
    art() / va_copy()后,必须得有相应的va_end()与之匹配。参数指针可以在参数列
    表中随意地来回移动,但必须在va_start() … va_end()之内。

    转载于:https://www.cnblogs.com/doudongchun/p/3699669.html

    展开全文
  • C语言没有像C++中函数重载功能,对于不确定参数个数的函数,需要通过va_list实现参数的提取。 一、概念 va_list 是在C语言中解决变参问题的一组宏,所在头文件: #include <stdarg.h> 1)va_list在头文件中的...

    C语言处理不确定个数参数

    C语言没有像C++中函数重载功能,对于不确定参数个数的函数,需要通过va_list实现参数的提取。

    一、概念

    va_list 是在C语言中解决变参问题的一组宏,所在头文件:

    #include <stdarg.h>
    

    1)va_list在头文件中的定义为:

    #ifdef  _M_ALPHA
    typedef struct {
            char *a0;       /* pointer to first homed integer argument */
            int offset;     /* byte offset of next parameter */
    } va_list;
    #else
    typedef char *  va_list;
    #endif
    

    2)_INTSIZEOF 宏,获取类型占用的空间长度,最小占用长度为int的整数倍:

    #define _INTSIZEOF(n)   ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
    

    3)VA_START宏,获取可变参数列表的第一个参数的地址(ap是类型为va_list的指针,v是可变参数最左边的参数):

    #define va_start(ap,v)  ( ap = (va_list)&v + _INTSIZEOF(v) )
    

    4)VA_ARG宏,获取可变参数的当前参数,返回指定类型并将指针指向下一参数(t参数描述了当前参数的类型):

    #define va_arg(ap,t)    ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
    

    5)VA_END宏,清空va_list可变参数列表:

    #define va_end(ap)      ( ap = (va_list)0 )
    

    二、代码例程

    int MyFuncExe(const int argc, ...)
    {
    	int nRtn = 0;
    	int args1, args2, args3, args4;
    	va_list args;
    	
    	va_start(args, argc);
    	if (0 == argc)
    	{
    		//to do
    	}
    	else if (1 == argc)
    	{
    		args1 = va_arg(args, int);
    		printf("args1:%d\n", args1);
    		//to do
    	}
    	else if (2 == argc)
    	{
    		args1 = va_arg(args, int);
    		printf("args1:%d\n", args1);
    		args2 = va_arg(args, int);
    		printf("args2:%d\n", args2);
    		//to do
    	}
    	else if (3 == argc)
    	{
    		args1 = va_arg(args, int);
    		printf("args1:%d\n", args1);
    		args2 = va_arg(args, int);
    		printf("args2:%d\n", args2);
    		args3 = va_arg(args, int);
    		printf("args3:%d\n", args3);
    		//to do
    	}
    	else if (4 == argc)
    	{
    		args1 = va_arg(args, int);
    		printf("args1:%d\n", args1);
    		args2 = va_arg(args, int);
    		printf("args2:%d\n", args2);
    		args3 = va_arg(args, int);
    		printf("args3:%d\n", args3);
    		args4 = va_arg(args, int);
    		printf("args4:%d\n", args4);
    		//to do
    	}
    	va_end(args);
    	return nRtn;
    }
    

    va_list args,定义了一个指针args,用于指示可选的参数;
    va_start(args, argc),初始化args,使参数列表指针args指向函数参数列表中的第一个可选参数,argc是位于第一个可选参数之前的固定参数,或者说最后一个固定参数;
    va_arg(args, int),返回参数列表中指针args所指的参数,返回类型为int,并使指针args指向参数列表中下一个参数,依次调用VA_ARG获取各个参数;
    va_end(args),清空参数列表, 并置参数指针args无效。

    假设以如下方式调用MyFuncExe:

    RegFuncExe(byParaCnt, 1, 2, 3, 4);
    

    byParaCnt为参数个数,后面的1,2,3,4是可选参数。

    三、注意事项

    使用VA_LIST应该注意的问题:
    (1)可变参数的类型和个数完全由程序代码控制,它并不能智能地识别不同参数的个数和类型;
    (2)如果我们不需要一一详解每个参数,只需要将可变列表拷贝至某个缓冲,可用vsprintf函数;
    (3)因为编译器对可变参数的函数的原型检查不够严格,对编程查错不利,不利于我们写出高质量的代码;
    (4)va_arg(ap,type)中的type绝对不能为以下类型:
    ——char、signed char、unsigned char
    ——short、unsigned short
    ——signed short、short int、signed short int、unsigned short int
    ——float
    在C语言中,调用一个不带原型声明的函数时,调用者会对每个参数执行“默认实际参数提升”,对可变长参数列表超出最后一个有类型声明的形式参数之后的每一个实际参数,也将执行上述提升工作。
    提升工作如下:
    ——float类型的实际参数将提升到double
    ——char、short和相应的signed、unsigned类型的实际参数提升到int
    ——如果int不能存储原值,则提升到unsigned int

    参考:

    1. va_list 详解
    2. 关于va_arg中的type
    3. C语言不定长参数实现方式
    展开全文
  • 如何在c语言中实现参数个数不确定的函数如何在C语言中实现参数个数不确定的函数?C 语言中有一种长度不确定的参数,形如:"...",它主要用在参数个数不确定的函数中,我们最容易想到的例子是 printf 函数。(注意:在 ...
  • C语言可变参数个数的函数学习

    千次阅读 2017-12-28 16:07:43
    C语言可变参数个数的函数学习 一、学习测试C代码 #include #include void fixed_args_func(int a, double b, char *c,int d) { printf("a = 0x%p\n", &a); printf("b = 0x%p\n", &b); printf
  • C语言中实现参数个数不确定的函数

    千次阅读 2016-09-30 10:53:21
    C语言中有一种长度不确定的参数,形如:"…",它主要用在参数个数不确定的函数中,我们最容易想到的例子是printf函数。(注意:在C++中有函数重载(overload)可以用来区别不同函数参数的调用,但它还是不能表示任意...
  • 在学习使用C语言的时候都会告知main函数是可以接入多个参数的,那么问题来了,不定参数个数的函数如何定义的呢,它是否可以在单片机中使用呢 定义和使用 //首先引用 #include <stdarg.h> //定义,count是...
  • C语言中实现参数个数可变函数

    千次阅读 2017-03-22 00:22:55
    其实,我总觉得有结论应该...正是如此,很多时候考虑诸如XXX是否可以用C语言实现的时候,应该无需考虑就能够给出一肯定的答复。  关于参数可变的函数的实现其实还不是这种情况,但是让我想到的是“是否能够实现参
  • c语言在写函数时,如果不确定要输入多少参数,标准库提供了一种方式输入任意长度参数。 二、使用方法 1、添加头文件:#include <stdarg.h> 2、定义:参数上面用“…”代表任意个参数,省略号之前的那个参数是 ...
  • stdarg.h提供了三宏,书写可变参数函数可以用到 void va_start(va_list ap, last); type va_arg(va_list ap, type); void va_end(va_list ap);   上面宏的前缀va表示variable argument,即可变参数的意思。变量ap...
  • 最近的内容相对变得复杂点了,希望大家在看的时候可以将代码和文字相结合。重在理解概念,程序很简单。主要是学习理解一些概念性的东西~~~...小括号里的整体叫做形式参数列表每形式参数的类型名称都不可以省略,不...
  • C语言中不定参数个数的函数

    千次阅读 2013-09-24 19:20:57
    C++中有函数重载这种方法,以供我们调用时要可以不确定实参的个数,其实C语言也可以,而且更高明! 我们在stdio.h中可以看到printf()函数的原型: int printf(char * format,...) 事实上,我们如果要写这样的函数也...
  • 参考文档一:采用C语言编程的时候...但在某些情况下希望函数的参数个数可以根据需要确定。典型的例子有大家熟悉的函数printf()、scanf()和系统调用execl()等。那么它们是怎样实现的呢? C编译器通常提供了一系列处理这
  • 以前一直不知道原来C语言也有参数个数可变的函数。 1、采用ANSI标准形式时,参数个数可变的函数的原型声明是: type funcname(type para1, type para2, ...) ---- 这种形式至少需要一个普通的形式参数,后面的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,855
精华内容 1,542
关键字:

c语言参数个数

c语言 订阅