可变参数函数

作者:Q

1.几个宏定义

实现可变参数函数需要文件stdarg.h的几个宏定义,其作用为实现参数指针的使用和控制,下面分别介绍如下:

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))       //第一个可变参数

#defineva_arg(ap,t) (*(t*)((ap+=_INTSIZEOF(t))-_INTSIZEOF(t))) //下一个参数地址

#defineva_end(ap) (ap=(va_list)0)       //无效该指针

2.实列一、可变加法

         以下函数,实现任意多个数字相加的函数,0xffffffff数字为结束符;该函数笔者并没有调试算是伪代码;

int add(int a, ...)

{

      va_list  arg;   

   int sum=0,temp=a;

   va_start(arg,a);

   while(a!=0xffffffff)

{

     sum+=temp;

     temp=va_arg(arg,int);

}

va_end(arg);

return sum;

}

调用:sum=add(10,20,30,0xffffffff);

3.实列二、自定义Printf

         以下函数实现动态输出函数,该文件在vs2012环境中调试通过,输出内容到控制台上,如在其他应用用户可以根据自己需求定制,如:打印到串口上、屏上……,所有应用只需要定制putchar即可。此外该函数笔者只写了” %d”,”%s”两个功能,如大家有兴趣,可以尝试下”%x”、”%2d”、”%02d”等更复杂的格式字符,同时提示读者一下,在嵌入式应用领域中映射库自带printf函数需要8KB左右空间,自己写个简单的Printf大概需要2K多。

//Printf.cpp : Defines the entry point for the console application.

//

#include "stdafx.h"

#include "stdarg.h"

 

void user_printf(constchar * format,...);

 

int _tmain(int argc,_TCHAR* argv[])

{

         user_printf("\r\nhello:%d",10);

         user_printf("\r\nhello:%s","123456你好");

         getchar();

         return0;

}

static voidto_dec_string(unsigned ints,char* asc_p)

{

         if(s<10)

         {

                   asc_p[0]=s+'0';

                   asc_p[1]=0x00;

         }

         else if(s>=10&&s<100)

         {

                   asc_p[0]=(s/10)+'0';

                   asc_p[1]=(s%10)+'0';

                   asc_p[2]=0x00;

         }

         else if(s>=100&&s<1000)

         {

                   asc_p[0]=(s/100)+'0';

                   asc_p[1]=((s%100)/10)+'0';

                   asc_p[2]=((s%10)/1)+'0';

                   asc_p[3]=0x00;

         }

         else if(s>=1000&&s<10000)

         {

                   asc_p[0]=(s/1000)+'0';

                   asc_p[1]=((s%1000)/100)+'0';

                   asc_p[2]=((s%100)/10)+'0';

                   asc_p[3]=((s%10)/1)+'0';

                   asc_p[4]=0x00;

         }

}

 

static void out_string(const char * arr)

{

         inti=0;

         while(*(arr+i)!='\0')

         {

                   putchar(*(arr+i++));

         }

}

 

void user_printf(constchar * format,...)

{

         va_list arg;  

         const char *ptr=format,*sval;

         inttemp,i;

         charout[6];

 

         va_start(arg,format);

         while(*ptr!='\0')

         {

                   if(*ptr=='%')

                   {

                            ptr++;

                            switch (*ptr)

                            {

                            case 'd':

                                     temp=va_arg(arg,int);

                                     to_dec_string(temp,out);

                                     out_string(out);

                                     ptr++;

                                     break;

                            case 's':

                                     for (sval = va_arg(arg, char*);(*sval!=0x00); sval++)

                                     {

                                               putchar(*sval );

                                     }

                                     ptr++;

                                     break;

                            }

                   }

                   putchar(*(ptr++));

         }

         va_end(arg);

}

/*

*       End of the file

*/

 

 

------------------------------------------------------------------------------------------------

电子技术软件硬件交流群,142282597,欢迎网友进来交流,进群请修改网名,网名格式“所在地+昵称”,群宗旨“文明交流,相互提高”

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值