Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/32.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么*(pa-1)的输出是'a'的最后一个元素?_C++ - Fatal编程技术网

C++ 为什么*(pa-1)的输出是'a'的最后一个元素?

C++ 为什么*(pa-1)的输出是'a'的最后一个元素?,c++,C++,我从下面代码的输出中得到的是*(pa-1)=5:为什么 #include<iostream> using namespace std; int main(){ int a[5]={1,2,3,4,5}; int *pa=(int *)(&a+1); cout<<"*(pa-1)="<<*(pa-1)<<endl; } #包括 使用名称空间std; int main(){ int a[5]={1,2,3,4

我从下面代码的输出中得到的是
*(pa-1)=5
:为什么

#include<iostream>

using namespace std;

int main(){

    int a[5]={1,2,3,4,5};
    int *pa=(int *)(&a+1);

    cout<<"*(pa-1)="<<*(pa-1)<<endl;

}
#包括
使用名称空间std;
int main(){
int a[5]={1,2,3,4,5};
int*pa=(int*)(&a+1);

cout
&a
是数组的地址,它的类型为“指针指向-
int[5]
”。因此
&a+1
前进五个点的整个数组,刚好经过数组

pa
是一种类型双关指针*,它现在将同一地址视为整数数组(而不是数组!)中的地址。因此,它与结束指针
a+5
之后的地址相同。减1表示数组中最后一个元素的指针,即
5


*)这种类型的双关是可以接受的,只要数组的底层类型是标准布局(即
int
),它就可以满足您的要求。

您还需要什么?
&a
具有类型
int(*)[5]
,因此
&a+1
点 到
a
之后的下一个
int[5]
;它是 迭代
int[5]
元素。然后
将其重新解释为
int*
,并访问它。正式地说,我认为您的代码没有定义 行为,因为这是你唯一可以合法处理结果的事情 一个
重新解释的类型是将其转换回原始类型。
(在涉及到字符类型指针的情况下也有例外。)
在实践中,各种要求贯穿于整个标准

这意味着您将获得
a

中最后一个
int
的地址,因为您正在将指向int数组的指针强制转换为指向int@DanF:只要
T
是标准布局,
(T*)[N]
可转换为
T*
,并给出第一个元素的地址。数组是特殊的:
a
是它自己的地址,
&a
=
a
-虽然类型不同。写得不错。@RichardSitze:是的,很多东西都有相同的地址。是类型和值对指定了唯一的对象。您可以很容易地列出一长串降序子对象,这些子对象也都有相同的地址。@RichardSitze,C标准并不禁止使用
运算符的
地址获取指向数组的指针,它会生成
类型(*)的指针[N]
。答案是正确的。@HristoIliev:我不认为Richard在抱怨。他只是指出数组是唯一的,因为变量名本身可以充当与对象地址相同值的地址,尽管类型不同。他可能应该说
(void*)(a)==(void*)(&a)
,尽管:-)@RichardSitze与我所见过的任何东西(包括标准)都不符。
a
的类型是
int[5]
&a
的类型是
int(*)[5]
(int*)[5]
不是合法的类型表达式。
&a
的类型是
int(*)[5]
,一个指向5个
int
数组的指针。类型是
int(*)[5]
。语法见C99标准的§6.7.6。@KerrekSB修复了它:-)。(我想我一定是在发布之前意外地错编了一些内容。可能是
a
有type
int[5]
,所以
&a
有type
int(*)[5]
)可以肯定的是,我认为这不是UB,因为当类型为标准布局时,允许将指向对象的指针视为指向第一个成员或元素的指针。@KerrekSB这可能在C++11中发生了更改。至少在之前,这是未定义的行为:C标准是精心设计的,以允许“fat”指针,包括边界信息(也可能是一些类型信息),以便完全检查实现是可能的。早期C++也允许这样做,并且至少有一个编译器在过去实现它。