Chinaunix首页 | 论坛 | 博客
  • 博客访问: 62357
  • 博文数量: 12
  • 博客积分: 469
  • 博客等级: 二等列兵
  • 技术积分: 155
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-24 22:00
文章分类

全部博文(12)

文章存档

2014年(2)

2012年(10)

分类: LINUX

2012-10-26 15:49:10

printf()函数的参数个数是不确定的,C语言是怎样去实现的。

看一个简单的例子:

点击(此处)折叠或打开

  1. 1 #include<stdio.h>
  2.   2 #include<string.h>
  3.   3 #include<stdarg.h>
  4.   4
  5.   5 /*ANSI的标准声明方式,括号内的省略号表示可选参数*/
  6.   6 int func(char *msg,...)
  7.   7 {
  8.   8 va_list argp; /*定义保存函数参数的可选参数*/
  9.   9 int argno = 1; /*记录参数个数*/
  10.  10 char *para; /*存放取出字符串参数*/
  11.  11 printf("msg地址:%x\n\n",msg);
  12.  12
  13.  13 /*argp指向传入的第一个参数。 */
  14.  14 va_start(argp,msg);
  15.  15
  16.  16 while(1){
  17.  17 para = va_arg(argp,char *);
  18.  18
  19.  19 if(strcmp(para,"\0") == 0) break;
  20.  20 printf("第%d个参数是: %s\n",argno, para);
  21.  21 printf("address:%x\n\n",para);
  22.  22 argno++;
  23.  23 }
  24.  24 va_end(argp);
  25.  25 return 0;
  26.  26 }
  27.  27
  28.  28
  29.  29 main()
  30.  30 {
  31.  31 func("111","1","22","333","4444","55555","666666","\0");
  32.  32
  33.  33 func("11","22","\0");
  34.  34 }


上面的func()函数能接受参数个数不同,其实现用到了几个宏 :

点击(此处)折叠或打开

  1. typedef char * va_list;

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

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

  4. #define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
  5. #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" 开确定参数的个数。
这就需要在确定函数接口的时候编写者自己定义。


 






阅读(1476) | 评论(0) | 转发(0) |
0

上一篇:通用文件模型

下一篇:内存对齐

给主人留下些什么吧!~~