*(&arr + 1) - arr 如何给出数组 arr 元素的长度?

joh*_*n_w 8 c++ arrays

#include <iostream>
using namespace std;

int main() { 
   int  arr[5] = {5, 8, 1, 3, 6};
   int len = *(&arr + 1) - arr;
   cout << "The length of the array is: " << len;
   return 0;
} 
Run Code Online (Sandbox Code Playgroud)

对于上面的代码,我不太明白这两段代码是做什么的:

*(&arr + 1) 
Run Code Online (Sandbox Code Playgroud)

*(&arr)
&arr
Run Code Online (Sandbox Code Playgroud)

有人可以解释一下吗?因为当我运行以下两个代码时,我得到以下相同的输出:

&arr (我认为这指向arr的第一个元素的地址)

*(&arr)那么我不太明白这是做什么的,符号*&arr(即这里的地址)有什么作用?,因为当我运行它们时,两个输出是相同的

最后,当一个整数说 1 被这里的代码添加到地址时,到底发生了什么: &arr + 1

Ted*_*gmo 5

这是一个雷区,但我会尝试一下:

  • &arr返回一个指向int[5]
  • + 1将指针移一int[5]
  • *(&arr + 1)将结果取消引用回int(&)[5]
    我不知道这是否会导致未定义的行为,但如果不会,下一步将是:
  • *(&arr + 1) - arrint[5]在两个衰减为指针后进行指针算术int,返回两个指针之间的差异int,即5

重写以使其更清晰一些:

int  arr[5] = {5, 8, 1, 3, 6};

int (*begin_ptr)[5] = &arr + 0;     // begin_ptr is a  int(*)[5]
int (*end_ptr)[5]   = &arr + 1;     // end_ptr is a    int(*)[5]

// Note:
//       begin_ptr + 1        ==  end_ptr
//       end_ptr - begin_ptr  ==  1

int (&begin_ref)[5] = *begin_ptr;   // begin_ref is a  int(&)[5]
int (&end_ref)[5]   = *end_ptr;     // end_ref is a    int(&)[5]   UB here?

auto len = end_ref - begin_ref; // the array references decay into int*
std::cout << "The length of the array is: " << len << '\n'; // 5
Run Code Online (Sandbox Code Playgroud)

我会留下这个问题,如果它是 UB 或未打开,但在分配引用的存储之前引用一个对象确实看起来有点可疑。

  • 构造一个指向最后一个元素之后的指针就可以了,所以 `&amp;arr + 1` 就可以了。取消引用它是 UB 所以 `*(&amp;arr + 1)` 是不行的。 (3认同)
  • 是的,您正在取消对末尾的引用,这是不允许的。我现在正在努力想出利用相同技术的代码,但找不到任何代码。我即将向语言律师提出问题。 (2认同)
  • 这段代码实际上并没有“取消引用”超过“arr”本身的末尾,而是“创建”一个指向“arr”末尾的指针,但它并没有取消引用该指针来访问“arr”本身的内存。现在,代码使用临时指针,将整个“arr”视为单元素数组以进行“+1”算术,然后取消引用该指针,但因为后备内存是另一个数组,并且这个代码只是操作指针,实际上并没有访问任何内存,我不确定该行为实际上是未定义的...... (2认同)
  • 提出问题:/sf/ask/4286714701/ (2认同)