【问题标题】:C++, static array, pointer, lengthC++,静态数组,指针,长度
【发布时间】:2018-04-03 21:05:33
【问题描述】:

有人可以向我解释为什么这段代码有效吗?!!

我知道 A 持有 &A[0],它不是一个真正的指针,就像你 cout

int main()
{
    double A[] = {2.4, 1.2, 4.6, 3.04, 5.7};
    int len =  *(&A+1) - A; // Why is this 5?
    cout << "The array has " << len << " elements." << endl;
    return 0;
} 

为什么这段代码不起作用?以及如何让它发挥作用?

void test(double B[])
{
  int len = *(&B+1) - B;
  cout << len << endl;

}
int main()
{
    double A[] = {2.4, 1.2, 4.6, 3.04, 5.7};
    test(A);
    system("pause");
    return 0;
} 

【问题讨论】:

  • 我相信 &amp;A 在这种情况下具有 double[5]* 类型
  • 或者你可以使用 std::vector :-)
  • 你是一个普遍误解的受害者,即 &amp;A&amp;A[0] 是相同的东西,而实际上它们不是。
  • @pm100 很遗憾不能对 cme​​ts 投反对票。如果有人无法理解 C++ 中指向数组的指针是如何工作的,那么使用 std::vector 不是解决方案。
  • 考虑到这里有两位精通评论者声称代码导致了 UB,这确实是一个很好的建议。不过我会换一种说法:找到更清洁的解决方案(例如使用std::vectorstd::array)!但是,知道&amp;A&amp;A[0] 不同是这里最有价值的信息。

标签: c++ arrays pointers pointer-arithmetic


【解决方案1】:

表达式解析如下:

(*((&A) + 1)) - A

可能令人烦恼的部分是,对于该表达式的某些(但不是全部!)部分,数组衰减为指向第一个元素的指针。所以,让我们打开这个:

  1. 首先获取数组的地址,它会为您提供一个指向包含五个元素的数组的指针。

  2. 然后,指针递增 (+ 1),给出紧跟数组的地址。

  3. 第三,指针被取消引用,这产生了对一个包含五个元素的数组的引用。

  4. 最后,数组被减去。只有在这里,两个操作数才真正衰减为指向它们的第一个元素的指针。两者是数组分开的长度,它给出了元素的数量作为距离。

【讨论】:

  • 技术上的尊重不是 UB 吗?
  • 需要注意的是 *(&amp;A + 1) 是 UB。
  • 我其实不知道。我知道允许在数组末尾使用元素的地址(not 访问内存)来形成“结束”迭代器。由于这里没有读取内存,我可以想象它是有效的。
  • 是的,它是 UB。形成一个过去的指针是一回事。取消引用它是另一回事。那些声称&amp;*identity 拯救世界的人是错误的。
  • 如果您可以为此提供参考,@LightnessRacesinOrbit,请将其作为答案。你会得到我的支持。
【解决方案2】:

&amp;A 获取A 本身的地址。 A 的类型是double[5]

当您获取A 本身的地址并将该指针增加1 时,您将其增加sizeof(double[5]) 字节。所以现在你有了一个指向A 数组后面的地址的指针。

当您取消引用该指针时,您将引用A 之后的下一个double[5] 数组,这实际上也是一个指向A[5] 地址的double* 指针。

然后减去A[0] 的地址(数组衰减为指向其第一个元素的指针),标准指针算法为您提供 5 个元素:

&A[5] - &A[0] = 5

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-03
    • 1970-01-01
    • 1970-01-01
    • 2017-11-15
    • 1970-01-01
    • 2017-05-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多