为什么指针是许多刚开始学习C或c++,甚至上了大学的学生困惑的主要因素?有没有什么工具或思维过程可以帮助你理解指针在变量、函数和级别之外是如何工作的?

有什么好的实践可以让人达到“啊哈,我懂了”的水平,而不会让他们陷入整体概念中?基本上,就是模拟场景。


当前回答

The problem with pointers is not the concept. It's the execution and language involved. Additional confusion results when teachers assume that it's the CONCEPT of pointers that's difficult, and not the jargon, or the convoluted mess C and C++ makes of the concept. So vast amounts of effort are poored into explaining the concept (like in the accepted answer for this question) and it's pretty much just wasted on someone like me, because I already understand all of that. It's just explaining the wrong part of the problem.

为了让你知道我是怎么来的,我是一个非常理解指针的人,我可以在汇编语言中熟练地使用它们。因为在汇编语言中,它们不被称为指针。它们被称为地址。当我在C语言中编程和使用指针时,我犯了很多错误,并感到非常困惑。我还没弄清楚。让我给你们举个例子。

当一个api说:

int doIt(char *buffer )
//*buffer is a pointer to the buffer

它想要什么?

它可能想要:

表示缓冲区地址的数字

(给它,我说doIt(mybuffer),还是doIt(* mybuffer) ?)

表示缓冲区地址的一种数字

(doIt(&mybuffer) or doIt(mybuffer) or doIt(*mybuffer)?)

表示缓冲区地址的地址的数字

(可能是doIt(&mybuffer)。还是doIt(&&mybuffer) ?甚至doIt(&&&mybuffer))

and so on, and the language involved doesn't make it as clear because it involves the words "pointer" and "reference" that don't hold as much meaning and clarity to me as "x holds the address to y" and "this function requires an address to y". The answer additionally depends on just what the heck "mybuffer" is to begin with, and what doIt intends to do with it. The language doesn't support the levels of nesting that are encountered in practice. Like when I have to hand a "pointer" in to a function that creates a new buffer, and it modifies the pointer to point at the new location of the buffer. Does it really want the pointer, or a pointer to the pointer, so it knows where to go to modify the contents of the pointer. Most of the time I just have to guess what is meant by "pointer" and most of the time I'm wrong, regardless of how much experience I get at guessing.

指针重载了。指针是指向值的地址吗?或者它是一个将地址保存到值的变量。当一个函数需要一个指针时,它是想要指针变量保存的地址,还是指针变量的地址? 我困惑。

其他回答

邮政信箱号码。

它是一条信息,允许你访问其他东西。

(如果你计算邮政信箱号码,你可能会有问题,因为信进了错误的信箱。如果有人搬到另一个州——没有转发地址——你就有一个悬浮指针。另一方面,如果邮局转发邮件,那么你就有了指向指针的指针。)

我认为,使指针难以学习的原因是,直到你熟悉了指针的概念,即“在这个内存位置是一组表示int型,double型,字符等的位”。

当你第一次看到一个指针时,你并不知道那个内存位置上有什么。“什么意思,里面有地址?”

我不同意“要么得到要么得不到”的观点。

当你开始发现它们的真正用途时(比如不要将大结构传递到函数中),它们就会变得更容易理解。

这种混淆来自于在“指针”概念中混合在一起的多个抽象层。程序员不会对Java/Python中的普通引用感到困惑,但指针的不同之处在于它们暴露了底层内存架构的特征。

清晰地分离抽象层是一个很好的原则,而指针做不到这一点。

指针让很多人感到困惑的原因是它们大多没有计算机架构背景。由于许多人似乎不知道计算机(机器)是如何实际实现的——在C/ c++中工作似乎很陌生。

一个练习是要求他们实现一个简单的基于字节码的虚拟机(在任何他们选择的语言中,python都很适合这个),其中的指令集集中于指针操作(加载、存储、直接/间接寻址)。然后要求他们为该指令集编写简单的程序。

任何需要比简单加法稍微多一点的东西都会涉及到指针,它们肯定会得到指针。

一个带有一组很好的图表的教程示例极大地帮助理解指针。

Joel Spolsky在他的《面试指南》文章中提出了一些关于理解指针的好观点:

出于某种原因,大多数人似乎生来就没有大脑中理解指针的那部分。这是一个天赋问题,而不是技能问题——它需要一种复杂的双重间接思维形式,而有些人就是做不到。