|
这是一个群友发的笔试题目,里面涉及的东西也比较有意思。 直接看代码 void (*f[])(char *)' a' K* e: t: R5 n这个是个什么东西? 我们先看看下面的东西 函数指针和指针函数的定义我们看个代码 int *func(int a,int b)我们之前说过运算符的优先级,「 * 」 的优先级低于「( 」 由于「 * 」的优先级低于「 () 」的优先级,因而func首先和后面的「 () 」结合,也就意味着,func是一个函数。即: int *(func)(int a,int b)# ?8 B2 ?; p/ J0 f) M然后这个函数的返回值的类型是「 int * 」 即:指向int类型的指针 然后我们这样修改上面的代码 int (*func)(int a,int b)6 J S8 i K* D, q3 s' b# s「(*func) 」说明func是一个指针,然后后面跟着「()」说明这个指针指向一个函数,即指向函数的指针。 所以 函数指针: 首先是一个指针,这个指针指向一个函数 指针函数:首先是一个函数,这个函数的返回值一个指针9 {2 Z" J$ ` S$ K. D @: Y 我们声明一个函数指针,正常方法是 int (*pfunc)(int a,int b)当我们命名很多个函数指针的时候,用上面的方法显得非常不方便,所以我们可以这样做 typedef int (*PF) (int a,intb)9 }8 o, A9 L+ v' ~( r3 c$ nPF pfunc;: P9 l* b+ ?6 H& ], r4 O 例程: #include "stdio.h"4 ?, g+ F; I0 s8 Z6 M `typedef int(*PF)(int, int);3 [( p5 T2 P$ A: m/ S+ p $ @! @. T3 K9 a6 m6 Y- B9 \ int add(int a, int b)( C N) _# T2 y" q- ] { return a + b;3 h Z E: }8 b% `! V } int reduce(int a, int b)- g2 S' P4 y$ s# O: n# X {1 X9 W8 j/ l* Y& x7 m return a - b;* o0 b; ]! q4 |3 B/ R G; e }2 B& N: V. ]7 |2 ^4 Z * ^# F& A4 _5 r& W; x/ u int main() { PF pfunc = NULL;& l1 Y* U) ?! O( H, T' S& ` pfunc = add;9 Z; u! |7 }: G/ |# c printf("add:%d\n",pfunc(3, 4));+ P3 ~ u/ Z( \6 U pfunc = reduce;/ h+ x' A! V/ T- y0 x printf("reduce:%d\n", pfunc(3, 4)); /*getchar用VS编写方便查看输出*/ getchar(); return 0;; ]2 v7 k C6 U6 `7 K6 o }* g- @4 v# S* F( ?9 T1 L" `
f 是个什么鬼东西? [] 的优先级 比 *的优先级高,所以 f首先是修饰了数组,然后跟后面的 *组合,就说明这个数组里面住的都是 指针,这些指针是什么呢,再出来看看就看到了,这个指针是 一个函数,这个函数的 参数是 char *返回值是void。 示例代码 #include <stdio.h>9 b [+ z1 m4 L- ~ y C1 y, R( V# Bvoid (*f[3])(char *);; Z8 ?2 ~: I0 s4 X$ P( o void efunction(char * s)4 u& W/ g) b! r/ ~ { printf("%s\n",s); }( v7 H$ L* a9 C int main() { f[0] = efunction; //void (*f[])(char *) = {efunction}; , D, P8 w3 _, ?5 {4 A6 B (*f[0])("hello code"); return 0; }% Z2 w8 ~" @% B 代码输出 hello code- | C4 \+ O6 s$ `( e* i0 t -------------------------------- Process exited after 0.08441 seconds with return value 0 P# P6 A* H! t* m- } 请按任意键继续. . .1 X) j: |; J) y" m% ]* G, K Z 函数指针在项目里的实际应用 这是我的android项目hal部分的代码,这部分代码用到的是函数指针,通过name来调用不同的函数。
我们有时候看别人的代码时候,经常是一面懵逼,比如下面这个void (*p)();还有这个(*(void(*) ())0)(); 我记得我在以前的文章里面有谈到一个右左原则,从p开始看,往右走直到遇到)再往左走遇到(,(*p)我们就可以看出p是一个指针,继续分析往右走,遇到(),说明p指向一个(void)的函数,往左走,知道p指向的函数返回值是void。 ok,看下面的例子。 #include "stdio.h"1 ]5 l8 S4 C& O1 t) A5 G Q9 v( c! X* E" D6 ]7 O void Function() { printf("Call Function!\n");. j7 w' z$ x& ~4 ^$ ^8 G } int main(). n) S e6 t6 J" p* N { void(*p)();! U3 Q2 @/ T" k *(int*)&p = (int)Function;! q3 r5 w" @; o* ~ (*p)();. O& N0 { \& ^0 z# m0 x( @' }; V* R getchar(); return 0; }% [$ l9 e0 U4 l, U8 A
然后继续分析(*(void(*) ())0)();
#include <string.h>0 q: D. [2 g3 x! v ( N1 \9 K1 d5 F* P2 Y( o7 J char * fun1(char * p)( a; G8 w' }* S( _# o! R { printf("%s\n", p); return p;1 P$ i0 ^' D- h! d- d2 W4 ^1 V } & ^5 j/ w4 n6 u char * fun2(char * p) { printf("%s\n", p); return p;6 J2 |8 N0 V- w+ @) r } 4 D9 _4 m2 b- x" e7 m' W char * fun3(char * p) { printf("%s\n", p);0 P9 Z) W0 Q" _0 ]0 G9 N# Q return p;2 w3 @/ C+ v4 [ n } o5 s) M( {* K; i% `7 X7 q" m 4 @; |# O0 C, O8 ^( n* K int main() { char * (*pf[3])(char * p); pf[0] = fun1; // 可以直接用函数名 pf[1] = &fun2; // 可以用函数名加上取地址符' c! O b2 A1 v5 V6 S% d pf[2] = &fun3;/ d; `& } G" E/ d2 n 7 _5 q' b( w9 t a/ j" ? pf[0]("fun1"); pf[0]("fun2");) k1 m% _) V2 z$ f! F pf[0]("fun3");: s4 b5 I; |0 U% o8 f getchar();# e! e6 m: X8 [( a$ c/ W return 0; } |
微信公众号
手机版