指针有什么好的解释?[关闭]


72

在您自己的学习中(无论是自己学习还是上课),当您最终真正理解指针时,您是否有一个“啊哈”时刻?您对初学者使用的解释是否似乎特别有效?

例如,当初学者第一次在C语言中遇到指针时,他们可能只添加&s和*s,直到它编译为止(就像我自己曾经做的那样)。也许是一张图片,或者是一个动机很好的例子,使指针为您或您的学生“点击”。那是什么,在那之前您尝试了什么却似乎没有用?是否有任何主题的前提条件(例如结构或数组)?

换句话说,当您可以放心使用&s和时*,要理解它们的含义是什么?仅学习语法和术语或用例还不够,有时需要将想法内在化。


更新:到目前为止,我真的很喜欢答案。请让他们来。这里有很多不错的观点,但是我认为我们将概念内部化之后,许多都是对自己的很好的解释/口号。我正在寻找黎明时分的详细情况和情况。

例如:

我在语法上只稍微了解了C指针。我听到我的两个朋友向另一个朋友解释了指针,后者问为什么将a struct与指针一起传递。第一个朋友谈论了如何引用和修改它,但这只是另一个朋友的简短评论,它打动了我:“它也更有效率。” 我需要的最后一个概念上的转变是传递4个字节而不是16个字节。


16
“ Shotgun”方法:在可行的所有地方抛出* s。
Michael K

15
@Michael:是的,祝你好运。
罗伯特·哈维

8
在每学期开始的SO课程后不久,就会提出这个问题。最新的化身是在这里:stackoverflow.com/questions/4118647/...
蒂姆后

10
指针有什么好的解释?Brian Kernhigan和Dennis Ritchie讨厌软件工程师。
亚当·克罗斯兰

3
在调试器中花了一些单步机器代码之后,它为我“点击”。是的,我熟悉计算机体系结构的基础知识–我学习了Commodore 64上的汇编,然后x86 ASM非常简单。所以我已经知道“地址”的概念,我只是不了解它如何映射到C的语法结构。
zvrba 2010年

Answers:


25

内存即网格图

通常我所做的是将内存表示为“网格”,以便我可以组成地址,突出显示不同的内存空间并在单元格中写入值(甚至更进一步,它们的二进制表示形式)并将内存中的指针链接到它们的值。指向。(然后仍然提到这是一种简化)。

通常,对我大多数学生来说,这是一个“噢”时刻。

符号杂耍

然后,当让他们停止忘记如何使用&和*时,这非常简单:以与他们进行数学或物理计算相同的方式呈现。如果将以千米为单位的距离除以以小时为单位的时间,则将得到以km / h为单位的速度。有什么需要注意的。简单。

printf到救援

仅仅做一些基本的例子,以视觉方式代表您对这些内容的解释,就会使他们感到满意,或者给他们机会说“啊,我不明白”。

广泛

覆盖简单类型的指针,并确保它们了解数据类型的寻址和大小之间的区别,然后是结构,然后是数组以及多个级别。

然后开始指针运算。


附录:递归

我通常使用视觉表示类似地解释递归。让他们使用编写单个字符的预制函数来打印字母,然后要求他们仅改变两行就以相反的顺序打印它。

通常有一个“什么……?” 现在,当您在printf中仅添加另一个参数以打印数字值并缩进步骤时,它就松了一口气。


替代方案:玩偶模型和水杯

我实际上在大学里有一些同事,向学生展示了一个视频,用play-doh粘贴解释了指针和内存访问。尽管我从来没有真正使用过这种技术,但是它非常聪明而且做得很好,除了非常年轻的学习者(对学习编程感兴趣)(但是通常我不会引导他们过早使用指针来学习语言)。基本上使用play-doh的小球,您可以将它们附加到表示内存空间的其他更大的play-doh的球上,并且可以组合在一起以链接它们(如在链接的数据结构中)或合并在一起(如在连续的中)内存空间)。为指向的存储空间使用不同的颜色,指针也有帮助。但是我仍然认为Memory-as-a-Grid的工作原理更好,正如您可以清楚地表明,指向实际上是一个“寻址”问题,例如在“地图/网格”上。Play-doh模式仍然使他们误以为事情确实在内存中彼此“接触”。

