终于把APUE看完一遍
数组的不对称边界

可变参数的实现原理

simplyzhao posted @ 2009年5月04日 05:32 in Unix-C Programming with tags varargs.h 可变参数 , 3152 阅读

 

/**
 * @brief 理解varargs.h的实现,虽然该头文件
 *        在GUN C库中已经被stdarg.h取代,但对于理解可变参数的实现
 *        以及参数传递机制还是非常有学习价值
 *
 *        参考 《C陷阱与缺陷》,附录
 * @date 2009-05-03
 */


#include<stdio.h>

typedef char *v_list;
#define v_dcl int v_alist;
#define v_start(list) list=(char *)&v_alist
#define v_end(list)
#define v_arg(list,mode) \
        ((mode *)(list+=sizeof(mode)))[-1]

/*
 * 假定:
 * 底层的C语言实现要求函数参数在内存中连续存储
 * 这样,但我们知道当前参数的地址,就能依次访问参数列表中的其他参
 */


void
test_arg(v_alist) v_dcl
{
    v_list ap;
        v_start(ap);

        char ch;
        printf("ap: %p\n", ap);
        /*
         * 陷阱
         * v_arg宏的第二个参数不能被指定为char, short, float
         * 因为char 和 short 参数将被转换为 int 类型, 而float 参数会被转换为 double
         */

        ch = v_arg(ap, int);
        printf("%c\n", ch);

        int i;
        printf("ap: %p\n", ap);
        i = v_arg(ap, int);
        printf("%d\n", i);

        double d;
        printf("ap: %p\n", ap);
        d = v_arg(ap, double);
        printf("%f\n", d);

        char *p;
        printf("ap: %p\n", ap);
        p = v_arg(ap, char *);
        printf("%s\n", p);

        v_end(ap);
}

int
main(int argc, char *argv[])
{
        char ch;
        int i;
        double d;
        char *p;
        ch = 'z';
        i = 1;
        d = 3.5;
        p = "simplyzhao";
        test_arg(ch, i, d, p);
        return 0;
}

 输出:

simplyzhao@Full-House:~$ gcc test.c
simplyzhao@Full-House:~$ ./a.out
ap: 0xbf8f8530
z
ap: 0xbf8f8534
1
ap: 0xbf8f8538
3.500000
ap: 0xbf8f8540
simplyzhao
 

ps.

发现stdarg.h头文件并不在/usr/include目录下,不知何解?

simplyzhao@Full-House:~$ locate stdarg.h
/usr/include/c++/4.3/tr1/stdarg.h
/usr/lib/gcc/i486-linux-gnu/4.3/include/stdarg.h
 

Enjoy Linux, Fighting.
Avatar_small
孤毒老鼠 说:
2009年5月04日 22:14

这个要看一下~~呵呵~~以后自己实现的程序要用到可变参数的话还能用上


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter