C++ 政府;(*a)在c&x2B中的操作+;,违反直觉?
在此代码中:C++ 政府;(*a)在c&x2B中的操作+;,违反直觉?,c++,C++,在此代码中: int* a; int* b; int c; int* d; a=new int(5); b=&(*a); c=*a; d=&c; cout<<"*a = "<<*a<<endl; cout<<"a = "<<a<<endl; cout<<"b ="<<b<<endl; cout<<"d = "<
int* a;
int* b;
int c;
int* d;
a=new int(5);
b=&(*a);
c=*a;
d=&c;
cout<<"*a = "<<*a<<endl;
cout<<"a = "<<a<<endl;
cout<<"b ="<<b<<endl;
cout<<"d = "<<d<<endl;
为什么d和b不同?他们不是都是&(*a)吗?如何用一行代码得到d结果
非常感谢。之后
d = &c;
d
指向由c
指定的存储位置,它不是由a
指向的存储位置c
是它自己的int
而不是int*
。当您说c=*a
时,实际上是将a
指向的值赋给一个单独的整数,该整数在内存中有自己的空间(即使该int
不是int*
,它仍然必须存在于内存中的某个地方)
因此,当你说
d=&c
时,你得到的是c
的地址,而不是a
d是作为本地堆栈变量的c的地址。b是您在堆上分配的整数的地址,并将其存储在a中。a
指向动态分配的位置,保留值5。当你做c=*a
,您正在将值5从动态分配的位置复制到c
。然后,您将获取c
的地址并将其分配给d
(并将其打印出来)
当你以这样的方式结束时:
实线表示指向某个位置的指针。虚线表示数据的移动。我不知道其中的所有规则和细节,但编译器能够将
&(*a)
简化为a
。因此,您正在初始化b
以指向a
指向的同一整数(b=a
)。然后将整数按值复制到c
。然后您正在初始化d
以指向c
。因此,a
和b
指向同一个整数,但d
指向另一个整数。c
是整数的新实例,这就是为什么d
不等于a
或b
。因此,当您尝试获取存储在a
中的值的地址时,您将获得a
的确切地址。但当您首先将a
的值赋给c
然后打印c
的地址时,您得到的地址与a
不同。在C++中,你对真实对象进行操作,而不是java或C语言中的引用。当您为变量赋值时,您会复制存储在此变量中的每个字段,但要小心-默认情况下,=
运算符不进行深度克隆 我认为C11/C99第6.5.3.2节第4段和脚注102中有一些内容
指向由其操作数指定的对象或函数的指针。这个
一元*运算符表示间接。如果操作数指向
函数,结果是函数指示符;如果它指向一个
对象,结果是指定该对象的左值如果操作数
类型为“指向类型的指针”,结果类型为“类型”。如果
为指针指定了无效值,该指针的行为
一元*运算符未定义。102)
脚注102说明了这一点
102)因此,&*E等同于E(即使E是空指针),并且
&(E1[E2])到((E1)+(E2))。如果E是一个函数
一元运算符的有效操作数的指示符或左值,
*&E是函数指示符或等于E的左值。如果*P是左值,T是对象指针类型的名称,*(T)P是左值
具有与T指向的类型兼容的类型。在人群中
一元*运算符取消引用指针的值无效
一个空指针,一个地址对类型的
指向的对象,以及对象结束后的地址
一生。是&
编辑
c=*a代码>将导致未定义的行为,因为未分配内存位置5 c
的值是a
的值,但不是a
的地址。当您执行d=&c
时,您已经获得c
的地址d
指向c
。是什么让你认为c
和*a
存储在同一个地方?@LynnCrumbling作业标签被擦掉了。@phoxis谢谢你提供的信息;有人替换吗?@LynnCrumbling:没有。
d = &c;