同事也直接使用了水杯的东西,但我不知道她是否提出了。这是一种有趣的方法,但我注意到许多学生对此解释感到困惑。DevSolo的咖啡杯技术类似。但是我认为这实际上是一种误导,因为它会让学生混淆容器,数据结构,指针和数组。在我假设的一开始,解释数组可能是一种有趣的方法,但是我不会坚持很长时间。


哇,谢谢你的赏金 很高兴得到答复。
haylem 2010年

画出来:| 听起来不错!
惊吓

80

比我以前说的要聪明得多的人:

修女吴金仓问惠国六世:“我研究玛哈帕瑞尼佛经已经很多年了,但是我对很多领域还不太了解,请赐教。”

家长回答:“我是文盲。请给我读出这些字符,也许我就能解释其含义。”

修女说:“你甚至不能认出这些字符。那么你怎么能理解含义呢?”

“真理与语言无关。真理可以比喻为天空中明亮的月亮。在这种情况下,词语可以比喻为手指。手指可以指向月亮的位置。但是,手指不是月亮。要看月亮,有必要凝视不出手指,对吗?


13
+1用于取消对月亮的引用。如果可以的话,可为koan +1。
蒂姆·波斯特

14
一根手指弹奏的声音是什么?
亚当·克罗斯兰

3
@Adam取决于您使用的是鼠标还是触控板。
丹尼尔·约瑟夫

7
@弗兰克这是一个伟大的报价。我仍然认为掌握这一想法无济于事。特别是对于刚接触指针的人。
Gulshan

11
这是一个美丽的故事...但是我怀疑人们因此投票,而不是因为它很好地解释了指针。
Kyralessa

46

我发现图表非常有帮助。例:

指针图


这种图帮助我看到指针是它们自己的变量,但是包含一个值,该值是另一个对象的位置,即数组或字符串。另外,当用铅笔完成时,我可以用它在纸上或黑板/白板上跟踪程序。


4
“指针”中的值应为4还是数组索引(或内存地址)应从0开始。否则,保存值为3的指针如何指向位置4?
MAK 2010年

++这正是我要解释的方式。我从Fortran开始(无论好坏!)。在Fortran中,那时,我们使用并行数组而不是结构数组(没有new)。如果一个数组在数组中包含“另一行”的索引,我们将其称为“指针”,这很令人兴奋。我们创建了链表,树,您可以命名。
Mike Dunlavey 2010年

2
我发现最好使用图片(指示存储位置)和箭头(指示指针指向)来解释指针。
gablin

32

当我第一次“学习”有关指针的知识时,我对它有所了解。我的大学已经很长一段时间才做出决定,因此我开始以Java为中心学习课程,因此,当我的数据结构教授就C进行了一次讲座并要求我们使用指针实现XOR-List时,我感到自己正在进入某种领域在我头上。

我了解这个定义:

指针是包含变量地址的变量

但是我仍然不太了解这个概念。回顾过去,我认为它集中在三件事上:

  1. 究竟什么存储位置?(当时我没有参加计算机组织课程)

  2. 笨拙的语法(所以,嗯...为什么将其定义为“ int * ip”,但随后我将变量称为“ ip”?)

  3. 存储变量的地址而不是仅仅使用变量有什么好处?

直到我购买了K&R书并完成了我真正掌握的所有问题。除了我长期完成计算机组织课程(我认为在学习C语言之前必须先完成该课程)之外,部分原因还在于我意识到指针可以用于函数,数组,结构...做有用的事情,而不仅仅是存储普通变量的地址。

但是到目前为止,我的“ aha”时刻是K&R解释定义简单指针的笨拙语法的方式。我在整本书中都做笔记(在书中我用自己的话改写了我的观点,以加深我的理解),这是与此相关的一个:

指针是包含变量地址的变量。使用'*'运算符既可以定义和取消引用指针(提供存储在它指向的内存位置的值);该表达式是助记符。

Ex.: 
   int a;      /* Variable 'a' is an integer */

   int *ip;   /* Variable ip is a pointer and dereferencing it gives an integer.
                 In other words, the expression *ip is an int, so ip is a pointer
                 to an int */

一直以来,我一直感到无法完全掌握更高级的指针概念,直到我的脑中根深蒂固。在完成该任务后,它无休止地困扰着我(顺便说一句,我做得不太好;))为什么在我(认为我)定义了“ * ip”之后就不存在“ * ip”。掌握这一点对于涉及指针(如函数指针)和更复杂的定义(如以下)的更高级概念至关重要:

