va_arg 总是运行 4 次

va_arg always runs 4 times

我正在学习 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;
}

没有标准机制可以告诉您传递给可变参数函数的参数数量。 printf() 之类的函数之所以有效,是因为它们可以通过检查格式字符串来确定参数的数量。

这是ISO 9899 WG14 n1256

中stdarg.h的定义

The header <stdarg.h> declares a type and defines four macros, for advancing through a list of arguments whose number and types are not known to the called function when it is translated

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

您可以像这样将哨兵传递给函数

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

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

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

#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 个论据来适应您的需要。

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

If there is no next argument, or if type is not compatible with the type of the actual next argument (as promoted according to the default argument promotions), random errors will occur.

除非您调用 strtest 时最后一个参数为 NULL,否则 va_arg 将继续读取,直到遇到使其停止的内容。将您现在正在做的事情想象成等同于读取超出其范围的数组。

我很惊讶无论如何它是 运行 4 次。我本以为计数等于您传递给 strtest 的参数数量加上 2 或更多。