C++返回指针/引用

48 c++ pointers return

我对解除引用操作符,操作符的地址和一般指针有相当好的理解.

但是当我看到这样的东西时,我感到很困惑:

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)
  1. returnA()我要求返回一个指针; 只是为了澄清这个作品因为j是一个指针?
  2. returnB()我要求返回一个指针; 因为指针指向一个地址,所以returnB()工作的原因是因为我回来了&b
  3. returnC()我要求int归还的地址.当我返回时c,&操作员会自动"追加" c吗?
  4. returnC2()我再问一个int要归还的地址.是否*d有效,因为指针指向一个地址?

假设a,b,c被初始化为整数为Global.

有人可以验证我的所有四个问题是否正确?

Tyl*_*nry 75

虽然彼得回答了你的问题,但有一点让你感到困惑的是符号*&.了解这些问题的难点在于它们都有两种与间接有关的不同含义(甚至不包括*乘法和&按位的第三种含义).

  • *,当用作类型的一部分时, 表示类型是指针: int是一个类型,因此int*是指向int类型int**的指针,并且是指向指针到int类型的指针.

  • &当用作类型的一部分时,表示该类型是引用.int是一个类型,因此int&是一个引用到int(没有引用引用这样的东西).引用和指针用于类似的事情,但它们是完全不同的,不可互换.最好将引用视为现有变量的别名或备用名称.如果xint,那么你可以简单地分配int& y = x到创建一个新的名称yx.后记,x并且y可以互换使用,以指代相同的整数.这样做的两个主要含义是引用不能为NULL(因为必须有一个原始变量来引用),并且您不需要使用任何特殊运算符来获取原始值(因为它只是一个替代名称,不是指针).引用也不能重新分配.

  • *当用作一元运算符时,执行一个称为解引用的操作(与引用类型无关!).此操作仅对指针有意义.当您取消引用指针时,您将返回它指向的内容.因此,如果p是指向int的指针,*pint指向.

  • &当用作一元运算符时,执行一个名为address-of的操作.这是非常不言自明的; if x是变量,那么&x是地址x.可以将变量的地址分配给指向该变量类型的指针.因此,如果xint,则&x可以将其指定为类型的指针int*,该指针将指向x.例如,如果您指定int* p = &x,则*p可以用于检索值x.

所以请记住,类型后缀&用于引用,与一元操作无关&,这与获取用于指针的地址有关.这两种用途完全不相关.并且*作为类型后缀声明指针,而*作为一元运算符对指针执行操作.

  • 感谢我在这些运营商上看到过的最清晰的解释之一. (10认同)
  • 很好的答案应该是被接受的。 (3认同)
  • 终于看到一个可以帮助我解决这两件事的解决方案 (2认同)

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*,它恰好是一个指针本身.

  • @ChosenTorture,通过声明函数类型`int&`,你说它返回一个引用,句点.引用只是变量的别名,因此不需要转换.就像,虽然ChosenTorture很可能不是你的真名,但在注册StackOverflow时你仍然不需要进行任何转换,是吗?;-)这里的人称你为ChosenTorture,但是你的妈妈可能会用一个完全不同的名字来称呼你,但你总是这样.类似地,在执行`int&x = returnC()`之后,`x`将引用与`c`相同的变量. (2认同)

小智 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)