char (*(x())[])()

总而言之,我认为指针的概念要求:

  1. 对内存在计算机中的布局方式(以及什么是内存)有基本的了解。

  2. 了解指针的功能有多强大(现实世界中的用法,而不仅仅是为了学习而学习的另一个抽象概念)。

  3. 通俗地说,对象形文字进行解密称为“指针的定义”

因此,总的来说,我认为学习指针至少应该有3个“ aha”时刻。我仍然是一名学生,所以我想您会喜欢一个仍然(相对)刚开始学习该概念的人的观点。


+1代表3个“啊哈!” monents。指针不断增加。我“理解”了很长时间,才意识到自己只有大约一半的指针被理解了:)
Binary Worrier,2010年

我认为您是完全正确的,因为很大一部分“不了解指针”实际上是在怪异的C语法上触发的。[思考:我想知道使用这种语法会有多么困难:PointerTo<int> a]
Benjol 2010年

同意,@ Benjol。我很惊讶语法int* ip并不常见。看到格式化后的代码,我终于开始理解指针。然后,我可以将其读取为“ ip的类型为int指针”。
雅各布

19

指针有点像您桌面上的应用程序快捷方式。删除快捷方式,目标仍然存在。启动快捷方式,目标就可以启动。

我总是通过在桌面上简单地创建一个txt文件和该文件的两个快捷方式来解释其工作原理。复制和删除快捷方式后,您可以看到人们了解“引用”背后的想法。

一旦小组了解了快捷键背后的基本知识,您就可以开始解释指针。他们可能会很容易理解。


这不是一个坏的类比。对于任何使用此字面意义的“硬链接”的人,只需添加几点,即使更改目录,它也始终指向其目标,即使该对象已重定位,指针也将指向原始内存。当目标不再存在时,“硬链接”会告诉您,悬空指针的指针应设置为NULL。
snmcdonald 2010年

硬链接就像参考计数的智能指针
jk。

1
+1。解释指针的最佳实践类比之一。我敢肯定,由于该功能是每个人最常用的功能,因此学生会立即理解。
Karthik Sreenivasan 2012年

13

8到10年前,我在社区大学教授了“ C”入门课程。这始终是一个有趣的话题。看起来最有效的方法是,在与同事讨论了几次之后,就是用咖啡杯和手。

我将咖啡杯(或一行用于数组)的类比用作变量(它可以容纳某些东西)。然后,我用我的手,它也可以握住东西,或者通过伸出食指“指向”咖啡杯。

紧握的手是零,手指指向我的头(像是模拟枪)是悬空的指针。

然后,通过一些演示和调试器的调试,大多数人都点击了它。


3
你已经把我弄糊涂了。
kirk.burleson,2010年

1
@柯克,怎么回事?让我看看是否可以清除它。
DevSolo

4
++没有什么比教导让您思考这些事情更重要的了。
Mike Dunlavey 2010年

我在大学里的一位讲师做过类似的事情,使用的是学生(其中一位叫“尼尔”(Niel),以增加笑声),而不是咖啡杯。晃晃晃晃的指向观众,是一个悬垂的指针,因为它可能指向任何东西。
卡兹龙

2
悬空的指针更像是指向Neil,然后让他离开椅子而不改变您的指向位置...然后尝试跟随该指针并将您在那找到的东西解释为Neil,而不管最终到那里的人。
乔恩·普迪

10

当我听到“您如何掌握指针”的问题时,我真的很担心。我一直认为这个概念非常简单,并且语言的逻辑演变为程序员提供了强大的功能。

让我担心的是,我从未发现很难理解指针的概念。因此,当您一遍又一遍“什么时候终于得到它”时,您开始思考:

我真的明白了吗?也许我从来没有做过?

也许这个概念似乎很棘手的原因是因为我们一直在告诉尚未碰到它们的每个人,指针是如此的困难,这里有一百种学习方法?

只是把那个想法抛诸脑后,我个人当然喜欢一个很好的图表,而史蒂夫·吉布森Steve Gibson)总是在解释任何事情上做得非常出色


有趣的是...您当时使用哪种语言?我认为C语法吸引了很多人。如果您首先了解装配,我可以看到这是一个原因。[顺便说一句,我想对此进行投票,但今天我已经达到上限。]
Macneil 2010年

有趣的是,很长一段时间我都不了解“危险”指针,他们使用Python(和大学的Java)工作。然后,我采用了“面向对象的方法”模块,该模块使用C ++作为选择的语言,直接进入其中。
Marcus Whybrow 2010年

同样,我认为了解程序在内存中的表示方式肯定会有所帮助,但是我想说的是,理解为什么指针是语言的有用补充是最有效的角度,因为尽管您经历了同样的过程。作为原始设计师的过程。
Marcus Whybrow

+1我不知道为什么人们认为指针是硬的还是神秘的。
ggambett 2011年

是的,指针一直非常简单和有用,以至于我无法想象认为指针有什么“硬”。当任何课程的老师说“现在,这有点棘手”时,我讨厌它,因为它是如此具有颠覆性。只是教那些该死的东西,让学生自己决定他们是否认为这很棘手。
乔恩·普迪

7

对于C语言中的指针,我从来没有什么问题,但这可能是因为我必须先学习汇编程序。实际上,不必再处理自己的地址,这真是一种解脱。因此,也许答案(假设这是您正在教的东西)是为学生提供一种可使用的模拟汇编语言。他们在编写任何比“ Hello,world”更复杂的东西的过程中弄清楚。


+1用于适应更原始的抽象,而不是尝试使用类比。
匿名类型

在我的高中时,计算机研究的一个单元专门用于研究火柴盒计算机,该计算机可以从黑板上进行教学,而无需接触或涉及真实的计算机。
rwong 2010年

@拉里·科尔曼,大会!!!!!!我想在C之前先尝试。请告诉我从哪里开始学习。免费电子书,免费PDF?IDE?请!!!!!!!!!!!!!!!!!!!
Spacez Ly Wang 2012年


6

我如何真正了解指针?通过写一个简单的编译器大学一年级。

如何用外行的术语解释指针?我喜欢存储在索引卡上的图书馆目录的(日期?)类比。每个卡(“指针”)都包含有关某本书(“数据”)所在位置的信息,但实际上并不包含该书本身。如果您修改卡(“指针算术”),它所做的就是更改它指向的书,并且对书本身没有影响-请注意不要弄乱地址,否则您可能会指向不存在的书甚至是错误的库。但是,如果您遵循卡上的“地址”并转到库的适当部分(“取消引用指针”),则可以查看/修改书籍本身。


为我的CS课程的记忆+1,而我对此有确切的解释
Gary Rowe 2010年

从某种意义上说,这是件好事,但有些误导,因为卡片实际上并没有说书在哪里。您仍然需要执行面向运动鞋的搜索算法。也许这可以更好地为数据库建模-通过键(调用号)引用存储的对象。
DarenW

+1这个类比保留了与Barfieldmv解释的概念相同的概念,但采用了更为现实的方法。
Karthik Sreenivasan 2012年

5

我将假设要学习指针的人知道普通变量是什么以及它们在C中的工作方式。现在,让我们尝试使用一些属性来定义指针-

  • 它们也是变量,但性质不同。假设可变空间中有两层。不同类型的普通变量位于上层,指针位于下层。像这个图

    替代文字

  • 顾名思义,“指针”可以指向某物。就像我们的手指可以指向某个对象。他们指的是什么?这些是正常变量。简而言之,“指针指向普通变量”。

  • 与普通变量一样,指针也具有相同数量的类型,例如int,char或float。特定类型的指针只能指向相同类型的变量。
  • 指针可以指向一个变量,然后同一指针可以指向另一个变量。只是类型应该相同。因此,指针与某个变量的关联不是永久的,可以更改。
  • 那么,如何声明一个指针?几乎像普通变量一样。您必须在名称前加上星号(*)。喜欢-

    int *pointer;
    
  • 那么,指针如何与变量关联?&在像这样的变量之前使用运算符-

    pointer = &variable;
    
  • 通过指向变量如何使用指针?也可以通过在名称前加上星号(*)来完成此操作。然后就可以代替它现在指向的变量了-

    *pointer = var1 + var2;
    

    代替

    variable = var1 + var2;
    
  • 现在,使用带有一些代码的指针。现在就习惯指针的这种特性。至此,我们正在讨论指针的作用。一旦确定,就可以开始研究指针如何指向某个变量,以及如果对它们应用普通的算术运算,它们将如何反应。然后去寻找指针与数组以及指针之间的关系。

