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
的值增加1int[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;