va_arg总是运行4次

时间:2015-11-13 20:03:36

标签: c variadic-functions

我正在学习stdarg.h在c中我试图打印传递给函数的所有参数,而不知道有多少参数,但我还没有提出解决方案,在此过程中发生这种情况,无论我传递给strtest。 它总是打印0. 1. 2. 3.

void strtest(char *fmt, ...){
    va_list argp;
    int i = 0;

    va_start(argp, fmt);

    while(va_arg(argp, char*))
        printf("%d\t", i++ );

    va_end(argp);
}

int main(int argc, char *argv[]){
    strtest("s");
    printf("\n");
    return 0;
}

5 个答案:

答案 0 :(得分:5)

没有标准机制可以告诉你传递给varargs函数的参数数量。像printf()这样的函数可以工作,因为它们可以通过检查格式字符串来确定参数的数量。

答案 1 :(得分:1)

这是ISO 9899 WG14 n1256

中stdarg.h的定义
  

标题< stdarg.h>声明一个类型并定义四个宏,用于推进   通过一个参数列表,其数量和类型不为被调用函数所知   什么时候翻译

您必须将参数的数量以及可能的类型传递给调用者。这不必通过直接传递参数的数量来完成,还有其他方法,例如printf中使用的方法。

答案 2 :(得分:1)

这是一个示例,显示了传递未知数量参数的一种方法。

#include <stdio.h>
#include <stdarg.h>

void print (char *first, ...)
{
    va_list argptr;
    char *next;
    va_start (argptr, first);
    next = first;
    while (next) {
        printf ("%s\n", next);
        next = va_arg(argptr, char*);
        }
    va_end (argptr);
}

int main(void)
{
    print("hello","world", NULL);      // NULL as sentinel
    return 0;
}

节目输出

hello
world

也许您可以使用int参数来满足您的需求。

答案 3 :(得分:0)

你可以将哨兵传递给这样的功能

strtest("s", (char*)0);

这样函数可以注意到它位于参数列表的末尾。

答案 4 :(得分:0)

如果查看stdarg的手册页,va_arg包含此文本

  

如果没有下一个参数,或者类型与...不兼容   实际的下一个参数的类型(根据   默认参数促销),将发生随机错误。

除非你用一个NULL作为最后一个参数调用strtest,否则va_arg将继续阅读,直到它碰到让它停止的东西为止。想想你现在正在做的事情等同于读取超出界限的数组。

我很惊讶它无论如何都跑了4次。我原本期望计数等于你传递给strtest的args数加上2或更多。