Linux C编程连载【7】 - 变参数实现printf

【代码清单】

#include <stdio.h> #define va_list void* #define va_end(arg) #define va_start(arg, start) arg = (va_list)(((char *)&(start)) + sizeof(start)) #define va_arg(arg, type) *(type*)arg; arg = (char *)arg +sizeof(type) char *itoa(int num, char *str, int radix) { char string[] = "0123456789abcdefghijklmnopqrstuvwxyz"; char *ptr = str; int i,j; while(num) { *ptr++ = string[ num%radix ]; num /= radix; if(num < radix) { *ptr++ = string[num]; *ptr = '\0'; break; } } j = ptr - str -1; for(i=0; i<(ptr-str)/2; i++) { int temp = str[i]; str[i] = str[j]; str[j--] = temp; } return str; } int mprintf(const char *format, ...) { va_list arg; int done = 0; va_start(arg, format); while(*format != '\0') { if(*format == '%') { if(*(format+1) == 'c') { char c = (char)va_arg(arg,int); putc(c,stdout); } else if(*(format+1) == 'd'||*(format+1) == 'i') { char store[20]; int i = va_arg(arg,int); char *str = store; itoa(i,store,10); while(*str != '\0') putc(*str++,stdout); } else if(*(format+1) == 'o') { char store[20]; int i = va_arg(arg,int); char *str = store; itoa(i,store,8); while(*str != '\0') putc(*str++,stdout); } else if(*(format+1) == 'x') { char store[20]; int i = va_arg(arg,int); char *str = store; itoa(i,store,16); while(*str != '\0') putc(*str++,stdout); } else if( *(format+1) == 's' ) { char* str = va_arg(arg, char*); while( *str != '\0') putc(*str++, stdout); } format += 2; } else { putc(*format++, stdout); } } va_end (arg); return done; } int main(int argc, char* argv[]) { int n = 255; char str[] = "hello, world!"; // Test vprintf function mprintf("n = %d\n", n); mprintf("n = %i\n", n); mprintf("n = %o\n", n); mprintf("n = %x\n", n); mprintf("first char = %c\n", str[0]); mprintf("str = %s\n", str); mprintf("%s\tn = %d\n", str, n); return 0; }


【解析】

(1)

#define va_start(arg, start) arg = (va_list)(((char *)&(start)) + sizeof(start))

让arg指向start(即format)之后的地址,即可变参数的首地址。

(2)

#define va_arg(arg, type) *(type*)arg; arg = (char *)arg +sizeof(type)

定义了一个va_arg函数,该函数有两个参数,arg和type。并指明了arg是type*类型的指针。该函数的作用是将指针指向下一个可变参数。

【链接】函数定义的两种形式

(1) int func(int a, int b);

(2) int func(a,b) int a, int b;


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值