c - 如何使用 va_arg "extract"长 double ?

标签 c types variadic

我正在学习 C 编程并遇到一个问题。我想从参数列表中“提取”一个长 double 。但是,当我要求 va_arg “捕获”长双参数时,我遇到了一个随机错误(正如在关于错误 va_arg 调用的 man 中提到的那样)。 但我怎样才能解决这个问题呢? 以下是说明 pb 的代码示例:

void func(va_list *ptr)
{
    long double f;

    f = va_arg(*ptr, long double);
    printf("Value extracted: %Lf\n", f);
    return ;
}

void func2(char *format, ...)
{
    va_list ap;

    va_start(ap, format);
    func(&ap);
    va_end(ap);
    return ;
}

感谢您的帮助!

编辑:我知道如何使用 va_arg (至少对于简单的东西)。如您所见,该函数采用指向 va_list 的指针作为参数。这是因为我在调用函数中调用 va_start (并在同一调用函数的末尾调用 va_end )。我只是想向您展示问题所在,没有别的意思。

我对其他数据类型(int、long、char、char * 等)没有问题。这只是一个长双 pb。

编辑 #2:我编写了一个调用函数来向您展示我没有忘记 va_start 和 va_end。总而言之,我的问题是我正在尝试编写自己的 printf 函数,并且正在处理 -Lf 转换。我认为没有必要提及这一点,对此感到抱歉。

最佳答案

您仍然没有向我们展示您正在使用的完整的、可编译的代码,因此很难看出您做错了什么。这是一些完整的代码,说明了您要执行的操作。

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

void vlist_one_ldouble(va_list *pargs) {
    long double value;

    value = va_arg(*pargs, long double);
    printf(" %Lf", value);
}

void vlist_ldouble(int count, va_list *pargs) {
    printf("Now printing %d long doubles:\n", count);

    for (int i=0; i<count; i++)
        vlist_one_ldouble(pargs);

    printf("\n");
}

void list_ldouble(int count, ...) {
    va_list args;
    va_start(args, count);

    vlist_ldouble(count, &args);

    va_end(args);
    return;
}

int main(void) {
    long double a = 1.1, b=2.2, c=3.3;

    list_ldouble(3, a, b, c);
    list_ldouble(4, 1.1L, 2.2L, 3.3L, 4.4L);

    return 0;
}

如果没有完整的代码,我们无法检查的一件非常重要的事情是,您必须确保您确实传递了长 double 。这里我用两种方法来实现:首先,使用 long double 变量;其次是长 double 文字。

此处的 L 后缀是“类型文字”的示例。当您在源代码中指定变量的实际值时(例如 13.14'b'"foo")这是一个字面意思。通常您不必显式指定文字的类型,因为编译器可以执行任何必要的转换。对于浮点文字,标准是这样说的:

An unsuffixed floating constant has type double. If suffixed by the letter f or F, it has type float. If suffixed by the letter l or L, it has type long double.

如果使用文字值调用具有原型(prototype)的标准函数,例如 func(1.2),那么编译器将知道 func() 是否需要 float , double 或 long double 并将适当的类型传递给函数。但是对于可变长度参数列表函数,没有原型(prototype)可供使用,因此编译器根据您传递的值的类型进行工作。如果您传递 1.2,它将作为 double 值传递。如果你想传递一个长 double ,你必须指定你的 1.2 实际上是一个长 double ,这就是 L 的用途。如果您最终传递了一个 double 值,但期望得到一个长 double 值,则您将无法获得您期望的值。

我找不到对此的理想引用,但是 this page还不错,并且these pages都不错,但都是关于 C++,而不是 C。

如果这不能解决您的问题,请发布一个完整的、可编译的程序,该程序没有达到您的预期。

关于c - 如何使用 va_arg "extract"长 double ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53450940/

相关文章:

c++ - 作为可变参数模板的结构化参数

c++ - 可变模板函数重载失败

c++ - 想要在Hudson C/C++上工作

scala - Scala 宏的静态返回类型

MySQL非常长的数字数据类型

c# - 参数索引器的实际使用

c - 读取写入管道的信息后无法退出 while 循环

使用 malloc 创建指向指针的指针

c - c 中的大小和数组

types - 设计模式 : Question about "Types"