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

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


当前回答

指针的复杂性超出了我们可以轻易教授的范围。让学生们互相指指点点和使用写有家庭住址的纸都是很好的学习工具。他们在介绍基本概念方面做得很好。事实上,学习指针的基本概念对于成功使用指针是至关重要的。然而,在产品代码中,通常会遇到比这些简单演示所能封装的复杂得多的场景。

我参与过的系统中,我们有一个结构指向另一个结构指向另一个结构。其中一些结构还包含嵌入式结构(而不是指向其他结构的指针)。这就是指针真正令人困惑的地方。如果你有多个间接层,你最终会得到这样的代码:

widget->wazzle.fizzle = fazzle.foozle->wazzle;

它很快就会让人感到困惑(想象更多的线,可能还有更多的关卡)。再加上指针数组和节点到节点的指针(树、链表),情况就更糟了。我曾见过一些非常优秀的开发人员在开始开发这样的系统时迷失了方向,甚至是那些非常了解基础知识的开发人员。

Complex structures of pointers don't necessarily indicate poor coding, either (though they can). Composition is a vital piece of good object-oriented programming, and in languages with raw pointers, it will inevitably lead to multi-layered indirection. Further, systems often need to use third-party libraries with structures which don't match each other in style or technique. In situations like that, complexity is naturally going to arise (though certainly, we should fight it as much as possible).

我认为大学为帮助学生学习指针所能做的最好的事情就是使用良好的演示,并结合需要使用指针的项目。对于指针的理解,一个困难的项目要比上千个演示做得多。演示可以让您对指针有一个浅显的理解,但要深刻地理解指针,您必须真正地使用它们。

其他回答

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

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

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

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

I think that the main reason that people have trouble with it is because it's generally not taught in an interesting and engaging manner. I'd like to see a lecturer get 10 volunteers from the crowd and give them a 1 meter ruler each, get them to stand around in a certain configuration and use the rulers to point at each other. Then show pointer arithmetic by moving people around (and where they point their rulers). It'd be a simple but effective (and above all memorable) way of showing the concepts without getting too bogged down in the mechanics.

一旦你学了C和c++,对某些人来说似乎就更难了。我不确定这是因为他们最终把他们没有正确掌握的理论应用到实践中,还是因为在这些语言中指针操作天生就更难。我不太记得我自己的转变,但我知道Pascal中的指针,然后转到C,完全迷失了。

我发现一个有助于解释指针的类比是超链接。大多数人都能理解,网页上的链接“指向”互联网上的另一个页面,如果你可以复制和粘贴这个超链接,那么它们都将指向相同的原始网页。如果你去编辑原始页面,然后按照这些链接(指针)中的任何一个,你会得到新的更新页面。

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

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

我认为理解指针的主要障碍是糟糕的老师。

几乎每个人都被教导过关于指针的谎言:它们只不过是内存地址,或者它们允许你指向任意位置。

当然,他们很难理解,危险,半魔法。

这些都不是真的。指针实际上是相当简单的概念,只要你坚持c++语言对它们的描述,不要给它们灌输“通常”在实践中会起作用的属性,但语言却不能保证,因此不是指针实际概念的一部分。

几个月前,我试图在这篇博客文章中对此进行解释——希望它能帮助到一些人。

(请注意,在有人对我说学究气之前,是的,c++标准确实说指针表示内存地址。但它并没有说“指针是内存地址,而且只是内存地址,可以与内存地址互换使用或认为”。区别很重要)