在VC6中,打开printf函数的源代码,发现这个函数的代码量无比巨大,闲来无事,自己用C写了一个简单的printf函数,只实现了VC库中printf函数的部分简单功能,贴出自己写的代码只为抛砖引玉,娱人娱己,仅此而已!
printf.h 头文件
#ifndef _prinrf_h
#define _printf_h
#include "uart.h"
typedef char * va_list;
#define maxparments 128
#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) ) //保证是4字节对齐
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )
/*如果定义了两个表达式,先计算表达式1,再计算表达式2,返回表达式2的值*/
#define va_end(ap) ( ap = (va_list)0 )
int printf_test(void);
int outc(char c,unsigned char w);
int outs(va_list p);
int va_printf(const char* fmt,char* p);
int printf( const char* format,...);
int out_num(int m,int base,unsigned char c,unsigned char w);
//int out_float(float m,unsigned char c,unsigned char w,unsigned char wd);
#endif
printf.c文件
#include "printf.h"
unsigned char temp[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
int outc(char c,unsigned char w) //输出字符
{ unsigned char i;
for(i=1;i<w;i++)
{
putchar(' ');
}
putchar(c);
return 0;
}
int outs(va_list p) //输出字符串
{
puts( p);
return 0;
}
int out_num( int m,int base,unsigned char c,unsigned char w) //输出数字
{ unsigned int n;
unsigned char buf[maxparments],count=0,i;
unsigned char *s = (unsigned char *)buf+sizeof(buf);
*--s=' ';
if(m<0)
n=-m;
else
n=m;
do
{
*--s=temp[n%base];
n=n/base;
count++;
}while(n!=0);
for(i=1;i<=(w-count);i++)
{
*--s=c;
}
if(m<0)
*--s='-';
outs(s);
return 0;
}
int va_printf(const char* fmt,char* p)
{
while(*fmt!='\0')
{
unsigned char width=0; //总位宽
unsigned char width_decimal=0; //小数位宽
unsigned char lead=' '; //默认前导为空格
if(*fmt=='%')
{
fmt++;
if(*fmt=='0')
{
lead='0';
fmt++;
}
while((*fmt>='0')&&(*fmt<='9')) //得到总位宽
{
width=width*10;
width=width+(*fmt)-'0';
fmt++;
}
if(*fmt=='.') //得到小数位宽
{
fmt++;
while((*fmt>='0')&&(*fmt<='9'))
{
width_decimal=width_decimal*10;
width_decimal=width_decimal+(*fmt)-'0';
fmt++;
}
}
switch(*fmt) //调用相应的函数
{
case 'd': out_num(va_arg(p,int),10,lead,width); break;
case 'o': out_num(va_arg(p,unsigned int),8,lead,width); break;
case 'x': out_num(va_arg(p,unsigned int),16,lead,width) ;break;
case 'c': outc(va_arg(p,int),width); break;
case 's': outs(va_arg(p,char *)); break;
//case 'f': out_float(va_arg(p,float),lead,width,width_decimal); break;
default: outc(*fmt,1); break;
}
}
else putchar(*fmt);
fmt++;
}
return 0;
}
int printf(const char* format,...)
{
va_list apt;
va_start(apt,format);
va_printf(format,apt);
va_end(apt);
return 0;
}
int printf_test() //测试函数
{
printf("test char =%c,%c\n\r", 'A','a') ;
printf("test decimal number =%d\n\r", 123456) ;
printf("test decimal number =%d\n\r", -123456) ;
printf("test hex number =0x%x\n\r", 0x55aa55aa) ;
printf("num=%08d\n\r", 12345);
printf("num=%8d\n\r", 12345);
printf("num=0x%08x\n\r", 0x12345);
printf("num=0x%8x\n\r", 0x12345);
printf("num=0x%02x\n\r", 0x1);
printf("num=0x%2x\n\r", 0x1);
printf("num=%05d\n\r", 0x1);
printf("num=%5d\n\r", 0x1);
return 0;
}
main函数:
#include "s3c2440_reg.h"
#include "uart.h"
#include "printf.h"
int main()
{
uart_init0();
puts("Hello CSDN!\n\r");
printf_test();
return 0;
}
串口初始化程序请自行按照S3C2440数据手册编写!十分简单!
笔者的实验平台为JZ2440,下载后验证通过!