这就是我建议学习指针的全部内容。


我想遵循“先做什么然后怎样做”的过程。抽象!
Gulshan

5

为支持该问题的修订要求而进行了编辑

我对“指针后”理解(如果我没记错的话)的方法是这样的。从我还不熟悉BBC Micro的那一刻起,我就具有一些简单的汇编编程经验,因此我将内存的概念定义为一堆盒子(参见下文)。这通过使用数组得到了加强。但是,我进入了C语言世界,不得不处理字符串,这意味着指针。在BASIC中,这是微不足道的,在汇编程序中,我不需要使用它们,现在在经典C语言中,所有的都是指针和东西。啊,但是我可以像这样(以空终止)返回到数组:

char s[] = "Hello, world!";
printf("%s",s);

很好,这只是一个字符数组(在我的小世界里,每个字符8位),末尾有一个零字符以显示其结束位置。printf只是获取该数组并对其进行打印。但是,如果我想将此字符串传递给函数怎么办?

void print_str(char* p) {
  printf("%s",p);
}

手册上说的是什么,但是那又是什么呢?嗯,char *表示“指向char的指针”。好...失去了我 然后我发现char *使p等于s [0]。好的,我可以使用它,但是我仍然没有限制指针是什么。我的意思是,我该如何使用其中之一设置一些数据?再次转到手册...

char* p = "Hello World!";

当我写上面的文章时,我对自己说:“声明一个指向char的指针,并将其设置为等于此字符数组”。该指针以某种方式消除了对数组的需求。猜猜是编译器为我做了一些改变。那么如何使用此指针更改数组?我知道我可以使用阵列版本

 s[2] = 'L'; 

但是“指针说话”的含义是什么?再次转到该手册...

*(p+2) = 'L';

我猜想*只是表示“内存地址的内容”而(p+2)s[2]。这意味着指针p是……只是……一个……地址……b!

有启蒙的声音。我突然改变了指针(很久以前,我们的旧计时器直到后来才“增长”)。这只是间接的。


原版的:

好吧,我的2c价值:

想象一下,内存是一堆盒子。每个盒子的侧面都有一个数字(地址)。每个框包含一个数字(内容)。您可以通过2种方式使用这些框:变量(我想要框N的内容),指针(我想要框N的内容无论框N是什么)。指针只是间接的。

要获得涵盖您将需要知道的所有内容的重要答案,请阅读此内容


++这或多或少是我教授该主题的方式。
Mike Dunlavey 2010年

编辑文章以支持OP要求。
加里·罗

您使用的是哪本手册,它在字符串的末尾添加了额外的NUL字符?
Rob Gilliam 2010年

@raimesh一个很老的(大约1991年)。不记得哪个。
加里·罗

1991年?对于C语言手册来说,这并不算老-K&R的第一版于1978年出版!只是出于好奇,那里曾经有一本手册,建议您在字符串常量的末尾添加\ 0。(实际上,再次查看它,是不是要输入\ n?)
Rob Gilliam 2010年

4

得到一些木头小块。

在一端增加金属钩,在另一端增加金属眼。

您现在可以在可以玩的东西中创建一个链接列表。

尝试用这个物理道具进行解释。当我教一年级(新生)学生的指针时,我经常希望有这个。

小金属钩是指针,东西指着木块。

我认为任何人在玩积木后都不会得到它。


4

当我删除所有绒毛并开始将指针视为任何其他变量而不是一些神奇的实体(很久以前在11年级)时,我的生活就变得更轻松了。我只知道3件事:

  1. 指针是一个变量,用于存储另一个变量的地址(或仅存储任何地址)。
  2. *用于获取指针变量中存储的内存位置的值。
  3. &运算符给出存储位置的地址。

剩下的就是语法糖和常识。.只需使用指针编写一些简单的C程序(如实现链接列表库)即可。


2
  1. 可以将指针视为对数组的索引的一般化。
    • 考虑到可以将一个大数组切成许多较小的,不重叠的,可变大小的数组。现在,这些较小的数组是我们通常认为的数组。那么更大的是计算机的整个内存空间。切掉较小数组的过程称为内存分配。
  2. 可以将通过某些指针链接在一起的一组结构视为有向图
    • 每个顶点都是一个可以保存一些值的变量。
    • 一些变量是指针,每个指针可以恰好具有一个指向其他对象的输出边缘。
    • 不是指针的变量将没有任何输出边。它们可以具有任意数量的传入边缘。

