Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.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++ 政府;(*a)在c&x2B中的操作+;,违反直觉?_C++ - Fatal编程技术网

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;