简体   繁体   English

&(* a)在c ++中的操作,反直觉?

[英]the &(*a) operation in c++, counter-intuitive?

in this code: 在这段代码中:

  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;

I get: 我明白了:

*a = 5
 a = 0x83a2008
 b =0x83a2008
 d = 0xbfbfe540

why is d different from b? 为什么d与b不同? Aren't they both &(*a) ? 他们俩都不是&(* a)? how can I get the d result with a single line? 如何用一行得到d结果?

Thanks a lot. 非常感谢。

a points to a dynamically allocated location, holding the value 5. When you do c = *a; a指向动态分配的位置,保持值为5.当你执行c = *a; , you're copying the value 5 from that dynamically allocated location into c . ,您将 5从动态分配的位置复制到c You're then taking the address of c and assigning it to d (and printing it out). 然后你获取c的地址并将其分配给d (并将其打印出来)。

When you end up with is something like this: 当你最终得到这样的东西:

在此输入图像描述

The solid lines indicate a pointer referring to a location. 实线表示指向位置的指针。 The dashed line indicates movement of data. 虚线表示数据的移动。

c is its own int and not an int* . c是它自己的int而不是int* When you say c = *a , you're actually assigning the value pointed to by a to a separate integer with its own space in memory (even though this int is not an int* , it still has to exist somewhere in memory). 当你说c = *a ,你实际上是将a指向的值赋给一个单独的整数,并在内存中有自己的空间(即使这个int不是int* ,它仍然必须存在于内存中的某个地方)。

So when you say d = &c , you're getting the address of c , not the value of a . 所以,当你说d = &c ,你得到的地址c ,不值a

After

d = &c;

d points to the storage location designated by c , which is not the storage location pointed to by a . d指向由c指定的存储位置,该位置不是a指向的存储位置。

d is the address of c which is a local stack variable. d是c的地址,它是本地堆栈变量。 b is the address of the integer you allocated on the heap and stored the address of in a. b是您在堆上分配的整数的地址,并存储在a中的地址。

c is new instance of integer that's why d is not equal a nor b . c是整数的新实例,这就是d不等于ab So when You try to get address of value stored in a you get exactly address of a . 所以,当你尝试获取存储在值地址a你得到的确切地址a But when you first assign value of a to c and then print address of c you get different address than a . 但是,当你第一次分配的值ac ,然后打印的地址c你比得到不同的地址a In C++ you operate on real objects not references like in Java or C#. 在C ++中,您对真实对象进行操作,而不是像Java或C#中那样引用。 when you assign value to variable you copy every filed stored in this variable, but be careful - by default = operator don't do deep cloning. 当您为变量赋值时,您复制存储在此变量中的每个字段,但要小心 - 默认情况下=运算符不进行深度克隆。

I think there is something in C11/C99 Section 6.5.3.2 Paragraph 4 and footnote 102 我认为C11 / C99第6.5.3.2节第4段和脚注102中有一些内容

a pointer to the object or function designated by its operand. 指向由其操作数指定的对象或函数的指针。 The unary * operator denotes indirection. 一元*运算符表示间接。 If the operand points to a function, the result is a function designator; 如果操作数指向函数,则结果是函数指示符; if it points to an object, the result is an lvalue designating the object. 如果它指向一个对象,则结果是指定该对象的左值。 If the operand has type ''pointer to type'', the result has type ''type'' . 如果操作数的类型为''指向类型'',则结果的类型为''type'' If an invalid value has been assigned to the pointer, the behavior of the unary * operator is undefined.102) 如果为指针分配了无效值,则unary *运算符的行为未定义.102)

And footnote 102 tells 脚注102告诉我们

102) Thus, &*E is equivalent to E (even if E is a null pointer), and &(E1[E2]) to ((E1)+(E2)) . 102) 因此,&* E等效于E(即使E是空指针),和(E1 [E2])等于((E1)+(E2)) It always true that if E is a function designator or an lvalue that is a valid operand of the unary operator, *&E is a function designator or an lvalue equal to E. If *P is an lvalue and T is the name of an object pointer type, *(T)P is an lvalue that has a type compatible with that to which T points. 总是如果E是函数指示符或者是一元运算符的有效操作数的左值,*&E是函数指示符或等于E的左值。如果* P是左值而T是对象的名称指针类型,*(T)P是一个左值,其类型与T指向的类型兼容。 Among the invalid values for dereferencing a pointer by the unary * operator are a null pointer, an address inappropriately aligned for the type of object pointed to, and the address of an object after the end of its lifetime. 在由一元*运算符解除引用指针的无效值中,有一个空指针,一个与指向的对象类型不适当对齐的地址,以及一个对象在其生命周期结束后的地址。 is & 是&

EDIT c = *a; 编辑 c = *a; will result in an undefined behaviour, as the memory location 5 is not allocated. 将导致未定义的行为,因为未分配内存位置5。

I don't know all the rules and subtleties that go into this, but the compiler is able to simplify &(*a) to just be a . 我不知道所有的规则和细微之处,但编译器能够简化&(*a)只是a So you are initializing b to point at the same integer that a points at ( b = a ). 所以你要初始化b指向与( b = a )处a点相同的整数。 Then you are copying the integer by value to c . 然后,您将按值将整数复制到c Then you are initializing d to point at c . 然后你正在初始化d指向c So a and b point to the same integer, but d points to something else. 所以ab指向相同的整数,但d指向其他东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM