可变参数的实现原理
/**
* @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;
}
* @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
2009年5月04日 22:14
这个要看一下~~呵呵~~以后自己实现的程序要用到可变参数的话还能用上