到目前为止,我提出的最好的一个是卡片目录包含有关如何烹饪不同类型食物的说明。它不包含有关如何烹饪食物的信息,也不包含烹饪食物本身的说明,但它可以指向位于其他地方的相关说明。这是一个很好的比喻,因为它展示了能够烹饪不同类型的食物(墨西哥,素食,印度等)的灵活性,但卡片目录的概念很快被计算机化搜索所取代。我被问到可怕的“什么是卡片目录?”使用Google作为查找烹饪说明的示例是可以的,但是没有明确区分到物理位置,查找指令和“执行它们”。任何人都有任何适用于他们的类比吗?
答案 0 :(得分:15)
我认为通过非技术类比尝试教授一个非常技术性的概念并不是一个好主意 - 大概是你教的人不需要模糊的“管理总结”这种理解,他们最终需要申请这个概念具体地说,为什么这么绕道呢?
为什么不用简单的编程示例来解释它?也许最好的一种是通用排序算法(可能是学生已经学会了排序)。
“函数指针基本上是一种传递一段代码的方法,可以被其他不需要事先了解它的代码调用。例如,像quicksort或mergesort这样的排序算法实际上只需要知道一个关于它排序的东西的事情:如何比较它们。但是如果你在排序算法中建立比较,它只能比较一个东西,比如整数。通过将比较逻辑作为函数指针传递给排序算法,每当算法需要比较元素时调用,现在可以使用算法对任何事物进行排序而不必更改其代码 - 如果你想用它来比较苹果和橙子,你只需要写一个水果 - comaprison函数并将指向它的指针传递给排序算法,以及要分类的水果。“
答案 1 :(得分:5)
这个比喻似乎过于复杂。
功能指针就像可以为您完成工作的人的电话号码。
答案 2 :(得分:2)
我建议告诉你的学生 后来,他们会问自己“什么是解决这个问题的正确工具?”而不是“我的问题叫什么?”
想象一下,您编写的程序采用位图并将其转换为图像文件。位图有多种格式(黑色和白色,真彩色,带alpha通道的真彩色等)。并且有各种图像文件格式(JPEG,PNG,GIF)。如果你试图在没有函数指针的情况下编写它,你最终会得到N * M算法:N表示输入位图的数量,M表示支持的输出格式数。在这个基本的例子中,那将是9(3 * 3)。明天,你的老板也来了,也想要支持TIFF。这意味着12(3 * 4)算法。规格的微小变化会导致很多工作。死路一条。
但你可以定义三个函数指针:getWidth(bitmap)
,getHeight(bitmap)
,getPixel(bitmap, x, y)
现在你只需要N个算法来实现这三个FP。每种算法都适用于每种位图,并知道如何读取它。输出算法不再关心输入图像是什么样的,它们只需要三个FP来访问现在抽象的图像数据。所以你最终得到了6(3 + 3)种算法,当你的老板带有TIFF时,你只需要添加一个算法:7而不是12。
从计算机的角度来看,FP是蹦床。它不是开始在FP的地址(正常函数调用)上执行代码,而是读取存储在那里的地址,并开始执行地址在FP中保存的代码。
您需要编写的有趣代码只是为了让编译器满意。在汇编程序中,这看起来很简单。正常函数调用:
lea.l someFunction,a0 # Load address of someFunction
jsr.l a0 # Jump to subroutine
功能指针:
lea.l functionPointer,a0 # Load address of functionPointer
move.l (a0),a0 # Load what is stored at functionPointer into a0
jsr.l a0 # Jump to subroutine
正如您所看到的,只有一个指令差异。
答案 3 :(得分:1)
扩展卡片的想法:想象一下你玩游戏,你必须做你在卡上写的东西。所有的牌都是在比赛前写的,你知道完整的名单,但不知道你会选择的牌。
答案 4 :(得分:1)
函数指针就像信用卡。 :)
要进行付款,您无需携带资金自行进行交易,只需刷卡即可完成交易。
交易可以由不同的银行以不同的方式完成,但信用卡看起来仍然是相同的,并且工作方式相同。您无需了解其背后的所有细节,您只需知道如何使用该卡。
答案 5 :(得分:0)
我会说一个函数指针就像“实现的地址”到特定的“声明规范”(除非你处理空洞)。解释编译器检查指针类型以检查您是否正在使用具有正确实现的规范,并且该实现只是一个期望某个调用约定的指令块。
不是类比,但可能更简单。
答案 6 :(得分:0)
.NET称之为delegates,这可能对类比有用。
你可以说一个函数指针是你将你的工作委托给某人(工人,公司)的地址。
答案 7 :(得分:0)
我总是将函数指针视为提供将函数作为参数传递的机制(以及其他用途)。因此,如果你问“如何将此函数传递给另一个函数”,答案将是使用它的引用(指针)。不知道这是否有帮助。
答案 8 :(得分:0)
我认为“指针”可以称为“标识符”(这是合理的,因为实例的“内存地址”是其“身份”)。因此,“指向函数的指针”只是“存储某个函数的标识的变量”(假设您知道'函数'是什么)。
答案 9 :(得分:0)
无论如何,卡片目录似乎有点奇怪。与你的主题一起,对函数指针进行更好的比喻IMO就是它们是食谱索引中的一个条目。 “Cajun ...... 39”,所以你去第39页,并有烹饪Cajun的说明。
答案 10 :(得分:0)
此剪辑描述了CDS(信用违约掉期)。它正是指针如何影响您的系统。
http://www.youtube.com/watch?v=KPNdYtrlgaU#t=120s
“在这里,我们知道我们有一种特定的金融工具的工具,这种工具具有明显的危险性,它会产生长链风险,这些风险很容易受到该链中个体交易者或市场参与者的失败的影响,这些工具在影响中允许产生恶性循环。其中CDS价格与约束价格相互作用,市场价格可能会出现螺旋式上升。“我的耳朵告诉我:“不要创造依赖性,这会产生长链的崩溃系统。”
所以,如果他们知道什么是CDS。然后它会很容易。 :)