C/C++ va_list不能正确返回参数

4

我在使用va_list时遇到了问题。以下代码适用于int:

main() {
  int f1=1;
  float** m = function(n,f1);
}

float** function(int n,...) {

  va_list mem_list;
  va_start(mem_list, n);
  for (int i=0;i<n;i++) {
    for (int j=0;j<n;j++) {
      //m[i][j]=va_arg(mem_list,float);
      int f = va_arg(mem_list,int);
      printf("%i \n",f);
    }
  }

  va_end(mem_list);
  return NULL;
}

然而,当我将其更改为浮点数时,即:
float f1=1.0;
float f = va_arg(mem_list,float);
printf("%f \n",f);

它没有返回正确的值(值为0.00000)。我对发生的事情感到非常困惑。

2个回答

8
在可变参数调用的上下文中,float 实际上被提升为 double。因此,您需要实际获取 double,而不是 float。这也是为什么 %f 对于 printf() 适用于 floatdouble 的原因。

很好的并行于%f -> printf(),它确实提升了浮点数。 - ScarletAmaranth

3

由于我们在讨论C++,您可能希望使用更新的C++11设施。

我可以建议使用可变模板,但这可能有点过于高级。另一方面,现在有一个 std::initializer_list<T> 可以传递任意长的列表,其中T是一个简单的类型。

 void function(std::initializer_list<int> list);

它没有太多的功能,只有:

  • size(),返回列表中元素的数量
  • begin()end(),像往常一样返回迭代器

所以你实际上可以这样做:

void function(std::initializer_list<int> list) {
    std::cout << "Gonna print " << list.size() << " integers:\n";

    bool first = true;
    for (int i: list) {
        if (first) { first = false; } else { std::cout << ", "; }
        std::cout << i;
    }
    std::cout << "\n";
}

然后按以下方式调用:

int main() {
    function({1, 2, 3, 4, 5});
}

这将会打印:

Gonna print 5 integers:
1, 2, 3, 4, 5

一般来说,在C++中,应避免使用C-variadic。它们不安全且易出错。


谢谢你的回答,但我也需要将代码移植到Objective-C,因此我仍然坚持使用标准的ANSI C。 - user1422573
很抱歉,我加了C++标签是因为我使用的是C++编译器。 - user1422573

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接