printf()函数的参数个数是不确定的,C语言是怎样去实现的。
看一个简单的例子:
- 1 #include<stdio.h>
- 2 #include<string.h>
- 3 #include<stdarg.h>
- 4
- 5 /*ANSI的标准声明方式,括号内的省略号表示可选参数*/
- 6 int func(char *msg,...)
- 7 {
- 8 va_list argp; /*定义保存函数参数的可选参数*/
- 9 int argno = 1; /*记录参数个数*/
- 10 char *para; /*存放取出字符串参数*/
- 11 printf("msg地址:%x\n\n",msg);
- 12
- 13 /*argp指向传入的第一个参数。 */
- 14 va_start(argp,msg);
- 15
- 16 while(1){
- 17 para = va_arg(argp,char *);
- 18
- 19 if(strcmp(para,"\0") == 0) break;
- 20 printf("第%d个参数是: %s\n",argno, para);
- 21 printf("address:%x\n\n",para);
- 22 argno++;
- 23 }
- 24 va_end(argp);
- 25 return 0;
- 26 }
- 27
- 28
- 29 main()
- 30 {
- 31 func("111","1","22","333","4444","55555","666666","\0");
- 32
- 33 func("11","22","\0");
- 34 }
上面的func()函数能接受参数个数不同,其实现用到了几个宏 :
- typedef char * va_list;
- #define _INTSIZEOF(n) ((sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1)
- #define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )
- #define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
- #define va_end(ap) ( ap = (va_list)0 )
_INTSIZEOF(n) 是用来实现内存对齐的。
va_start(ap,v) v是函数的最后一个固定参数,该宏的作用是让ap指向第一个可变参数。
va_arg(ap,t) t为接收类型,这个宏实现两个功能
1. 返回当前ap,上面例子是用parp接收。
2. ap指向下一个参数
va_end(ap) 是ap 指向 NULL
上面的不定参数的实现是用到传参数确定了参数的个数,就如同函数参数最后用到 "\0" 开确定参数的个数。
这就需要在确定函数接口的时候编写者自己定义。
阅读(1524) | 评论(0) | 转发(0) |