2

我不太记得指针周围的情况,但是我根据对C样式数组的理解回溯了内存。(即arr[3]与相同*(arr+3)

由于某种原因,我发现每当遇到指针位置时,将指针视为数组都将非常有帮助。


2

基本上,@ Gary Rowe引入了正确的模型。内存是一组带有地址(数字)的盒子。每个框存储一个值(数字)。

指针的想法是将一个框中的值解释为另一个框中的地址。该值用于引用特定的框,因此将其称为reference。因此,取消引用是打开所引用的框的过程。

如果v是变量(框),则该语句

  • v表示的价值v,即给我盒子里的东西
  • *v表示取消引用的值v,即给我由的值引用的框中的内容v
  • &v意味着参考v,即在盒子上给我地址

我认为它没有达到将指针引入完全不同的目的。小时候,这对我来说很难理解。似乎总是有些我从未真正理解的黑魔法,需要很多特殊字符。我第一次理解是当我使用没有指针算术的语言使用双向间接编写了一个小型游戏时。这启发了我。

指针只是一个解释问题。我认为解释一下使事情变得容易得多。如果显示一个具有10个变量的内存的简单示例,则指针算术是极其简单和直观的操作。


2

我真正感到震惊的解释是:

考虑一个在不同的土地上建有不同房屋的城市网格。您手里拿着一张纸。您在纸上写过:


大卫的房子,

某某街112号。


这张纸(指针变量)包含一个指向大卫家的地址。当您想告诉朋友看看大卫的凉爽房屋时,用纸价格作为房屋的参考要比在邮件中发送实际的两层楼建筑容易得多。

与真正的指针一样,当您遵循纸上的地址时,可能会遇到麻烦。大卫可能已经搬走了,当您到达那里时,您只会在地面上发现一个大洞。在这种情况下,最好在David移动或至少将其更改为新地址时擦除纸上的地址。您还可能会发现自己去了地址,然后输入您认为是朋友大卫的客厅的地址,但是这次您最终进入了一个完整的陌生人游泳池。有人将您地址上的空格用于其他完全不同的地方。


2

如果要解释指针,则必须先解释内存。我通常使用带有行和列的方格纸/方格纸执行此操作。如果“学生”了解内存,则她可以了解地址是什么。如果您有地址,则有指针。

您可以使用这种抽象。例如,将一个方格的地址(数字)写入另一个方格。现在从指针正方形到目标正方形绘制一个箭头。现在覆盖指针(例如增加指针)并调整箭头。在另一个方块中写一个地址,让学生画箭头...

下一步:给某些方块(如指针)起一个名字。现在您可以解释取消引用。而已。


2
让我想起了我接触过实际使用电子的计算机之前使用过的“计算机”,即我认为它叫做“纸板”的“ CARDIAC”。从字面上看,将数字写在数字框中可以从其他数字框中获取数字。这是有教育意义的,我从没有真正理解真正微处理器上的指针的困难。
DarenW

2

也许只有我一个人,但是我可以很好地与类比一起工作。因此,假设您有一个朋友(功能/类)“ Foo”,但由于某种原因,他想让其他人(不同的功能/类)“ Bar”与您联系。“ Foo”可以带您去看看“ Bar”,但这不方便,将所有这些生物(实例)移动到四周。但是,“ Foo”可能会向“ Bar”发送您的电话号码(指针)。这样,无论您身在何处,“ Foo”都知道如何联系您而无需找到您。

并且,假设“ Bar”有一个熟人“ Baz”,他也想与您联系。但是,您可以保护自己的电话号码,并且不希望所有人都拥有,“ Baz”可以呼叫“ Bar”(电话作为指针),然后后者可以将呼叫转发给您(另一个指针)。依此类推,直到“巴兹”的朋友和朋友的朋友。


2

让指针方式,如果你研究汇编语言和/或计算机架构更有意义。我认为,如果我教C类,那么我将从几周的体系结构入手,以解释内存模型和处理器实际执行的指令种类。


绝对。当您处理寄存器并了解立即值和间接寻址之类的内容时,指针的整个概念很直观。在编写第一行C语言之前,我学习了6502汇编语言,然后学习了68K汇编语言,因此当我被介绍给指针时,我已经看过编译器的(中间)汇编语言,它完全符合预期。
Radian

2

我的“啊哈!” 本教程中出现的时刻:

C语言中的指针和数组教程

确切地说,它出现在本章中:第3章:指针和字符串

更准确地说,它带有以下句子:

传递给puts()的参数是一个指针,即一个指针的值(因为C中的所有参数都按值传递),而指针的值就是它指向的地址,或者简单地是一个地址。

当我读到这篇文章时,乌云散开,天使们吹响了号角声。

因为,您看到的是,在此之前我读过的每本C教程或书都断言C可以通过值或引用来传递邪恶的谎言。事实是C总是按值传递,但是有时传递的值恰好是一个地址。在该方法中,该地址是一个副本,就像复制传入的int一样。副本不是由指针指向的值组成的。因此,通过使用方法中的指针,您可以访问原始值并进行更改。

我从未成为C程序员,但后来成为.NET程序员,并且对象和对象引用的工作方式相同。对对象的引用按值传递(并因此被复制),但对象本身未复制。我与许多不了解这一点的程序员合作,因为他们从未学习过指针。


1

诀窍是要解释事物的位置和事物本身并不相同,就像管道的图片不是管道一样。当您移动事物时,其位置会改变。该位置仍然存在,可以将其他东西放在那里。


1

指针是一个便签,可以告诉您有用的内容在哪里。它包含事物的位置,并告诉您事物的大小(无论如何,在C中)。因此,双指针就像一个便签,上面写着“冰箱里有六包”。您必须实际得到六支装才能确定是可口可乐还是百威啤酒。


1

给定代码:

int v=42; //声明并初始化一个简单的变量

int *p = &v; //为变量v创建一个点p

关于上面的代码,可以这样说:

int * p //“ int指针p” ...这就是您如何声明一个指向int类型变量的指针

*p //“由p指向” ...即p指向的数据,与v相同。

&v //“变量v的地址” ...这表示p的文字值


1

http://cslibrary.stanford.edu/

该站点提供了很棒的教程,用于学习指针和内存管理。

我建议您逐步了解该站点上提供的指针基础知识,指针和内存。您还可以查看链接上给出的链接列表问题,以进一步加强指针概念。


1

解释指针的关键是要确保向您解释的人已经了解了内存的概念。如果他们真正了解它的底层知识,那会很不错,因为他们认为内存作为一个庞大的数组存在,并且了解您可以通过其索引位置访问数组中的任何位置就足够了。

下一步,具有传递索引位置而不是复制整个内存的概念对大多数人来说都是有意义的。这足以使大多数人理解为什么指针有用。

理解指针的最后一步是说明如何将存储索引位置作为参数传递给该方法,以存储所有数据存储位置的索引位置。我发现对于某些人来说这可能太过分了。

一旦有人掌握了这些基本步骤,他们便可以直接理解,可以无限期地链接指针,只要您跟踪需要多少次查看地址即可找到实际的数据对象。

一旦有人掌握了指针,他们必须快速掌握的下一件事情就是堆内存和堆栈内存之间的区别,以及为什么将指针传递给方法之外的堆栈内存是危险的。


0

我记得有一本书“ C困惑”或类似的书,我读这本书纯粹是因为它是图书馆中与编程/计算机相关的少数书籍之一,我对C的理解是基本的。它对您产生了C表示,并要求爆炸它,变得越来越复杂。


0

当我上大学时,我的教授有一些非常整洁的PowerPoint幻灯片,它们将一个点单独描述为一个单独的变量,并带有指向存储位置的箭头(表示为数组),当我们执行“链接列表”时,他会一步一步地完成分步显示箭头何时更改,指针何时取消引用等...,在几分钟之内就无法理解它。这个概念本身确实很容易,但是正确执行或在实际程序中应用它需要更多的实践。


0

在此之前,我将解释在编程中“一切都使用内存”以及在内存中进行(静态)变量分配。我还将解释什么是内存地址,以及内存空间,内存地址和变量之间的关系。

最后,我将解释整数数据类型和变量,字符串数据类型和变量...等等,直到解释存在一种特殊的数据类型来存储内存地址,该地址的空值如0 o“”,称为null

最后,通过指针的使用来动态分配变量。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.