C语言中可变形参简单实例和简单的printf功能的实例



C语言中可变形参简单实例和简单的printf功能的实例。

以下程序主要包括三个主要函数:

  • 一个最简单的可变形参函数实例;
  • 一个简单的printf功能的实例;
  • 一个打印字符串函数(辅助);

其中myPrintf函数,实现了printf的部分简单功能,并没有去实现格式化输出操作(%2d %.2f 等),

因为只是它一个实例而已,目的是更好理解掌握可变参数。

后续有兴趣时,我会继续完善的。

 

  1. /*******************************************************************************************************
  2. * 名  称: main.c
  3. * 功  能:C语言可变形参 variable arguments,典型案例是printf和scanf
  4.                 实现了一个简单的可变参数函数例子 ShowArgs
  5.                 实现了一个简单printf功能的函数 myPrintf
  6. * 描  述:可变参数的个数是不确定的
  7.                可变参数的类型是不确定的
  8.                printf和scanf在实现时,通过前面的%d %f 等获取可变参数的个数和类型
  9.                可变参数由定义在stdarg.h头文件中的宏:va_list va_start va_arg va_end等组成
  10.                va_list:用于保存参数列表
  11.                va_start(v,l):将参数列表的首地址 l 赋值给 v
  12.                va_arg(v,l):获取参数列表中类型为 l 的参数的值,并将参数列表指针向后移动到下一个参数处
  13.                va_end(v):结束可变参数
  14. * 作  者:JarvisChu
  15. * 时  间:2011-7-17 创建
  16. ********************************************************************************************************/
  17. #include <stdio.h>
  18. #include <stdarg.h>
  19. #include <string.h>
  20. //在此处选择函数
  21. //#define SHOW_ARGS
  22. //#define MY_PRINTF
  23. #define SHOW_STRING_BY_CHAR
  24. //一个简单的实例,num代表可变参数的个数,类型全部默认为double型
  25. void ShowArgs(int num,…){
  26.     int i=0;
  27.     double var;
  28.     va_list ls;
  29.     va_start (ls,num);          //获取可变参数列表的首地址,赋值给ls
  30.     printf(“———–%d个可变参数,如下:———-\n”,num);
  31.     while(i<num){
  32.         var = va_arg(ls,double);//返回类型为double的的可变参数值,并使ls指向下一个可变参数
  33.         printf(“参数%d:%f\n”,++i,var);
  34.     }
  35.     va_end(ls);                //结束
  36.     printf(“\n”);
  37. }
  38. //实现类似printf的部分功能,利用putchar向屏幕输出字符
  39. void myPrintf(char* str,…){
  40.     int i, len;
  41.    // int num = 0;       //num为可变参数个数
  42.     char pre,cur;        //前一个字符和当前的字符
  43.     va_list ls;
  44.     va_start(ls,str);
  45.     len = strlen(str);   //获取字符串长度
  46.     pre = ‘ ‘;           //初始化时,pre为空格(只要不是特殊字符或转义字符就行)
  47.     for(i=0;i<len;i++){
  48.         cur = str[i];
  49.         switch(pre){
  50.             case ‘%’:           //前一个字符值是%字符,我们就要考虑%d %f 这种情况了
  51.                 switch(cur){
  52.                     case ‘d’:    //%d,输出整数
  53.                         printf(“%d”,va_arg(ls,int));//将可变部分的int类型变量替代%d输出,本来很不想在这里用printf的,
  54.                         break;                      //但是没有想到其他的办法向屏幕输出一个整型,姑且用printf吧
  55.                     case ‘f’:    //%f,输出float double类型
  56.                         printf(“%f”,va_arg(ls,double));
  57.                         break;
  58.                     case ‘c’:   //%c,输出一个字符
  59.                         putchar(cur);
  60.                         break;
  61.                 }
  62.                 break;
  63.             default:             //前一个字符不是什么特殊字符
  64.                 if(cur != ‘%’){  //当前字符不是%
  65.                      putchar(cur);
  66.                 }
  67.                 break;
  68.         }
  69.         pre = cur;
  70.     }
  71.     va_end(ls);
  72. }
  73. //辅助函数:将一个字符串,一个字符一个字符的输出
  74. void ShowStringByChar(char* str){
  75.     int i, len;
  76.     char ch;
  77.     len = strlen(str);
  78.     for(i=0;i<len;i++){
  79.         ch = str[i];
  80.         putchar(ch);
  81.         printf(“\n—-\n”);
  82.     }
  83. }
  84. int main()
  85. {
  86. #ifdef SHOW_ARGS
  87.     ShowArgs(0);
  88.     ShowArgs(1,1.1);
  89.     ShowArgs(2,1.1,2.2);
  90. #endif
  91. #ifdef MY_PRINTF
  92.     myPrintf(“Jarvis”);
  93.     myPrintf(“\n”);         //注意\n \t为一个字符,不要理解成了char[0] = ‘\’ ; char[1] = ‘n’;
  94.     myPrintf(“\n”);
  95.     myPrintf(“Jarvis\n”);
  96.     myPrintf(“Jarvis %d\n”,22);
  97.     myPrintf(“Jarvis %d\t%d\n”,22, 1990);
  98.     myPrintf(“Jarvis %d\t%d\t%f\n”,22, 1990,63.2);
  99. #endif
  100. #ifdef SHOW_STRING_BY_CHAR
  101.     ShowStringByChar(“123\t456\n789%d”);
  102. # endif
  103.     return 0;
  104. }