C++ *(&;arr+;1)-arr如何给出数组arr的元素长度? #包括 使用名称空间std; int main(){ int-arr[5]={5,8,1,3,6}; int len=*(&arr+1)-arr; cout

C++ *(&;arr+;1)-arr如何给出数组arr的元素长度? #包括 使用名称空间std; int main(){ int-arr[5]={5,8,1,3,6}; int len=*(&arr+1)-arr; cout,c++,arrays,C++,Arrays,这是一个雷区,但我要试一试: &arr返回指向int[5] +1步进指针一步int[5] *(&arr+1)将结果解引用回int(&)[5] 我不知道这是否会导致未定义的行为,但如果不会,下一步将是: *(&arr+1)-arr在两个int[5]指针衰减为int指针后,是否执行指针算术,返回两个int指针之间的差值,即5 重写以使其更加清晰: int arr[5] = {5, 8, 1, 3, 6}; int (*begin_ptr)[5] = &arr + 0; //

这是一个雷区,但我要试一试:

  • &arr
    返回指向
    int[5]
  • +1
    步进指针一步
    int[5]
  • *(&arr+1)
    将结果解引用回
    int(&)[5]

    我不知道这是否会导致未定义的行为,但如果不会,下一步将是:
  • *(&arr+1)-arr
    在两个
    int[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
intarr[5]={5,8,1,3,6};
int(*begin_ptr)[5]=&arr+0;//begin_ptr是一个int(*)[5]
int(*end_ptr)[5]=&arr+1;//end_ptr是一个int(*)[5]
//注:
//开始\u ptr+1==结束\u ptr
//结束\u ptr-开始\u ptr==1
int(&begin\u ref)[5]=*begin\u ptr;//begin\u ref是一个int(&)[5]
int(&end_-ref)[5]=*end_-ptr;//end_-ref在这里是一个int(&end)[5]UB吗?
auto len=end\u ref-begin\u ref;//数组引用衰减为int*
std::cout示例:

int  arr[] = {1, 2, 3, 4, 5, 6}; 
int size = *(&arr + 1) - arr; 
在这里,指针算法完成了它的部分。我们不需要显式地将每个位置转换为字符指针

&arr
==>指向6个元素数组的指针。 [有关&arr之间的差异,请参见此 和arr]

(&arr+1)
==>前面6个整数的地址 指针类型是指向数组的指针 由6个整数组成

*(&arr+1)
==>与(&arr+1)相同的地址,但是 指针的类型为“int*”

*(&arr+1)-arr
==>因为*(&arr+1)点 到地址6个整数 在arr之前,差异
鉴于以下事实,二者之间为6.

  • 当您以整数值递增/递减指针时,指针的值将以指针指向的类型字节数的倍数递增/递减

  • 当您减去2个相同类型的指针时,结果是其保留地址之间的差值除以所指向类型的字节数

  • 当您仅以名称引用数组时,它会衰减为指向数组第一个元素的指针

arr
变量的类型是
int[5]
,即一个由5个
int
s组成的数组。
&arr
返回一个
int[5]*
指针,指向
arr
(从技术上讲,它实际上是像
int(*)[5]
一样编写的,但为了简单起见,这里不必担心这一点).让我们调用下面的指针
temp

然后,
+1
temp
的值增加1
int[5]
元素。换句话说,
temp
中存储的地址增加
1*sizeof(int[5])
1*(sizeof(int)*5)
,字节数。这有效地为您提供了
int[5]*
指向
arr
(即指向
&arr[5]
)末尾的指针。该内存地址上不存在
int[5]
元素,但出于指针算法的目的,创建指向该元素的指针是合法的

取消引用
temp
会在
arr
末尾提供对
int[5]
的引用。该引用在传递到
运算符-
时会衰减为
int*
指针

-arr
中,对
arr
的引用在传递给
运算符-
时,会衰减为指向
arr[0]
int*
指针

因此,鉴于这一准则:

int len=*(&arr+1)-arr;

实际上与此相同:

int len=&arr[5]-&arr[0];

实际上与此相同:

int len=(-)/sizeof(int);


因此,结果是5。

*(&arr+1)
调用未定义的行为。此代码不计算数组的长度,它只是中断了,但这如何给出长度:*(&arr+1)-arrUndefined行为意味着任何事情都可能发生。包括意外的预期结果。尽管这可能只是在您的计算机和编译器上,但请尽快忘记此技巧。使用规范的
sizeof(arr)/sizeof(*arr)“Ed/ListCo”。@ TEDLYNGMO,是的,C++中更好。 SeZOOS方法在C和C++中都是有效的,考虑到构造一个指针,过去一个元素是好的,所以<代码>和ARR+ 1 < /代码>可以。
不正常。@bolov是的,我一直盯着我写的东西,并试图说服自己。它仍然无法访问内存,只是类型发生了变化。这有关系吗?是的,你正在取消引用末尾的一个,这是不允许的。我现在非常努力地利用同样的技术来编写代码,但无法完成nd any。我正要问一个语言律师的问题。这段代码实际上并不是从
arr
本身的末尾去引用,而是创建一个指向
arr
结尾的指针,但它不是去引用该指针来访问
arr
本身的内存。现在,这段代码使用了一个临时指针treati为了
+1
算法的目的,将整个
arr
作为一个单元素数组,然后取消对该指针的引用,但由于支持内存是另一个数组,而该代码只是操纵指针,而不是实际访问任何内存,我不确定该行为是否确实未定义……问了一个问题:见鬼o、 为了你的第一次高潮
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
int  arr[] = {1, 2, 3, 4, 5, 6}; 
int size = *(&arr + 1) - arr;