我对解除引用操作符,操作符的地址和一般指针有相当好的理解.
但是当我看到这样的东西时,我感到很困惑:
int* returnA() {
int *j = &a;
return j;
}
int* returnB() {
return &b;
}
int& returnC() {
return c;
}
int& returnC2() {
int *d = &c;
return *d;
}
Run Code Online (Sandbox Code Playgroud)
returnA()
我要求返回一个指针; 只是为了澄清这个作品因为j
是一个指针?returnB()
我要求返回一个指针; 因为指针指向一个地址,所以returnB()
工作的原因是因为我回来了&b
?returnC()
我要求int
归还的地址.当我返回时c
,&
操作员会自动"追加" c
吗?returnC2()
我再问一个int
要归还的地址.是否*d
有效,因为指针指向一个地址?假设a,b,c被初始化为整数为Global.
有人可以验证我的所有四个问题是否正确?
Tyl*_*nry 75
虽然彼得回答了你的问题,但有一点让你感到困惑的是符号*
和&
.了解这些问题的难点在于它们都有两种与间接有关的不同含义(甚至不包括*
乘法和&
按位的第三种含义).
*
,当用作类型的一部分时,
表示类型是指针:
int
是一个类型,因此int*
是指向int类型int**
的指针,并且是指向指针到int类型的指针.
&
当用作类型的一部分时,表示该类型是引用.int
是一个类型,因此int&
是一个引用到int(没有引用引用这样的东西).引用和指针用于类似的事情,但它们是完全不同的,不可互换.最好将引用视为现有变量的别名或备用名称.如果x
是int
,那么你可以简单地分配int& y = x
到创建一个新的名称y
为x
.后记,x
并且y
可以互换使用,以指代相同的整数.这样做的两个主要含义是引用不能为NULL(因为必须有一个原始变量来引用),并且您不需要使用任何特殊运算符来获取原始值(因为它只是一个替代名称,不是指针).引用也不能重新分配.
*
当用作一元运算符时,执行一个称为解引用的操作(与引用类型无关!).此操作仅对指针有意义.当您取消引用指针时,您将返回它指向的内容.因此,如果p
是指向int的指针,*p
则int
指向.
&
当用作一元运算符时,执行一个名为address-of的操作.这是非常不言自明的; if x
是变量,那么&x
是地址x
.可以将变量的地址分配给指向该变量类型的指针.因此,如果x
是int
,则&x
可以将其指定为类型的指针int*
,该指针将指向x
.例如,如果您指定int* p = &x
,则*p
可以用于检索值x
.
所以请记住,类型后缀&
用于引用,与一元操作无关&
,这与获取用于指针的地址有关.这两种用途完全不相关.并且*
作为类型后缀声明指针,而*
作为一元运算符对指针执行操作.
Pét*_*rök 29
在returnA()中我要求返回一个指针; 只是为了澄清这是有效的,因为j是一个指针?
是的,int *j = &a
初始化j
指向a
.然后返回值j
,即地址a
.
在returnB()中我要求返回一个指针; 因为指针指向一个地址,returnB()工作的原因是因为我正在返回&b?
是.在这里,同样的事情发生在上面,只需一步.&b
给出了地址b
.
在returnC()中,我要求返回一个int的地址.当我返回c时,&运算符会自动附加吗?
不,它是对返回的int的引用.引用不是与指针相同的地址 - 它只是变量的替代名称.因此,您无需应用&
运算符来获取变量的引用.
在returnC2()中,我再次询问要返回的int的地址.*d是否有效,因为指针指向一个地址?
同样,它是对返回的int的引用.*d
指的是原始变量c
(无论可能是什么),指向c
.这可以隐含地转化为参考,就像在returnC
.
指针通常不指向一个地址(尽管它们可以 - 例如int**
指向int的指针).指针是某种东西的地址.当你声明指针时something*
,这something
就是指针指向的东西.所以在上面的例子中,int**
声明了一个指向a的指针int*
,它恰好是一个指针本身.
小智 5
Tyler,这是非常有用的解释,我做了一些使用visual studio调试器的实验来进一步澄清这种差异: -
int sample = 90;
int& alias = sample;
int* pointerToSample = &sample;
Name Address Type
&alias 0x0112fc1c {90} int *
&sample 0x0112fc1c {90} int *
pointerToSample 0x0112fc1c {90} int *
*pointerToSample 90 int
alias 90 int &
&pointerToSample 0x0112fc04 {0x0112fc1c {90}} int * *
Run Code Online (Sandbox Code Playgroud)
PointerToSample Sample/alias
_______________......____________________
0x0112fc1c | | 90 |
___________|___.....__|________|_______...
[0x0112fc04] ... [0x0112fc1c
Run Code Online (Sandbox Code Playgroud)