自己实现myprintf函数

#include <stdio.h>
#include <stdarg.h>

void printint(int dec)
{
    if(0 == dec)
    {
        return;
    }

    printint(dec / 10);
    putchar(dec % 10 + '0');
}

void printstr(char *str)
{
    while(*str)
    {
        putchar(*str);
        str++;
    }
}
void printfloat(float flt)
{
    int tempint = (int)flt;
    int tempflt = (int)(100000 *(flt - tempint));

    if(tempflt % 10 > 5)
    {
        tempflt = tempflt /10 + 1;
    }
    else
    {
        tempflt = tempflt / 10;
    }

    printint(tempint);
    putchar('.');
    printint(tempflt);
}

void myprintf(const char *format,...)
{
    va_list ap;

    va_start(ap,format);
    while(*format)
    {
        if(*format != '%')
	{
	    putchar(*format);
	    format++;
	}
	else
	{
	    format++;
	    switch(*format)
	    {
	        case 'c':
		{
		    char val_ch = va_arg(ap,int);
		    putchar(val_ch);
		    format++;
		    break;
		}

		case 'd':
		{
		    int val_int = va_arg(ap,int);
		    printint(val_int);
		    format++;
		    break;
		}

		case 's':
		{
		    char * val_str = va_arg(ap,char *);
                    printstr(val_str);
		    format++;
		    break;
		}

		case 'f':
		{
		    float val_flt = va_arg(ap,double);
		    printfloat(val_flt);
		    format++;
		    break;
		}
		default :
		{
		    putchar(*format);
		    format++;
		}
	    }
	}
    }

    va_end(ap); 
    
}


va_start()宏初始化ap以供va_arg()和va_end()随后使用,并且必须在他们前面定义。参数last是可变参数列表之前的最后一个参数的名称,调用函数知道其类型的最后一个参数。因为这个参数的地址可能在va_start()宏中使用,它不应该被声明为寄存器变量,或者作为函数或数组类型。
 
va_start()宏初始化va_list型的变量ap,ap是存储参数地址的指针。因为得到参数的地址后,再结合参数的类型,就能得到参数的值。


      va_arg()宏扩展为具有调用中的下一个参数的类型和值的表达式。 参数ap是由va_start()初始化的va_list ap。 每次调用va_arg()都会修改ap,以便下一次调用返回下一个参数。参数类型是指定的类型名称,以便可以通过向类型中添加*来获取指向具有指定类型的对象的指针的类型。在va_start()宏之后第一次使用va_arg()宏将返回最后一个参数。 连续调用返回其余参数的值。如果没有下一个参数,或者如果类型与实际下一个参数的类型不兼容,则会出现随机错误。如果ap被传递给使用va_arg(ap,type)的函数,则ap的值在该函数返回后是未定义的。
 
依次使用va_arg宏使得ap返回可变参数的地址,得到这个地址后,结合参数的类型,就可以得到参数的值。

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值