C语言不定参数的解决方法

发表于:2015年3月25日 11:54  分类:c 672次浏览

C语言中,函数的参数个数和类型一般在声明函数时确定,但当声明函数时不能确定参数的个数和类型时,就需要使用“…”作为参数占位符,表示不定参数的内存地址。
解决不定参数的方法就是按照指定的类型读取栈中的不定参数,并且指定一个结束标志,每次输出前判断结束标志,具体实现如下:

void showstr(char *, ...);

char *p1 = "This is a c programm.";
char *p2 = "Welcome to c!";
char *p3 = "Hello world!";

main()
{
    showstr(p1, p2, p3, 0);
}

void showstr(char * p, ...)
{
    int i = 0;
    while(0 != *p)
    {
        printf("%s\n", p);
        i++;
        p = *(&p + i);
    }
}

运行结果:
c-va-list-1

除了自己动手写处理函数,C语言中提供了一组宏解决不定参数,定义在stdarg.h中,TC2.0版本中的定义:

typedef void    *va_list;

#define va_start(ap, parmN) (ap = ...)
#define va_arg(ap, type)    (*((type *)(ap))++)
#define va_end(ap)
#define _va_ptr         (...)

使用该宏改写上面的程序:

typedef void    *va_list;

#define va_start(ap, parmN) (ap = ...)
#define va_arg(ap, type)    (*((type *)(ap))++)
#define va_end(ap)
#define _va_ptr         (...)

void showstr(char *, ...);

char *p1 = "This is a c programm.";
char *p2 = "Welcome to c!";
char *p3 = "Hello world!";

main()
{
    showstr(p1, p2, p3, 0);
}

void showstr(char * p, ...)
{
    char * str = p;
    va_list argptr;
    va_start(argptr, p);
    
    while(0 != *str)
    {
        printf("%s\n", str);
        str = va_arg(argptr, char *);
    }   
    va_end(argptr);
}

不定参数宏的具体分析:

语句 分析
typedef void    *va_list; Va_list作为void *的别名,因为不定参数的类型不能确定,所以使用void *保存,之后按照需要进行强制类型转换。
#define va_start(ap, parmN) (ap = …) va_start是有参数的宏,将…赋值给ap,表示不定参数的内存首地址,parmN表示第一个不定参数的前一个参数,即不定参数前必须有一个确定的参数。
#define va_arg(ap, type)    (*((type *)(ap))++) 先将void指针ap转化为type类型的指针,然后右++,最后返回不定参数,并且ap指向了下一个不定参数的地址。
#define va_end(ap) 清除ap,将ap指向NULL
#define _va_ptr         (…) _va_ptr表示不定参数占位符。

其次,还可以使用指针数组表示不定参数,原理同前,最常见的就是int main(int argc, char *argv[]);。

发表评论

电子邮件地址不会被公开。 必填项已用*标注