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

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


当前回答

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

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

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

其他回答

起初,我很难理解指针的原因是,许多解释都包含了很多关于引用传递的废话。所有这些都混淆了问题。当你使用指针形参时,你仍然是通过值传递;但是这个值恰好是一个地址,而不是int型。

其他人已经链接到本教程,但我可以强调我开始理解指针的时刻:

C语言指针和数组教程:第3章-指针和字符串

int puts(const char *s);

目前,忽略const。传递给puts()的形参是一个指针,即指针的值(因为C中的所有形参都是按值传递的),指针的值是它所指向的地址,或者简单地说,是一个地址。因此,当我们写put (strA);正如我们所看到的,我们正在传递strA[0]的地址。

当我读到这些文字的那一刻,乌云散开,一束阳光带着指教般的理解将我笼罩。

即使你是一个VB . net或c#开发人员(就像我一样)并且从未使用过不安全的代码,了解指针的工作原理仍然是值得的,否则你将无法理解对象引用的工作原理。然后您就会有一个常见但错误的概念,即将对象引用传递给方法会复制对象。

为了使事情更混乱一点,有时你必须使用句柄而不是指针。句柄是指向指针的指针,因此后端可以移动内存中的内容以整理堆。如果指针在例程中间发生了变化,那么结果是不可预测的,因此您首先必须锁定句柄,以确保没有任何事情发生。

http://arjay.bc.ca/Modula-2/Text/Ch15/Ch15.8.html#15.8.5比我讲得更清楚一点。: -)

在C/ c++语言中,指针为什么是许多新、甚至老大学生困惑的主要因素?

一个值的占位符的概念——变量——映射到我们在学校教的东西——代数。如果不理解内存在计算机中是如何物理布局的,就无法画出一个现有的并行图,而且没有人会考虑这种事情,直到他们处理低级别的事情——在C/ c++ /字节通信级别。

有没有什么工具或思维过程可以帮助你理解指针在变量、函数和级别之外是如何工作的?

地址框。我记得当我学习在微型计算机上编程BASIC时,有一些漂亮的书,里面有游戏,有时你必须在特定的地址中插入值。他们有一张图片,上面有一堆盒子,标有0、1、2……它解释说,只有一个小的东西(一个字节)可以装在这些盒子里,而它们有很多——一些计算机有多达65535!他们紧挨着,都有一个地址。

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

为了演习?创建一个结构体:

struct {
char a;
char b;
char c;
char d;
} mystruct;
mystruct.a = 'r';
mystruct.b = 's';
mystruct.c = 't';
mystruct.d = 'u';

char* my_pointer;
my_pointer = &mystruct.b;
cout << 'Start: my_pointer = ' << *my_pointer << endl;
my_pointer++;
cout << 'After: my_pointer = ' << *my_pointer << endl;
my_pointer = &mystruct.a;
cout << 'Then: my_pointer = ' << *my_pointer << endl;
my_pointer = my_pointer + 3;
cout << 'End: my_pointer = ' << *my_pointer << endl;

与上面的例子相同,除了在C中:

// Same example as above, except in C:
struct {
    char a;
    char b;
    char c;
    char d;
} mystruct;

mystruct.a = 'r';
mystruct.b = 's';
mystruct.c = 't';
mystruct.d = 'u';

char* my_pointer;
my_pointer = &mystruct.b;

printf("Start: my_pointer = %c\n", *my_pointer);
my_pointer++;
printf("After: my_pointer = %c\n", *my_pointer);
my_pointer = &mystruct.a;
printf("Then: my_pointer = %c\n", *my_pointer);
my_pointer = my_pointer + 3;
printf("End: my_pointer = %c\n", *my_pointer);

输出:

Start: my_pointer = s
After: my_pointer = t
Then: my_pointer = r
End: my_pointer = u

也许这通过例子解释了一些基础知识?

我发现Ted Jensen的“C中的指针和数组教程”是学习指针的极好的资源。它分为10节课,从解释指针是什么(以及它们是用来干什么的)开始,到以函数指针结束。http://web.archive.org/web/20181011221220/http://home.netcom.com:80/~tjensen/ptr/cpoint.htm

接着,Beej的《网络编程指南》教授了Unix套接字API,从中你可以开始做一些真正有趣的事情。http://beej.us/guide/bgnet/

我不认为指针是一个特别棘手的概念——大多数学生的心理模型都映射到这样的东西,一些快速的盒子草图会有帮助。

困难之处在于,至少在我过去的经历和看到其他人处理的过程中,在C/ c++中指针的管理可能是不必要的复杂。