在此代码中:
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;
我明白了:
*a = 5
a = 0x83a2008
b =0x83a2008
d = 0xbfbfe540
为什么d与b不同?他们俩都不是&amp;(* a)?如何用一行得到d结果?
非常感谢。
答案 0 :(得分:7)
a
指向动态分配的位置,保持值为5.执行c = *a;
时,您将值 5从动态分配的位置复制到{ {1}}。然后,您将获取c
的地址并将其分配给c
(并将其打印出来)。
当你最终得到的是这样的:
实线表示指向位置的指针。虚线表示数据的移动。
答案 1 :(得分:6)
c
是它自己的int
而不是int*
。当您说c = *a
时,您实际上是将a
指向的值分配给内存中具有自己空间的单独整数(即使此int
不是int*
},它仍然必须存在于内存中。)
因此,当您说d = &c
时,您获得的地址为c
,而不是a
的地址。
答案 2 :(得分:1)
在
d = &c;
d
指向c
指定的存储位置,该位置不是a
指向的存储位置。
答案 3 :(得分:1)
d是c的地址,它是本地堆栈变量。 b是您在堆上分配的整数的地址,并将地址存储在。
中答案 4 :(得分:1)
c
是整数的新实例,这就是d
不等于a
或b
的原因。因此,当您尝试获取存储在a
中的值的地址时,您会获得a
的确切地址。但是,当您首先将a
的值分配给c
然后打印c
的地址时,您获得的地址与a
不同。在C ++中,您对真实对象进行操作,而不是像Java或C#中那样引用。当您为变量赋值时,您复制存储在此变量中的每个字段,但要小心 - 默认情况下=
运算符不进行深度克隆。
答案 5 :(得分:1)
我认为C11 / C99第6.5.3.2节第4段和脚注102中有一些内容
指向由其操作数指定的对象或函数的指针。该 一元*运算符表示间接。如果操作数指向a 功能,结果是功能指示符;如果它指向一个 对象,结果是指定对象的左值。 如果是操作数 类型''指向类型'',结果类型为''type''。如果 无效值已分配给指针,行为 unary * operator is undefined .02)
脚注102告诉
102)因此,&amp; * E等效于E(即使E是空指针), &amp;(E1 [E2])至((E1)+(E2))。如果E是一个函数,那总是如此 指示符或左值运算符的有效操作数的左值, *&amp; E是函数指示符或等于E的左值。如果* P是左值而T是对象指针类型的名称,*(T)P是左值 具有与T指向的类型兼容的类型。之间 一元*运算符取消引用指针的值无效 一个空指针,一个不恰当地对齐类型的地址 object指向的对象,以及对象结束后的地址 一生。是&amp;
修改强>
c = *a;
将导致未定义的行为,因为未分配内存位置5。
答案 6 :(得分:0)
我不知道所有的规则和细微之处,但编译器能够将&(*a)
简化为a
。因此,您要初始化b
以指向a
指向(b = a
)的相同整数。然后,您将按值将整数复制到c
。然后,您正在初始化d
以指向c
。因此a
和b
指向相同的整数,但d
指向其他整数。