﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-Freedom</title><link>http://www.cppblog.com/viki/</link><description>C++  OpenGL  English</description><language>zh-cn</language><lastBuildDate>Wed, 08 Apr 2026 03:54:50 GMT</lastBuildDate><pubDate>Wed, 08 Apr 2026 03:54:50 GMT</pubDate><ttl>60</ttl><item><title>指针函数&amp;函数指针</title><link>http://www.cppblog.com/viki/archive/2008/08/06/58157.html</link><dc:creator>Freedom</dc:creator><author>Freedom</author><pubDate>Wed, 06 Aug 2008 08:20:00 GMT</pubDate><guid>http://www.cppblog.com/viki/archive/2008/08/06/58157.html</guid><wfw:comment>http://www.cppblog.com/viki/comments/58157.html</wfw:comment><comments>http://www.cppblog.com/viki/archive/2008/08/06/58157.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/viki/comments/commentRss/58157.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/viki/services/trackbacks/58157.html</trackback:ping><description><![CDATA[<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">iostream</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br>#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><br></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;std;<br><br></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;alert(&nbsp;</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">&nbsp;msg&nbsp;)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;msg&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;endl;<br>}<br><br></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">GetFunction())(</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;alert;<br>}<br><br></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;main()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;&nbsp;&nbsp;&nbsp;刚看完C++&nbsp;Primer第七章，合上书，写个复杂点的函数试一下，刚开始函数声明不是这样的，一点点往上加后来才变成了void&nbsp;(*((*ptr)()))(string)。<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">写完后就有种预感——明天看了估计就看不懂了，赶紧记下来，呵呵。<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;&nbsp;&nbsp;&nbsp;正在从C#转C++，这是在园子C++版里的第一篇文章，有错的地方请大家不要给面子，该拍砖拍砖；-）<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">ptr是一个指针，他指向一个函数，这个函数返回一个指针，该指针指向一个函数，这个函数带有一个string参数，但是没有返回值</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">((</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">ptr)()))(</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;GetFunction;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">写完了声明然后调用，刚开始我写的是(*ptr)()("Hello&nbsp;C++")，一运行结果出来了，挺开心，可是在重读一遍的时候发现自己写&#8220;错&#8221;了，忘了解引用<img src="http://www.cppblog.com/Images/dot.gif">可是结果怎么是对的？<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">接着又写了(*((*ptr)()))("Hi&nbsp;C++")，F5，结果也出来了<img src="http://www.cppblog.com/Images/dot.gif">于是刚从函数声明中解脱出来的大脑又晕了<img src="http://www.cppblog.com/Images/dot.gif"></span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;(</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">ptr)()(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Hello&nbsp;C++</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br>&nbsp;&nbsp;&nbsp;&nbsp;(</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">((</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">ptr)()))(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Hi&nbsp;C++</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">为什么呢，难道函数指针在调用时解不解引用都可以吗？为了证明这个结论，再声明一个的函数指针试一下</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;&nbsp;(</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">ptrAlert)(</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">);<br>&nbsp;&nbsp;&nbsp;&nbsp;ptrAlert&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;alert;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">不解引用</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;ptrAlert(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Hello&nbsp;Alert</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">解引用</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;(</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">ptrAlert)(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Hi&nbsp;Alert</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;结论：函数指针在调用时解不解引用都可以<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在网上搜到的相关资料：<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;围绕这两种写法，当初C89制定的时候曾经有过争论。(*p)();是一种旧式的规定，旧式规定圆括号左边必须具有&#8220;函数&#8221;类型，如果是指向函数的指针，<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;那么必须加上*声明符。但C89不再把圆括号的左边限定为&#8220;函数&#8221;类型，而是一个后缀表达式。那么问题就来了，如果p的值是函数地址，那么*号就是声明符，<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;但如果p指向的内容是函数地址，*号就得被看作运算符了。同一种形式会有两种解释，这是一个矛盾。不仅函数调用如此，指向数组的指针也存在这种矛盾。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;编译器为了处理这种情况得增加代码，效率自然就降低了。争论的最后结果是谁也不能把对方完全说服，于是就干脆两种都支持了。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;说实话，我没怎么看懂上面的话，因为不了解C89这些标准，只是觉得(*p)()容易理解些，虽然写着麻烦点，以后c++程序写多了应该会有更深的认识吧。<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br>}</span></div>
<img src ="http://www.cppblog.com/viki/aggbug/58157.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/viki/" target="_blank">Freedom</a> 2008-08-06 16:20 <a href="http://www.cppblog.com/viki/archive/2008/08/06/58157.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>