C------可变参数
1. 概念
常用如printf函数:
它的参数并不是固定个数的,而在调用时根据情况确定
2. C中的实现
用到了 <stdarg.h>
va_list:每次指向一个可变的参数
va_start:初始化va_list变量,使其指向第一个可变参数
va_arg:返回一个可变长参数的值并使va_list变量指向下一个参数
va_end:清理
3. 书上的两个简单例子
(1)
int print_arg(int nums,...);
nums是字符串个数,后面是不固定个数的字符串,以NULL结尾
1 int print_arg(int nums,...) 2 { 3 va_list ap; 4 char *p; 5 int n = 0; 6 va_start(ap,nums); 7 printf("there is %d args\n",nums); 8 p = va_arg(ap,char *); 9 while(NULL != p) { 10 ++n; 11 printf("arg %d:%s\n",n,p); 12 p = va_arg(ap,char *); //获取下一个字符串 13 } 14 va_end(ap); 15 return n; 16 }
(2)printf的简单实现
这里只处理 %%、%d、%lf、%s这些
#include <stdio.h> #include <stdarg.h> #include <string.h> int my_printf(const char *format,...) { va_list ap; char c,ch; int i; char *p; double fi; char buf[64] = {0}; va_start(ap,format); c = *format; while('\0' != c) { if('%' == c) { ++format; c = *format; switch(c) { case 'c': ch = va_arg(ap,int); putchar(ch); break; case 'd': i = va_arg(ap,int); //printf("%d",i); memset(buf,0,sizeof(buf)); sprintf(buf,"%d",i); //不用puts,因为puts会在最后自动添加一个换行符 fputs(buf,stdout); break; case 'f': fi = va_arg(ap,double); //printf("%lf",fi); memset(buf,0,sizeof(buf)); sprintf(buf,"%lf",fi); //不用puts,因为puts会在最后自动添加一个换行符 fputs(buf,stdout); break; case 's': p = va_arg(ap,char *); fputs(p,stdout); break; case '%': putchar('%'); break; default: va_end(ap); return 0;//格式不对,执行失败 } } else { putchar(c); } c = *(++format); } va_end(ap); return 1; }
简单测试:
int n = my_printf("%%zyk%%zyk%%"); printf("\nn=%d\n",n); n = my_printf("%dzyk%fzyk%s",10,3.14,"abc"); printf("\nn=%d\n",n); n = my_printf("zyk"); printf("\nn=%d\n",n); n = my_printf("%zyk%"); printf("\nn=%d\n",n);