前言
c语言的函数没有重载,可以使用两种方式实现重载功能
1.宏定义
2.可变参数表,使用stdarg.h头文件
本文介绍可变参数表的使用
一、stdarg.h中宏定义说明
通过stdarg.h中的4个宏定义实现可变长参数
1. va_list
类型 :类型宏
说明:可变参数列表的指针类型
2. va_start
类型: 函数宏
说明 : 初始化变量参数列表,即将可变参数列表,初始化到ap中
原型 :void va_start(va_list ap, last_arg)
参数 : va_list ap 传入的可变参数列表的指针变量。
last_arg 传入最后一个固定参数。
3. va_arg
类型: 函数宏
说明 : 检索函数参数列表中类型为 type 的下一个参数
原型 :type va_arg(va_list ap, type)
参数 :va_list ap 传入的可变参数列表的指针变量。
type 获取的参数类型
4. va_end
类型: 函数宏
说明 : 允许使用了 va_start 宏的带有可变参数的函数返回。如果在从函数返回之前没有调用 va_end,则结果为未定义,其实就是回收参数列表,最多的清理工作
原型 :void va_end(va_list ap)
参数 : va_list ap 传入的可变参数列表的指针变量。
二、简单示例
此函数,为求和函数,参数可以输入任意个数。
#include <stdio.h>
#include <stdarg.h>
/* 可变参数个数的求和函数 */
int sum(int count,...){
va_list args; /*va_list 类型为 可变参数列表的指针 */
int result=0;
int i;
va_start(args,count); /*将形参中的可变参数初始化到args中*/
i=0;
for(i=0;i<count;i++){
int num=va_arg(args,int);/*每次循环都从args中获取一个int型的数值*/
result+=num;
}
va_end(args); /*结束时清理工作*/
return result;
}
int main()
{
int result=sum(4,2,2,3,4); /*输入4个参数,其中第一个参数为固定参数(必须输入),其他参数任意输入*/
printf("4个数字求和: %d\n",result);
result=sum(5,2,2,3,4,3,6); /*输入6个参数*/
printf("6个数字求和: %d\n",result);
getchar();
return 0;
}
运行结果:
三. 经典示例
此示例出自于K&R的《c程序设计语言》第二版
编写mini版的打印函数,只可以 %d、%f、%s三种格式输出,参数个数可以任意的修改。此例子只是为了说明可变参数的使用,不是真正的printf函数。
#include <stdio.h>
#include <stdarg.h>
void minprintf(char *fmt,...);
int main(){
minprintf("打印参数:%d\n",100); /* 打印一个参数 */
int a1=100,a2=200;
minprintf("打印参数1:%d; 打印参数2:%d",a1,a2); /* 打印两个参数 */
getchar();
return 0;
}
/*带有可变参数表的简化printf函数,只可以 %d、%f、%s三种格式输出*/
void minprintf(char * fmt,...){
va_list ap; /* 依次指向每个无名参数 */
char * p,*sval;
int ival;
double dval;
va_start(ap,fmt); /*将ap指向第一个无名参数 va_start(va_list ap, last_arg),第一个参数为指向无名参数,第二个为最后一个固定参数*/
for(p=fmt;*p;p++){
if(*p!='%'){ /*只要不是 %,这跳过本次循环,进行下一次循环,直到找到下一个%*/
putchar(*p);
continue;
}
switch(*++p){
case 'd' :
ival=va_arg(ap,int);
printf("%d",ival);
break;
case 'f':
dval=va_arg(ap,double);
printf("%f",dval);
break;
case 's':
for(sval=va_arg(ap,char* );*sval;sval++)
putchar(*sval);
break;
default:
putchar(*p);
break;
}
}
va_end(ap); /*结束时的清理工作*/
}
运行结果:
总结
一般只要看到第一个示例就可以了。第二个示例,是出自于祖师爷编写的书籍,如果研究一下,可以加深理解