4

当我declared as array of references of type float&将函数声明为时,XCode 中出现错误:

void calcCoeff(float sigma, float& ap[], float& bp[], float& an[], float& bn[]);

谁能告诉我可能是什么问题?我也试过

void calcCoeff(float sigma, float &ap[5], float &bp[5], float &an[5], float &bn[5]);

谢谢...

4

2 回答 2

6

问题与错误消息所描述的完全一样:float& ap[]声明了一个引用数组,这不是 C++ 中的合法类型,就像禁止引用的指针和引用的引用一样。

如果它是合法的,您可以通过考虑指针数组来思考它的含义。引用在某些方面在概念上类似于指针。引用旨在引用另一个实体,当引用需要运行时表示时,C++ 实现通常使用指针。

因此,如果要将指针数组传递给函数,则需要构造一个初始化它:

float a, b, c;
float *arr[] = {&a, &b, &c};    // or in fictional array-of-references syntax: float &arr[] = {a, b, c};

或者,如果您已经有一个浮点数组,并且您想要一个指向这些元素的指针数组:

float a[3];
float *b[] = {&a[0], &a[1], &a[2]);     // or in fictional array-of-references syntax: float &b[] = {a[0], a[1], a[2]};

大概您真正想要的是通过引用将数组传递给函数,以便函数可以写入数组并且调用者可以看到更改。(或者仅仅是因为你想避免复制数组)。由于通常函数参数是按值传递的,而通过引用传递的方法是坚持&在那里,你对数组类型也做了同样的事情。这是一个很好的直觉,但是 C++ 中有一些皱纹让你搞砸了。

第一个是 C++ 中声明的奇怪语法。您可以在其他地方阅读有关“螺旋规则”或“声明模仿使用”的信息,但只要说它是否&“更接近”(在语法上)变量名或float. float &arr[]是一个引用数组。您需要几个括号来将 & 符号更靠近变量:float (&arr)[]声明对数组的引用。

接下来是 C++ 不幸地从 C 继承了一些奇怪的行为,旨在使数组和指针几乎可以互换。您的情况下的相关行为是,如果您声明一个采用数组参数的函数:

void foo(int arr[], int size);

该语言明确表示该类型被“调整”为指针。结果与以下相同:

void foo(int *arr, int size);

这意味着数组的行为不像值类型。尝试“按值”传递数组不会导致将数组的可修改副本传递给函数;相反,该函数有效地“通过引用”接收数组。

第二个后果是数组参数不需要具有完整的数组类型,即可以省略数组大小,因为调整了数组类型并且无论如何都不会使用大小。这意味着,如果您天真地将未指定大小的“数组参数”转换为对数组的引用,则除了添加&. float (&arr)[10].


在我看来,使用原始数组作为参数是非常不可取的。首先是因为它丢弃了类型信息:

void foo(int arr[10]) { // same as void foo(int *arr)
    int x = arr[9];
}

int bar[3];
foo(bar); // no compile error! the special array rules discarded the size of the array

并且由于原始数组与其他内置类型不一致,所有这些都具有值语义。由于这些原因,应避免使用原始数组。相反,您可以使用std::arraywhich 避免内置数组的所有“特殊”规则,因此其行为与内置数组一样。

void foo(std::array<int, 10> arr); // Takes arr by value, modifications will not be visible externally

std::array<int, 3> bar;
foo(bar); // compile error

如果您需要一个动态大小的数组,那么您可以使用它std::vector

于 2013-01-14T17:16:07.023 回答
2

将其更改为:

void calcCoeff(float sigma, float ap[], float bp[], float an[],
               float bn[]);

您将能够很好地修改这些值。函数参数中的[]符号等价于指针。所以它和这个是一样的:

void calcCoeff(float sigma, float* ap, float* bp, float* an,
               float* bn);

这意味着在这两种情况下,您都会获得指向数据的指针而不是副本。[]语法只是一种风格决定;尽管float a[]与 的含义相同float* a,但[]语法是对函数调用者的暗示,它可以在数组而不是单个变量上工作。

于 2013-01-14T15:53:05.100 回答