LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 998|回复: 4

问关于”不定参数“的几个问题?

[复制链接]
发表于 2004-4-1 22:37:40 | 显示全部楼层 |阅读模式
C语言中有些函数会利用不定参数的方式来取得参数内容,常见的如printf()、sprintf()、execl()等等,其最后参数以......来定义,即代表后面的参数为不定个数的参数内容。不定参数的相关表头文件在/usr/lib/bcc/include/stdarg.h,其定义如下:

问题1:找不到stdarg.h,如何能得到这个头文件?

[php]
typedef char *va_list;

#define va_start(ap,p) (ap=(char *)(&(p)+1))
#define va_arg(ap,type) ((type *)(ap+=sizeof(type)))[-1]

问题2:上面一句后面的-1是用中括号,还是小括号?结合下面的范例说明一下这个宏定义

#define va_end(ap)

范例:
#include <stdio.h>
#indlude <stdarg.h>

void fun(char *s,......)/*......声明不定参数*/

问题3:不定参数用什么符号,用的是句号吗,需要几个点?

{
        va_list ap;

问题4:ap是一个指针变量,还是一个字符变量?

        int t;
        va_start(ap,s);
        printf("%s",s);
        while((t=va_arg(ap,int)))

问题5:这个循环是如何运行的?

                printf("%d",t);
        va_end(ap);
}

int main(void)
{
        int a=1,b=2,c=3;
        fun("test:",a,b,c,NULL);/*以NULL作结束*/
        printf("\n");
        return 0;
}
[/php]

上面这段来自《Linux C函数库参考手册》

不定参数在linux编程里出现在比较多,所以看了一下,但还不是很清楚,麻烦兄弟解答一下,这里先谢过了!
发表于 2004-4-1 23:24:11 | 显示全部楼层
1.我是debian、gcc 3.3,stdarg.h在
/usr/lib/gcc-lib/i486-linux/3.3.3/include/
gcc为了跨平台,所以把stdarg做在了编译器里面,比如x86是用栈(内存)传递参数的,而RISC计算机是用寄存器传递参数的,用库就难以实现跨平台
2.中括号
3.句号,3个
4.应该是指针,不过这一点你不需要知道
5.va_arg每次取下一个参数,你的参数列表最后一个是NULL,用来终止循环
 楼主| 发表于 2004-4-2 14:03:52 | 显示全部楼层

OK!很详细,谢谢libinary版主的回答

1、我的是Fedora1、gcc 3.3.2,头文件在这里/usr/lib/gcc-lib/i386-redhat-linux/3.3.2/include/
4、是指针
typedef char *va_list;/*定义va_list为字符指针类型*/

va_list ap;/*ap为字符指针变量*/

问题4的我查阅了第二版潭浩强的C语言程序设计的第273页。
 楼主| 发表于 2004-4-2 14:14:46 | 显示全部楼层

再问:

#define va_arg(ap,type) ((type *)(ap+=sizeof(type)))[-1]

这个后面加个[-1]有什么用?
发表于 2004-4-2 19:19:47 | 显示全部楼层
va_arg是取参数用的,比如你传入了a,b两个int参数,一开始ap指向a的第一个字节,看看宏定义,
va_arg(ap, int)转换成((int *)(ap+=sizeof(int)))[-1]
最里面的是ap+=4,ap就指向了b的第一个字节,va_arg要返回a就要用:
((int *)ap)[-1],取上一个位置
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表