Linux C编程连载【7】 - 变参数实现printf
2011-11-15 16:16
260 查看
【代码清单】
【解析】
(1)
让arg指向start(即format)之后的地址,即可变参数的首地址。
(2)
定义了一个va_arg函数,该函数有两个参数,arg和type。并指明了arg是type*类型的指针。该函数的作用是将指针指向下一个可变参数。
【链接】函数定义的两种形式
(1) int func(int a, int b);
(2) int func(a,b) int a, int b;
#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;
相关文章推荐
- 使用未公开关键字在 C# 中导入外部 printf 等参数数量可变函数 [2] C# 实现
- 可变参数函数printf函数的实现
- 从printf谈可变参数函数的实现
- 详解_C语言可变参数_va_list和_vsnprintf及printf实现
- 解析可变参数函数的实现原理(printf,scanf)
- 可变参数模拟printf()函数实现一个my_print()函数以及调用可变参数需注意的陷阱
- 从printf谈可变参数函数的实现
- printf可变参数实现
- 从printf谈可变参数函数的实现
- C语言中的可变参数函数的浅析(以Arm 程序中的printf()函数实现为例)
- 创建函数利用可变参数列表的形式模拟实现printf的功能
- 对C的printf函数的可变长参数实现的分析
- 详解C语言可变参数 va_list和_vsnprintf及printf实现
- va_list、va_start、va_end(用于实现函数参数的个数可变的函数,如scanf()/printf()系列函数)
- printf()多参数实现机制
- 利用可变参数模拟实现简易printf
- 详解C语言可变参数va_list和vsnprintf及printf实现
- 不定参数函数原理以及实现一个属于自己的printf函数
- C中printf与scanf函数读取与储存参数实现办法
- 从printf谈可变参数函数的实现