您的位置:首页 > 运维架构 > Linux

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

2011-11-15 16:16 260 查看
【代码清单】

#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;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: