为啥此代码显示“无法将 'double' 转换为 'double*'”错误?

Posted

技术标签:

【中文标题】为啥此代码显示“无法将 \'double\' 转换为 \'double*\'”错误?【英文标题】:Why does this code show the "cannot convert 'double' to 'double*'" error?为什么此代码显示“无法将 'double' 转换为 'double*'”错误? 【发布时间】:2014-09-14 02:33:08 【问题描述】:

考虑这段代码:

double dist(double x[3], double y[3])

    double Sum;
    double distance;

    for(int i=0; i<3; i++)
    
        cout << "Enter value of first coordinate";
        cin >> x[i];
        cout << "Enter value of second coordinate";
        cin >> x[i];

        Sum = Sum + pow((x[i] - x[i]), 2.0);
        distance = (int)sqrt(Sum);
    
        cout << "DISTANCE: " << distance;
    return distance;


int main()

    int i, n;
    double x[3]; double y[3];
    cout << "enter number of test case" << endl;
    cin >> n;
    for(i=0; i<n; i++)
    
        dist(x[i], y[i]);
    
    return 0;

dist(x[i], y[i])这行一直报错

无法将参数 '1' 的 'double' 转换为 'double*' 到 'double dist(double*, double*)'

【问题讨论】:

Sum = Sum + pow((x[i]-x[i]),2.0); 您使用了两次x[i]。你是这个意思吗? dist 需要一个包含三个双精度值的数组。 x[i] 只是一个双精度值。 @IgorTandetnik 从技术上讲,dist 需要两个指向 doubles 的指针。 3 毫无意义。 @T.C.我知道。我试图避免增加已经大量存在的混乱。此外,说dist 期望一个包含三个双精度数的数组作为其合同的一部分也许是正确的,无论这一事实在其签名中表达得多么好。 Sum也需要初始化。 【参考方案1】:

这不是将数组传递给函数的方式:

for (i = 0; i < n; i++) 
    dist(x[i], y[i]);

您可能认为您使用包含来自x[0..n-1] 的所有值的数组调用函数dist 一次(对于y 也是如此)。事实并非如此。由于您处于循环中,因此您调用该函数的次数与循环运行的次数一样多,在本例中为 n 次。

此外,作为参数传递给函数的值是double 类型的元素。这不是您以为您提供的数组。


而且我知道错误消息看起来很奇怪。 “double*来自哪里?”你可能问过自己。答案很简单:

数组不能传递给函数。

由于所谓的“类型衰减”,当在表达式中使用数组时,它们会被转换为指向其第一个元素(基地址)的指针。 dist (dist(double x[3], double y[3]) 的参数类型与dist(double* x, double* y) 完全相同。这意味着当您错误地尝试将 double 传递给函数时,编译器报告您无法将它们转换为指针。

传递数组的名称将传递一个指向第一个元素的指针。这将解决您的主要问题:

dist(x, y);

您仍然可以在指针上使用下标运算符x[n] 的原因是因为下标运算符是*(x + n) 的语法糖。也就是说,一个指针偏移了n 加上一个解引用来给你那个地址的值。


这种类型衰减还带来了另一个问题:由于数组被转换为指针,因此无法确定其类型附带的大小信息。你可以有一个函数,它接受一个double[100] 并将一个包含 1 个元素的数组传递给它,因为当数组衰减到一个指针时,它们的类型完全匹配。有几种方法可以解决这个问题:

使参数成为函数的引用/指针 使用标准库数组类

现在,a pointer and a reference are two different things, 但它们仍然可以用来解决这个问题。使用对数组的引用与实际传入数组本身不同。引用充当对象的别名,它们基本上是引擎盖下的指针,但有一些例外(请参阅提供的链接)。参考对于我们的示例来说已经足够了,但是它看起来是这样的:

double dist(double (&x)[3], double (&y)[3]);

这里不会发生类型衰减,而且你有一个保证大小,因为如果传入任何其他大小的数组,编译器会报错。

参考很有用,但对于初学者来说可能不太好。幸运的是,标准库为我们提供了一个数组类std::array。不需要奇怪的语法,它有一个更干净的界面 - 没有指针!

#include <array>
double dist(std::array<double, 3> x, std::array<double, 3> y);

std::array<double, 3> x, y;
dist(x, y);

【讨论】:

【参考方案2】:

您的 dist 函数已经循环了 3 次。 你可能想摆脱main()中的循环

  cin>>n;
  dist(x,y);
  return 0;

这样,x 和 y 都是double*

只是在这里猜测你的意图

【讨论】:

【参考方案3】:

只要打电话

dist(x, y);

实际上,您是从数组中传递双精度值,而不是数组本身。

【讨论】:

以上是关于为啥此代码显示“无法将 'double' 转换为 'double*'”错误?的主要内容,如果未能解决你的问题,请参考以下文章

为啥此代码不会显示 Android 设备方向更改?

为啥此 SwiftUI 代码在目标屏幕中显示“空”?

为啥此代码显示参数索引超出范围异常? [复制]

在此代码中,对于 while 循环内的条件,错误显示“除以零”。为啥会这样?

为啥此裁剪代码会导致图像旋转?

为啥显示此错误?发送到客户端后无法设置标头