• C语言中的可变参数函数的浅析(以Arm 程序中的printf()函数实现为例) . 分类: HI3531 arm-linux-Ubuntu 2013-12-16 14:19 438人阅读 评论(0) 收藏


    我们在C语言编程中会遇到一些参数个数可变的函数,一般人对它的实现不理解。例如Printf():

      Printf()函数是C语言中非常常用的一个典型的变参数函数,它

    的原型为: int printf( const char* format, ...);

    它除了一个参数format固定外,后面的参数的个数和类型是不确定的,如下列三种调用方法:

    1.    printf(“%d ”, i);

    2.    printf(“%s ”, “Hello World”);

    3.    printf(“The result is %d, name is %s”, i, “Lily”);

    使用可变参数时,需要用到的库函数:va_list 、va_start、va_arg、va_end,要包含头文件<stdarg.h>

    使用可变参数的步骤:

    1)首先在函数里定义一个va_list型的变量,如arg

    2)然后用va_start宏初始化变量arg,这个宏的第二个参数是第一个可变参数的前一个参数,是一个固定的参数.
    3)然后用va_arg返回可变的参数.依次取可变参数,va_arg的第二个参数是你要返回的参数的类型

    4)最后用va_end宏结束可变参数的获取.

    现在你就可以在函数里使用第二个参数了.如果函数有多个可变参数的,依次调用va_arg获取各个参数.

     

    应用:在ARM调用串口打印时,是没有Printf()的,这时就需要自己写一个打印函数(前提是已经实现串口的字符、字符串及整数打印)

     

     

    void Uart_Printf(const char *format, ...)

    {

          va_list unnamed_p;

         

          char *p, *sval;

         

          unsigned int value_i;

     

          /* unnamed_p point to first unnamed argument */

          va_start( unnamed_p, format);

     

          for ( p=(char *)format; *p!=''; p++ )

          {

               if ( *p != '%' )//循环检测format的每位字符,没有遇到“%”,//则输出该字符

               {

                     Uart_Put_Char( *p );

                     continue;

               }

    //如果遇到“%”,则是格式控制符,向下运行,指针p加1,确定是//“%d”、“%s”等,然后相应处理

               switch ( *++p )

               {

               case 'd'://输出十进制整数

                     value_i = va_arg( unnamed_p, unsigned int );          

                     Out_Put_Int( value_i, 10 );

                     break;

    #if  0

               case 'c'://输出字符

                     {

                          sval = va_arg(unnamed_p, char*);

    Uart_Put_Char(*sval);//串口输出字符函数

    break;

             }

    #endif

               case 's'://输出字符串

                     for (sval = va_arg(unnamed_p, char*); *sval; sval++)

                          Uart_Put_Char( *sval ); //此为串口输出字符函数

                     break;

     

               case 'x': //X表示16进制

                     value_i = va_arg( unnamed_p, unsigned int );          

                     Out_Put_Int( value_i, 16 );//此为串口输出无符号整数函数,//第一个参数为要输出的整数,第二个参数为进制,表示以多少进制//的格式输出

                     break;

     

               default: //输出字符

                     Uart_Put_Char( *p );

                     break;

              

               }

              

          }

          va_end( unnamed_p ); //结束可变参数的获取

     

    }

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    小w的喜糖(candy)
    亚瑟王(arthur)
    Bajtman i Okrągły Robin
    Bajtman i Okrągły Robin
    网络流模板
    网络流模板
    觉醒力量 (hidpower)
    觉醒力量 (hidpower)
    E-card
    E-card
  • 原文地址:https://www.cnblogs.com/mao0504/p/4706695.html
Copyright © 2020-2023  润新知