娓娓道来c指针 (8)开发可变参数函数

(8)开发可变参数函数

在c语言中,可变参数的函数极其常见,如常用的printf()。可变参数函数的一般形式如下:

  1. 返回值类型 函数名(类型1 参数1,类型2 参数2,...类型n 参数n,...);  

如上所示,这是一个典型的可变参数样式,它共有n个确定的参数,最后的...表示可变参数的含义。必须指出...必须位于最后,并且它至少要有一个确定的参数,原因后面陈述。

为了开发可变参数的函数,需用到头文件stdarg.h。下面共给出两个实例,在实例中详细解释用法。一是求可变个整数的和;二是模仿printf函数。

实例一:求可变个整数的和

  1. #include<stdio.h>  
  2. #include<stdlib.h>  
  3. #include<stdarg.h>  
  4. /* 
  5. 对可变个参数求和 
  6. count是可变个参数的个数 
  7. */  
  8. int sum(int count, ...)  
  9. {  
  10.     int sum = 0;  
  11.     if (count > 0)  
  12.     {  
  13.         va_list pData;   //typedef char* va_list;  
  14.         va_start(pData, count);   //使pData指向count的下一个参数  
  15.         int i;  
  16.         for (i = 0; i < count; i++)  
  17.             sum += va_arg(pData, int);   //以int类型解析pData所指向的内存区域,解析之后,使pData指向下一个位置  
  18.         //va_end()与va_start()配套使用  
  19.         va_end(pData);  
  20.     }  
  21.     return sum;  
  22. }  
  23. int main()  
  24. {  
  25.     printf("%d\n", sum(5, 1, 2, 3, 4, 5));  
  26.     return 0;  
  27. }  

运行    15

在sum中共用到了va_list类型,va_start()、va_arg()和va_end()宏。

其中,va_list就是char*类型,故直接使用char*,也是可以的。但推荐使用va_list,这样更能表达含义。va_start()、va_arg()和va_end()都是在stdarg.h中定义的宏。va_start()的作用是使va_list型的变量指向第一个可变参数,故需要使用到离...最近的一个固定的确定的参数,这就是在设计可变参数函数时至少需要一个确定参数的原因。它的真实原因与函数的参数在内存中的分布有关:


显然,由最后一个参数的地址,可以确定第一个可变参数的地址。接着使用va_arg(pData, int),不断解析pData指向内存区域,且要指明用何种方式解析,这是va_arg()第二个参数的作用,解析完后,pData指向下一个可变参数的地址。由此即可得到所有的可变参数的值。


实例二,模拟printf()函数

  1. #include<stdio.h>  
  2. #include<stdlib.h>  
  3. #include<stdarg.h>  
  4. /* 
  5. 简单模拟printf()函数 
  6. format是输出格式字符串 
  7. */  
  8. int iprintf(char *format,...)  
  9. {  
  10.     //count统计输出数据个数  
  11.     int count;  
  12.     count = 0;  
  13.     va_list p;  
  14.     va_start(p, format);  
  15.     char ch;  
  16.     while (ch = format[count])  
  17.     {  
  18.         switch (ch)  
  19.         {  
  20.         case 'd':printf("%d\n", va_arg(p, int)); break;  
  21.         case 'f':printf("%f\n", va_arg(p, double)); break;  
  22.         case 's':puts(va_arg(p, char*)); break;  
  23.         }  
  24.         count++;  
  25.     }  
  26.     va_end(p);  
  27.     return count;  
  28. }  
  29. int main()  
  30. {  
  31.     int count = iprintf("sdf", "mvp", 4, 3.5);  
  32.     printf("共输出 %d 个数据\n", count);  
  33.     system("pause");  
  34.     return 0;  
  35. }  

运行



在上面的模拟printf()函数中我们实际上还是靠库函数printf()来实现输出,模拟的只是原理。


专栏目录


posted @ 2017-11-19 21:49  立体风  阅读(162)  评论(0编辑  收藏  举报