不定参数函数
stdarg.h是C语言中C标准函数库的头文件,stdarg是由stdandard(标准) arguments(参数)简化而来,主要目的为让函数能够接收不定量参数。 C++的cstdarg头文件中也提供这样的机能;虽然与C的头文件是兼容的,但是也有冲突存在。
不定参数函数(Variadic functions)是stdarg.h内容典型的应用,虽然也可以使用在其他由不定参数函数调用的函数(例如,vprintf)。
声明不定参数函数
不定参数函数的参数数量是可变动的,它使用省略号来忽略之后的参数。例如printf函数一般。代表性的声明为:
int check(int a, double b, ...);
不定参数函数最少要有一个命名的参数,所以
char *wrong(...);
在C是不被允许的(在C++中,这样的声明是合理的)。在C,省略符号之前必须要有逗号;在C++,则没有这种强制要求。
定义不定参数函数
使用相同的语法来定义:
long func(char, double, int, ...);
long func(char a, double b, int c, ...)
{
/* ... */
}
在旧形式可能会出现较省略的函数定义:
long func();
long func(a, b, c, ...)
char a;
double b;
{
/* ... */
}
访问参数
访问未命名的参数,首先必须在不定参数函数中声明va_list型态的变数。调用va_start并传入两个参数:第一个参数为va_list型态的变数,第二个为函数最后一个参数的名称,接着每一调用va_arg就会回传下一个参数,va_arg的第一个参数为va_list,第二个参数为回传的型态。最后va_end必须在函数回传前被va_list呼叫(當作參數)。(沒有要求要讀取完所有參數)
C99提供額外的巨集,va_copy,它能够复制va_list。而va_copy(va2, va1)意思为拷贝va1到va2。
没有机制定义该怎么判别传递到函数的参数量或者型态。函数通常需要知道或确定它们变化的方法。共通的惯例包含:
使用printf或scanf类的格式化字符串来嵌入明确指定的型态。
在不定参数最后的标兵值(sentinel value)。
总数变数来指明不定参数的数量.
类型安全性
有些C工具将C扩充允许编译器检查适当格式化字符串及标兵(sentinels)的使用。如果没有这个扩充,编译器通常无从检查传入函数的未命名参数是否为所预期的型态。因此,必须对点做出谨慎的正确性确认,型态没有吻合为未定义行为(Undefined behavior)。举个例,如果传入NULL指针,首先就是不能写入对应到适当指针型态但纯粹NULL的指针。再者考虑默认参数应用到未命名参数。float将会自动的被转换成double‧同样的比int(整数)更小容量的参数型态将会被转换成int或者unsigned int‧函数所接收到的未命名参数必须预期到会被转换型态。
例子
#include <stdarg.h>
#include <stdio.h>
int sum(int n,...)
{
int sum = 0;
va_list arg_ptr;
va_start(arg_ptr,n);
for(;n;--n)
{
sum = sum + va_arg(arg_ptr,int);
}
va_end(arg_ptr);
return sum;
}
int main(int argc,const char* argv[])
{
printf("sum: %i\n",sum(3,1,2,3));
return 0;
}
分享到:
相关推荐
一、前言 今天在看Thinking in C++这本书时,书中的一个例子引起了我的注意,具体是...C/C++中规定了函数参数的压栈顺序是从右至左,对于含有不定参数的printf函数,其原型是printf(const char* format,…);其中f
本文实例展示了C++可变参数的函数与模板的实现方法,有助于大家更好的理解可变参数的函数与模板的应用,具体...一、可变参数函数 1、initializer_list形参 如果函数的实参数量未知但是全部实参的类型都相同,我们可以
不定参数在C语言中的应用实例:不定参数当年做为C/C++语言一个特长被很多人推崇,但是实际上这种技术并没有应用很多。除了格式化输出之外,我实在没看到多少应用。主要原因是这种技术比较麻烦,副作用也比较多,而...
由于在C语言中没有函数重载,解决不定数目函数参数问题变得比较麻烦,即使采用C++,如果参数个数不能确定,也很难采用函数重载。对这种情况,提出了指针参数来解决问题。 如printf()函数,其原型为:int printf( ...
变长参数的函数,即参数个数可变、参数类型不定的函数。设计一个参数个数可变、参数类型不定的函数是可能的,最常见的例子是printf函数、scanf函数和高级语言的Format函数。最近的一个项目中就遇到这么一个相关的...
43.c //结构体函数 44.c //结构体二维数组 45.c //学生信息管理系统 46.c //结构体函数 47.c //二维数组转一维 48.c //if(1?i>j:i) 49.c //冒泡排序的运用 50.c //指针递归输出逆序数组 xiaoxiaoran2 //c++经典程序 ...
不定参数在C语言中的应用实例:不定参数当年做为C/C++语言一个特长被很多人推崇,但是实际上这种技术并没有应用很多。除了格式化输出之外,我实在没看到多少应用。主要原因是这种技术比较麻烦,副作用也比较多,而...
不指定范围产生随机数用到函数rand(),函数原型为int rand(),无参数。此时会产生一个介于0~RAND_MAX间的整数。RAND_MAX的大小可以查看,在include文件夹(linux在usr目录、windows在安装目录)的stdlib.h可以看到...
php的基本语法和c/c++,java的差不多,只是php在定义变量时没有要显示声明变量类型,php对变量的...所以在函数中可以根据不同情况返回不同类型的值,以及可以向函数传入不定数量的参数,这一点像c/c++,java是做不到的
涉及到自定义类的构造函数、重载构造函数、函数默认值、析构函数、复制构造函数、重载运算符(赋值函数、加法函数)、虚函数、常值函数、...不定参数函数、友函数、友类、类型引用、终态函数、终态类、模板变量等内容...
这段程序是一个C语言的小技巧,其展示了如何把一个参数为结构体的函数转成一个可变参数的函数。
16.4.1 编写可变参数函数模板 620 16.4.2 包扩展 621 16.4.3 转发参数包 622 16.5 模板特例化 624 小结 630 术语表 630 第Ⅳ部分 高级主题 633 第17章 标准库特殊设施 635 17.1 tuple类型 636 ...
由于在C语言中没有函数重载,解决不定数目函数参数问题变得比较麻烦;即使采用C++,如果参数个数不能确定,也很难采用函数重载.对这种情况,有些人采用指针参数来解决问题。
16.4.1 编写可变参数函数模板 620 16.4.2 包扩展 621 16.4.3 转发参数包 622 16.5 模板特例化 624 小结 630 术语表 630 第Ⅳ部分 高级主题 633 第17章 标准库特殊设施 635 17.1 tuple类型 636 ...
5.2.7 接受数量不定的函数实参 229 5.3 从函数返回值 231 5.3.1 返回指针 231 5.3.2 返回引用 234 5.3.3 函数中的静态变量 236 5.4 递归函数调用 239 5.5 C++/CLI编程 241 5.5.1 接受数量可变实参的...
由于在C语言中没有函数重载,解决不定数目函数参数问题变得比较麻烦;即使采用C++,如果参数个数不能确定,也很难采用函数重载.对这种情况,有些人采用指针参数来解决问题.下面就c语言中处理不定参数数目的问题进行讨论
C++11版本特性(参数数量不定的模板)将参数进行分解,类似于递归的情况,每一个每一个·进进行打印,要函数出口...就是一个所谓的pack(包)nullptr用
如果搞不定自己电脑上的编程软件,我们也会提供在网页中编写、运行C语言程序的方法。 课程大纲 01 程序设计与C语言 课时 1 计算机和编程语言 2 C语言 3 第一个程序 02 计算 课时 1 变量 2 数据类型 3 表达式 4 ...
代码里用了备份dll的方法,因此在自定义的函数中可以直接调用在内存中备份的dll代码,而不需要再把函数头部改来改去。 IOCP反弹远控客户端模型,外加上线服务端,全部代码注释! 如题。这个是IOCP远程控制软件的...
答:对于复杂而开发时间紧的项目时,可以采用C语言,但前提是要求对该MCU系统的C语言和C编译器非常熟悉,特别要注意该C编译系统所能支持的数据类型和算法。虽然C语言是最普遍的一种高级语言,但不同的MCU厂家其...