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

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


当前回答

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

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

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

其他回答

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

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

我认为这可能是语法问题。指针的C/ c++语法似乎不一致,而且比实际需要的更复杂。

具有讽刺意味的是,真正帮助我理解指针的是c++标准模板库中迭代器的概念。这很讽刺,因为我只能假设迭代器被认为是指针的泛化。

有时候,只有当你学会忽略树木时,你才能看到森林。

上面的一些回答断言“指针并不难”,但并没有直接解决“指针难”的来源。几年前,我辅导一年级的CS学生(只教了一年,因为我显然学得很差),我很清楚指针的概念并不难。难的是理解为什么以及什么时候需要指针。

我不认为您可以将这个问题(为什么以及何时使用指针)与解释更广泛的软件工程问题分开。为什么每个变量都不应该是全局变量,以及为什么应该把类似的代码分解成函数(也就是使用指针将它们的行为专门化到它们的调用位置)。

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

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

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型,字符等的位”。

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

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

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