函数参数的类型

来源:互联网 发布:php curl模拟get请求 编辑:程序博客网 时间:2024/05/19 12:16

输出结果:

这段代码主要是想说明:函数的参数在传入时,是做类型的转换的,也就是参数在入栈时就已经被截取了(例如long 传入 char 时);其中还包括了强制类型转换的存储结果,和用不符合变量类型的格式输出时,结果的不同。

 

由这段代码想到了printf的实现,想到了printf需要先解析那个const char *str中的格式字符来确定va_list的指针类型,移动大小。下面是一位大侠对printf的解释,很好!!

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)