我可以有一个用于引用和指针的 ELI5 以及何时使用它们吗?

Posted

技术标签:

【中文标题】我可以有一个用于引用和指针的 ELI5 以及何时使用它们吗?【英文标题】:Can I have an ELI5 for references and pointers and when to use them? 【发布时间】:2020-06-16 19:27:13 【问题描述】:

我学习编码已经有一段时间了,但仍然无法理解引用和指针。我搜索的每个答案对我来说都太复杂了。

当我们调用要使用的变量时,例如

int32 y = 1;
int32 x = 2;
int32 z = y + x;

1) "z" 中到底发生了什么?是通过引用,通过指针调用“y”和“x”还是通过变量调用它们?

在这段代码中我正在学习

FString Log = TEXT("Hello");
FString* PrtLog = &Log;
Log.Len();
(*PrtLog).Len();
PrtLog->Len();

2) 这里发生了什么? “PrtLog”是引用还是指针?

3) 讲师说 *PrtLog 是“取消引用”PrtLog。这是否意味着对 PrtLog 的引用被删除了? * 和 ->

有什么区别

4) 如果调用变量也可以,为什么我们还需要引用或指针?

5) 为什么有些人声称 90% 的变量将使用更高级别的引用和指针?它们有什么好处吗?如果我们只是通过变量调用,是不是更简单更快?

抱歉,如果问题太多。我无法得到一个我能够在引用和指针的任何地方理解的答案,所以我真的很困惑。

【问题讨论】:

变量不会被“调用”。只有函数可以。我不知道您所说的“它是通过引用、指针调用“y”和“x”还是仅通过变量调用它们?” PrtLog 是一个指针。不幸的是,取消引用以这种方式命名,因为它与引用无关。您只能取消引用指针。 @BessieTheCow 我也完全不知道哈哈。讲师就是这么说的。或者也许我只是听错了,因为信息太多。什么是正确的术语?从 y 和 x 获取数据?获取数据?编辑:它可能被称为“通过”。编码中的术语太多了,我真的被淹没了 【参考方案1】:

1) "z" 中到底发生了什么?它是通过调用“y”和“x”吗 引用,通过指针还是仅通过变量调用它们?

这些变量都不是指针或引用。它们只是..变量。 xy 是使用的变量。 operator+(x, y).

2) 这里发生了什么? “PrtLog”是引用还是指针?

PrtLog 是一个指针,你可以通过查看它的类型声明来看到这一点:

FString*

显然它是一个指向 FString 的指针。

= &Log; 可能会引起混淆。在这部分代码中,& 是获取指向Log 的指针所需的地址运算符。 & 仅表示作为类型一部分的引用,Log 这里是变量,而不是类型。

3) 讲师说 *PrtLog 是“取消引用”PrtLog。这是否意味着 删除了 PrtLog 的引用? * 有什么区别 和 ->

在这种情况下,取消引用只是一个不幸的名称,它意味着获取指针所指向的“事物”。 FString* 是指向 FString 的指针,因此取消引用此类指针将产生 FString

*-> 之间的区别在于->(*pointer). 的简写,或“取消引用pointer 并访问其成员”。

4) 为什么我们在调用变量时甚至需要引用或指针 一样好吗?

您想要使用指针或引用有几个可能的原因。例如,引用一个对象但不复制对象本身。

5) 为什么有些人声称 90% 的变量将使用引用 和更高级别的指针?它们有什么好处吗?要是我们 只是通过变量调用,是不是更简单更快捷?

这是谁声称的?我没有数字,但这似乎不准确。当然,它们都是非常有用的结构,但在很大程度上取决于项目是否以这些数字使用它们。

【讨论】:

1) 感谢您的回复,从回复中逐渐清晰,但现在仍然有点阴天。如我错了请纠正我;我得到的是参考是指我的变量存储的位置。因此,如果我声明 int32 x = 5,则数字 5 存储在某处,并且该位置是一些随机的 HEX 数字,例如 123f43。十六进制数称为地址,对吗?所以如果我引用 int32& y = x,y 将是 123f43,对吧? @Benjamin 这并不完全正确,对于指针来说确实如此。指针保存指向它所指向的变量的地址。地址的样子在这里并不是一个真正的问题,你不应该过多地关注它的细节。请记住,就语言而言,只有指针的值包含它指向的地址,引用不包含。对于语言,引用(& 不是 *)没有地址,它总是将您定向到它所绑定的变量。 2) 指针与引用完全相反?使用上面的例子,如果我编码 int32* z = y 我应该得到 z = 5,这就是 x 应该是什么。由于 y 是 x 的“位置”,z 将返回存储在位置 123f43 中的数字,对吗? @Benjamin 不,指针有点像引用。它们只是有一些差异,以使引用更安全。 ***.com/questions/57483/… 这个答案可能会更详细地为您解答。他们绝对不是对立的。 很抱歉打扰了,但在上面的链接中,从第 2 点开始,我完全迷失了。什么是指针,什么是引用,最后什么是变量?为什么它们在定义上听起来如此相似,但同时又如此不同?编辑:以我在 Unreal Engine C++ 中的游戏制作水平,我真的需要使用指针和引用吗?如果可能的话,我真的想尽可能地避免它们【参考方案2】:

