printf函数

来源:互联网 发布:php用户管理系统 编辑:程序博客网 时间:2024/04/29 20:42

int  DEFUN(printf, (format), CONST char *format DOTS)
{
  va_list arg;
  int done;

  va_start(arg, format);
  done = vprintf(format, arg);
  va_end(arg);

  return done;
}

可以看到printf其实在内部调用的是vprintf,通过查看vprintf.c中的内容,我们可以看到vprintf其实是通过vfprintf实现的,它的函数原型是这样的:

int  DEFUN(vfprintf, (s, format, args),
      register FILE *s AND CONST char *format AND va_list args)
这个函数的整体执行结构是这样的:

register CONST char *f;                //可以看到f是一个const char的指针
 
  f = format;            
  while (*f != '/0')
{                              

 ...
 if (*f != '%')
 {
  ...
 }

 if (*f == '%')
 {
   fc = *f++;
   ...
  switch (fc)
   {
       case 'd':
            ...
       case 'c':
            ...
        ....
    }
 }
    }
从上面的结构我们可以看出,函数首先读取字符串中的字符,然后一个个比较,如果是%,则马上用switch...case结构判断后续字符

在每一个case语句块里面,都有这样的语句:

 nextarg(...);
 outchar(...);

 nextarg()是一个宏,有如下宏定义

#define castarg(var, argtype, casttype) /
  var = (casttype) va_arg(args, argtype)

#define nextarg(var, type) castarg(var, type, type)

一出现va_arg,我们就很熟悉了,这个宏的作用就是读取可变参数,在这里的作用就是将args中的内容读入。也就是利用栈顶指针读取
栈中的内容。

outchar(...)也是一个宏,它的定义如下

#define outchar(x)                                     /
  do                                                               /
    {                                                                /
      register CONST int outc = (x);           /
      if (putc(outc, s) == EOF)                     /
 RETURN(-1);                                            /
      else                                                       /
 ++done;                                                     /
    } while (0)