为什么指针是许多刚开始学习C或c++,甚至上了大学的学生困惑的主要因素?有没有什么工具或思维过程可以帮助你理解指针在变量、函数和级别之外是如何工作的?
有什么好的实践可以让人达到“啊哈,我懂了”的水平,而不会让他们陷入整体概念中?基本上,就是模拟场景。
为什么指针是许多刚开始学习C或c++,甚至上了大学的学生困惑的主要因素?有没有什么工具或思维过程可以帮助你理解指针在变量、函数和级别之外是如何工作的?
有什么好的实践可以让人达到“啊哈,我懂了”的水平,而不会让他们陷入整体概念中?基本上,就是模拟场景。
当前回答
我认为这可能是语法问题。指针的C/ c++语法似乎不一致,而且比实际需要的更复杂。
具有讽刺意味的是,真正帮助我理解指针的是c++标准模板库中迭代器的概念。这很讽刺,因为我只能假设迭代器被认为是指针的泛化。
有时候,只有当你学会忽略树木时,你才能看到森林。
其他回答
指针让很多人感到困惑的原因是它们大多没有计算机架构背景。由于许多人似乎不知道计算机(机器)是如何实际实现的——在C/ c++中工作似乎很陌生。
一个练习是要求他们实现一个简单的基于字节码的虚拟机(在任何他们选择的语言中,python都很适合这个),其中的指令集集中于指针操作(加载、存储、直接/间接寻址)。然后要求他们为该指令集编写简单的程序。
任何需要比简单加法稍微多一点的东西都会涉及到指针,它们肯定会得到指针。
我认为理解指针的主要障碍是糟糕的老师。
几乎每个人都被教导过关于指针的谎言:它们只不过是内存地址,或者它们允许你指向任意位置。
当然,他们很难理解,危险,半魔法。
这些都不是真的。指针实际上是相当简单的概念,只要你坚持c++语言对它们的描述,不要给它们灌输“通常”在实践中会起作用的属性,但语言却不能保证,因此不是指针实际概念的一部分。
几个月前,我试图在这篇博客文章中对此进行解释——希望它能帮助到一些人。
(请注意,在有人对我说学究气之前,是的,c++标准确实说指针表示内存地址。但它并没有说“指针是内存地址,而且只是内存地址,可以与内存地址互换使用或认为”。区别很重要)
一个带有一组很好的图表的教程示例极大地帮助理解指针。
Joel Spolsky在他的《面试指南》文章中提出了一些关于理解指针的好观点:
出于某种原因,大多数人似乎生来就没有大脑中理解指针的那部分。这是一个天赋问题,而不是技能问题——它需要一种复杂的双重间接思维形式,而有些人就是做不到。
我喜欢用数组和下标来解释它——人们可能不熟悉指针,但他们通常都知道下标是什么。
所以我说,假设RAM是一个数组(你只有10个字节的RAM):
unsigned char RAM[10] = { 10, 14, 4, 3, 2, 1, 20, 19, 50, 9 };
然后,指向变量的指针实际上只是该变量在RAM中的第一个字节的索引。
因此,如果你有一个指针/索引unsigned char index = 2,那么这个值显然是第三个元素,或者数字4。指针指向指针的指针是指将该数字本身用作索引,如RAM[RAM[index]]。
我会在纸上的列表上画一个数组,然后用它来显示一些东西,比如指向同一个内存的许多指针、指针算术、指针到指针等等。
起初,我很难理解指针的原因是,许多解释都包含了很多关于引用传递的废话。所有这些都混淆了问题。当你使用指针形参时,你仍然是通过值传递;但是这个值恰好是一个地址,而不是int型。
其他人已经链接到本教程,但我可以强调我开始理解指针的时刻:
C语言指针和数组教程:第3章-指针和字符串
int puts(const char *s);
目前,忽略const。传递给puts()的形参是一个指针,即指针的值(因为C中的所有形参都是按值传递的),指针的值是它所指向的地址,或者简单地说,是一个地址。因此,当我们写put (strA);正如我们所看到的,我们正在传递strA[0]的地址。
当我读到这些文字的那一刻,乌云散开,一束阳光带着指教般的理解将我笼罩。
即使你是一个VB . net或c#开发人员(就像我一样)并且从未使用过不安全的代码,了解指针的工作原理仍然是值得的,否则你将无法理解对象引用的工作原理。然后您就会有一个常见但错误的概念,即将对象引用传递给方法会复制对象。