多參數函數可以很好的寫一個通信協議,下面試着實現printf
#include "stdio.h"
#include "stdarg.h"//變參函數包含庫
#include "string.h"
char* apart_num_l(long num,char *buf,char length)
{
int i_;
char ag;
long num_=num;
char * ret_adr=buf;
for(i_=length;i_>=0;i_--)
{
ag=(char)(num_%10);
num_/=10;
*(ret_adr+i_)=ag+'0';
}
*(ret_adr+length+1)='\0';
return ret_adr;
}
char* apart_num_ul(unsigned long num,char *buf,char length)
//max 4294967295 min 0
{
int i_;
char ag;
unsigned long num_=num;
char * ret_adr=buf;
for(i_=length;i_>=0;i_--)
{
ag=(char)(num_%10);
num_/=10;
*(ret_adr+i_)=ag+'0';
}
*(ret_adr+length+1)='\0';
return ret_adr;
}
char seek_nonzere(char * ct)
{
char i;
for(i=0;i<9;i++)
{
if(*(ct+i)!='0')return i;
}
return 0;
}
int printff(const char* str, ...)
{
va_list argp; /*定義保存函數參數的個數*/
char s_flag=0; //用來關閉主循環中的putchar
int int_flag=0;
char *char_pr_arg;
char char_arg; /*存放取出的字符串參數*/
int int_arg;
long long_arg;
unsigned long u_long_arg;
char buf1[50];
char num=0;
va_start( argp, str ); /*argp指向傳入的第一個可選參數,msg是最後一個確定的參數*/
char_arg=*str++;
while(char_arg!='\0') //主循環
{
if(char_arg=='%')
{
char_arg=*str++ ;
if(char_arg=='c')
char_arg = va_arg(argp,char); /*取出當前的參數,類型爲char*/
if(char_arg=='s')
{
s_flag=1;
char_pr_arg = va_arg( argp,char*);
char_arg = *char_pr_arg++;
while(char_arg!='\0')
{
putchar(char_arg);
char_arg = *char_pr_arg++;
}
}
if(char_arg=='d')
{
s_flag = 1;
int_arg = va_arg(argp,int)%65536;
if(int_arg<0){putchar('-');int_arg*=-1;};
char_pr_arg=apart_num_l(int_arg,buf1,9);
int_flag=seek_nonzere(char_pr_arg);
char_arg = *char_pr_arg++;
while(char_arg!='\0')
{
if(int_flag!=0){--int_flag; char_arg = *char_pr_arg++;continue;}
putchar(char_arg);
char_arg = *char_pr_arg++;
}
}
if(char_arg=='l')//max = 2147483647 min = -2147483647
{
s_flag = 1;
long_arg = va_arg(argp,long)%2147483647;
if(long_arg<0){putchar('-');long_arg*=-1;};
char_pr_arg=apart_num_l(long_arg,buf1,9);
int_flag=seek_nonzere(char_pr_arg);
char_arg = *char_pr_arg++;
while(char_arg!='\0')
{
if(int_flag!=0){--int_flag; char_arg = *char_pr_arg++;continue;}
putchar(char_arg);
char_arg = *char_pr_arg++;
}
}
if(char_arg=='u')
{
char_arg=*str++ ;
if(char_arg=='l')
{
s_flag = 1;
u_long_arg = va_arg(argp,unsigned long);
char_pr_arg=apart_num_ul(u_long_arg,buf1,9);
int_flag=seek_nonzere(char_pr_arg);
char_arg = *char_pr_arg++;
while(char_arg!='\0')
{
if(int_flag!=0){--int_flag; char_arg = *char_pr_arg++;continue;}
putchar(char_arg);
char_arg = *char_pr_arg++;
}
}
if(char_arg=='d')
{
s_flag = 1;
u_long_arg = va_arg(argp,unsigned long)%65536;
char_pr_arg=apart_num_ul(u_long_arg,buf1,9);
int_flag=seek_nonzere(char_pr_arg);
char_arg = *char_pr_arg++;
while(char_arg!='\0')
{
if(int_flag!=0){--int_flag; char_arg = *char_pr_arg++;continue;}
putchar(char_arg);
char_arg = *char_pr_arg++;
}
}
}
}
if(!s_flag)
putchar(char_arg);
else s_flag=0;
char_arg=*str++;
}
va_end(argp);
return 0;
}
void main( void )
{
char a[]="asdf";
int b=123;
printff("%d",123);
}
變參編程的關鍵就是確定所有參數在內存的長度,和每個參數的在內存的長度。