天天看点

函数指针,指针函数,函数指针数组

这是一个群友发的笔试题目,里面涉及的东西也比较有意思。

直接看代码

这个是个什么东西?

我们先看看下面的东西

我们看个代码

我们之前说过运算符的优先级,「 * 」  的优先级低于「(  」

由于「 * 」的优先级低于「 () 」的优先级,因而func首先和后面的「 () 」结合,也就意味着,func是一个函数。即:

然后这个函数的返回值的类型是「  int * 」 即:指向int类型的指针

然后我们这样修改上面的代码

「(*func) 」说明func是一个指针,然后后面跟着「()」说明这个指针指向一个函数,即指向函数的指针。

所以

函数指针: 首先是一个指针,这个指针指向一个函数

指针函数:首先是一个函数,这个函数的返回值一个指针

我们声明一个函数指针,正常方法是

当我们命名很多个函数指针的时候,用上面的方法显得非常不方便,所以我们可以这样做

例程:

函数指针,指针函数,函数指针数组

img

再说回上面的那个题目

<code>f</code> 是个什么鬼东西了?

<code>[]</code> 的优先级 比 <code>*</code>的优先级高,所以 <code>f</code>首先是修饰了数组,然后跟后面的 <code>*</code>组合,就说明这个数组里面住的都是 指针,这些指针是什么呢,再出来看看就看到了,这个指针是 一个函数,这个函数的 参数是 <code>char *</code>返回值是<code>void</code>。

示例代码

代码输出

函数指针在项目总的实际应用

这是我的android项目hal部分的代码,这部分代码用到的是函数指针,通过name来调用不同的函数。

函数指针,指针函数,函数指针数组

android hal部分代码

我们有时候看别人的代码时候,经常是一面懵逼,比如下面这个<code>void (*p)();</code> 还有这个<code>(*(void(*) ())0)();</code>

我记得我在以前的文章里面有谈到一个右左原则,从<code>p</code>开始看,往右走直到遇到)再往左走遇到<code>(</code>,<code>(*p)</code>我们就可以看出<code>p</code>是一个指针,继续分析往右走,遇到<code>()</code>,说明<code>p</code>指向一个<code>(void)</code>的函数,往左走,知道<code>p</code>指向的函数返回值是<code>void</code>。

ok,看下面的例子。

函数指针,指针函数,函数指针数组

输出结果

然后继续分析<code>(*(void(*) ())0)()</code>;

1、<code>void (*)()</code>  我们上面分析了这个是一个函数指针,只是把<code>p</code>去掉了而已。

2、把上面的<code>void (*)()</code>用<code>pn</code>代替,上面的表达式变成<code>(*(pn)0)()</code>;<code>pn</code>后面有一个<code>0</code>,这个是让我们咋舌的地方,然后我们向一下 <code>(char)a</code>;这样的表达式,所以<code>*(pn)0</code>就是把<code>0</code>当成一个地址,强制转换为pn类型,用<code>*</code>这个钥匙取出这个地址区域的值。

3、把<code>(*(pn)0)()</code>替换成<code>pm</code>,原来的表达式变成<code>pm()</code>,这样大家看起来比较容易了吧,就是正常的函数调用。

文章来源于嵌入式linux ,作者写代码的篮球球痴

继续阅读