C++ 如何使用指针编写参数数目可变的函数?

C++ 如何使用指针编写参数数目可变的函数?,c++,function,variables,arguments,C++,Function,Variables,Arguments,因此,我有一项任务,就是使用指针编写一个参数数目可变的函数mult。这个函数必须计算浮点数的乘积 我遵循了大学给我们的指南,但我的产品仍然等于零。我发现问题是,每乘以一个其他的数字,就等于零 #include <iostream> using namespace std; int mult(int k,...){ int* p = &k; int m = 1; for(; k != 0; k--){ m *= *(++p);

因此,我有一项任务,就是使用指针编写一个参数数目可变的函数mult。这个函数必须计算浮点数的乘积

我遵循了大学给我们的指南,但我的产品仍然等于零。我发现问题是,每乘以一个其他的数字,就等于零

#include <iostream>


using namespace  std;

int mult(int k,...){
    int* p = &k;
    int m = 1;
    for(; k != 0; k--){
        m *= *(++p);
    }
    return m;
}

int main(){
    float res1 = mult(11,45,10,9,8,7,6,5,4,3,2,2);
    float res2 = mult(7,12,23,0.3,0.6,1,2);
    float res3 = mult(3,0.6,-12,-0.9);
    cout << "Your results are:\n"
         <<res1<<"\n"
         <<res2<<"\n"
         <<res3<<"\n";

    return 0;
}
您可以将mult编写为一个可变函数,并使用std::acculate和std::multiples作为运算符

#include <functional>
#include <initializer_list>
#include <iostream>
#include <numeric>

template<typename T, typename... Args>
T mult(T t, Args... args)
{
    std::initializer_list<T> values{args...};
    return std::accumulate(values.begin(), values.end(), t, std::multiplies<T>());
}

int main()
{
    std::cout << mult<float>(11,45,10,9,8,7,6,5,4,3,2,2);
    return 0;
}
您可以将mult编写为一个可变函数,并使用std::acculate和std::multiples作为运算符

#include <functional>
#include <initializer_list>
#include <iostream>
#include <numeric>

template<typename T, typename... Args>
T mult(T t, Args... args)
{
    std::initializer_list<T> values{args...};
    return std::accumulate(values.begin(), values.end(), t, std::multiplies<T>());
}

int main()
{
    std::cout << mult<float>(11,45,10,9,8,7,6,5,4,3,2,2);
    return 0;
}

我会对这个代码的有效性有很多担心

是在寄存器或堆栈上传递的椭圆参数。对于64位,表示第一对指针/int/etc在寄存器中传递。 即使椭圆参数在堆栈上传递,k也肯定不是,它将被放置在寄存器中。所以你不能记下它的地址。 椭圆参数是,这意味着所有浮点数都转换为双精度,所以当您尝试转换为int时,会得到半个双精度。
我认为这仅仅是因为一些未定义的行为,如果有的话,我甚至怀疑这一点,因为pt。3.

我会对这个代码的有效性有很多担心

是在寄存器或堆栈上传递的椭圆参数。对于64位,表示第一对指针/int/etc在寄存器中传递。 即使椭圆参数在堆栈上传递,k也肯定不是,它将被放置在寄存器中。所以你不能记下它的地址。 椭圆参数是,这意味着所有浮点数都转换为双精度,所以当您尝试转换为int时,会得到半个双精度。 我认为这仅仅是因为一些未定义的行为,如果有的话,我甚至怀疑这一点,因为pt。3.

如果必须使用指针,这里有一个解决方案:

包括 包括 包括 包括 包括 样板 穆尔特,阿格斯。。。args { std::unique_ptr p=std::make_uniquestd::initializer_list{args…}; 返回std::累加ep->begin,p->end,t,[]自动a,自动b{返回a*b;}; } int main { std::cout好吧,如果必须使用指针,这里有一个解决方案:

包括 包括 包括 包括 包括 样板 T multT T,Args…Args { std::unique_ptr p=std::make_uniquestd::initializer_list{args…}; 返回std::累加ep->begin,p->end,t,[]自动a,自动b{返回a*b;}; } int main { std::cout与您描述的C++17函数类似,创建起来非常简单:

template<typename... Args>
auto mult(Args... args)
{
    // Parenthesis are required
    return (... * args); 
}
可以使用任何二进制运算符替换乘法:

// Sum
return (... + args);

// and
return (... && args);
您还可以使用这些执行相当复杂的操作:

template<typename T, typename... Args>
void comma_sep_print(const T& first, const Args&... args)
{
    std::cout << first;
 
    // Fold over comma operator
    ((std::cout << ", " << args), ...) << '\n'; 
}

comma_sep_print(1, 2, 3);
// Outputs: 1, 2, 3
使用C++17函数,如您所述,创建起来非常简单:

template<typename... Args>
auto mult(Args... args)
{
    // Parenthesis are required
    return (... * args); 
}
可以使用任何二进制运算符替换乘法:

// Sum
return (... + args);

// and
return (... && args);
您还可以使用这些执行相当复杂的操作:

template<typename T, typename... Args>
void comma_sep_print(const T& first, const Args&... args)
{
    std::cout << first;
 
    // Fold over comma operator
    ((std::cout << ", " << args), ...) << '\n'; 
}

comma_sep_print(1, 2, 3);
// Outputs: 1, 2, 3

你不认为使用指针在这里意味着你应该把指针作为参数吗?你的大学的指导是由不知道C++的人编写的。C++使用模板函数来实现这个目的。这是一个练习吗?你的要求完全是向后的。另外,我应该计算数字的乘积。什么是实际需求?写一个函数来计算一些浮动的乘积?或者使用指针?在C++中,我会热情地推荐一个模板,用它可以用安全性和编译时间检查来编写这些函数。在C语言中使用,它不能提供这些功能,因此总是容易出错。如果您将指南的代码与中描述的代码进行比较,您可能会得出与我相同的结论:指南的此代码是错误的。在特定平台上的特定编译器在某些条件下,它最多只能使用实现dEnkes,但它不是标准的符合代码既不在C也不在C++。你不认为使用指针在这里意味着你应该通过指针作为参数?你的指南在你的大学是由不知道C++的人编写的。C++使用模板函数来实现这个目的。这是一个练习吗?IMPO你的要求完全是向后的。改写:我的TAKS是使用指针,写一个函数,它需要多个参数。另外,我应该计算数字的乘积。什么是实际需求?写一个函数来计算一些浮点的乘积?或者使用指针?在C++中,我会热情地推荐一个模板,用它来写这样的函数。键入安全和编译时检查。这取代了C中使用的旧方法,C中无法提供这些功能,因此总是容易出错。如果您将指南的代码与中描述的代码进行比较,您可能会得出与我相同的结论:指南的此代码是错误的。I 在特定的条件下,T可以在特定的平台上使用最佳编译器,但它不符合标准的符合代码,既不在C中也不在C++中。