Chinaunix首页 | 论坛 | 博客
  • 博客访问: 120434
  • 博文数量: 41
  • 博客积分: 2564
  • 博客等级: 少校
  • 技术积分: 455
  • 用 户 组: 普通用户
  • 注册时间: 2007-09-20 19:17
文章分类

全部博文(41)

文章存档

2009年(41)

我的朋友

分类: C/C++

2009-04-08 20:55:09

关于可变参数函数,最著名的莫过于printf了。实际上,可变参数并不神秘,只要了解函数调用时参数存放的方式就可以实现自己的可变参数函数。

myprintf--gcc编译:

#include <stdio.h>

void myprintf(const char *, ...);

int main()
{
    myprintf("result: %d %d %d", 1, 2, 3);
    return 0;
}

void myprintf(const char *fmt, ...)
{
    char *vars = (char *)&fmt;
    vars += sizeof(fmt);
    while (*fmt)
    {
        if('%' != *fmt)
        {
            putchar(*fmt);
        }
        else
        {
            fmt ++;
            switch (*fmt)
            {
                case '%':
                {
                    putchar('%');
                    break;
                }
                case 'd':
                {
                    printf("%d", *(int *)vars);
                    vars += sizeof(int);
                    break;
                }
                default:
                {
                    ;
                }
            }
        }
        fmt ++;
    }
}

函数中,fmt位于栈顶,接下去依次是调用myprintf时传入的其它参数(从左到右)。因此,通过fmt的地址就可以找到我们需要的参数列表的首地址,代码中的vars初始化过后指向的就是参数列表第一个参数的地址,即'1'的地址。

另外,从这里还可以知道gcc环境下,函数参数的入栈顺序是从右到左。

阅读(283) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~