xy 被称为左值表达式(通常缩写为左值)。这意味着它们对应于内存位置。表达式的上下文决定了一个值是写入内存位置,还是从内存位置检索的值。

在代码x = 2; 中,一个值被写入x 命名的位置。在代码x + 2中,从x命名的位置读取一个值。

PrtLog 是一个指针,因为它是用指针​​声明符声明的。这里回答了为什么有人会使用指针的问题:Why use pointers?

“取消引用”意味着从指针表达式中删除一个间接级别。一个指针指向一个内存位置。取消引用指针的结果是对应于该内存位置的左值表达式。这可以有多个级别。如果a 是指针,则a->b 等效于(*a).b

【讨论】:

【参考方案3】:

指针只是一个数字。此数字对应于您计算机 RAM 中相应变量值的存储位置。

int theAnswer = 42;
int *pointer = &theAnswer;

std::cout << pointer << '\n';
/*
 * this will print where in memory `theAnswer` is stored,
 * it'll just look like some random number. Try it out!
 */

所以在你的例子中,(2)PrtLog 是一个指针。引用也是一个指针,但 C++ 有点“隐藏”它是一个。

(3) 请记住,指针只是一个数字。因此,如果您想使用指针的值,而不是使用指针本身进行数学运算(例如,您不应该这样做),您需要以某种方式“跟随”该数字到存储值的位置。这就是取消引用的作用。它“跟随”指针获取其值,并允许您执行调用函数或修改函数等操作。

// make an integer variable
int theAnswer = 42;
int *pointer = &theAnswer;

std::cout << "Original: " << theAnswer << " Pointer: " << *pointer << '\n';
// prints "Original: 42 Pointer 42"
*pointer = 41;
std::cout << "Original: " << theAnswer << " Pointer: " << *pointer << '\n';
// prints "Original: 41 Pointer 41"

(4) 有时您无法访问原始文件,例如运行时内存分配,或者如果您想创建一种方法来改变变量等。在 c++ 中,很多这些都隐藏在标准中包含引用和类之类的库,但它仍然偶尔会出现。虽然,如果你在 C++ 中使用 raw 指针(而不是引用或 RAII 类),你应该有充分的理由这样做,内存泄漏真的很容易。

// you can only access this variable though the pointer
int *dynamic = new int;
*dynamic = 42;

std::cout << *dynamic << '\n';

delete dynamic;

(5) 这似乎和 4 是同一个问题,但我可能解释错了。

我希望这很清楚。如果您有任何其他问题,请随时发表评论,我会尽力回答,我很乐意帮助本杰明的同胞!

【讨论】:

感谢您的回复。我想澄清一下,因为我意识到在你的答案之后,我不知道指针、引用和变量的真正含义。 * 表示指针,&amp; 表示引用,变量只是您定义并赋予其含义的单词/字母,例如字母 5 或单词 dog 对吗?在这行代码中:int *pointer = &amp;theAnswer; 为什么把*&amp; 都放进去?我对不断重复我的问题感到非常难过,但我对此感到很困惑,真的很想理解。很抱歉 @Benjamin int* pointer 声明了一个名为 pointer 类型为 int* 的变量,即一个 int 指针。 int&amp; ref 声明了一个名为 ref 类型为 int&amp; 的变量,即一个 int 引用。 &amp;theAnswer 获取theAnswer 的地址,即int* 类型的值。在这两种情况下使用&amp; 彼此无关。 &amp; 在两种情况下都有不同的含义。 &amp;theAnswer 中的 &amp; 称为 address-of 运算符operator&amp; (en.cppreference.com/w/cpp/language/…)

以上是关于我可以有一个用于引用和指针的 ELI5 以及何时使用它们吗?的主要内容,如果未能解决你的问题,请参考以下文章

用于多级指针取消引用?

为啥以及何时需要提供我自己的删除器?

引用还是指针?

C ++:在向量中插入啥 - 指针或引用,向量何时复制它的元素?

函数何时值传递,何时指针,何时引用传递总结

C语言面试中的问题-指针和引用的使用场景?