日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2023/12/2 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 函数指针,指针函数,函数指针数组 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這是一個群友發的筆試題目,里面涉及的東西也比較有意思。

直接看代碼

void?(*f[])(char?*)

這個是個什么東西?

我們先看看下面的東西

函數指針和指針函數的定義

我們看個代碼

int?*func(int?a,int?b)

我們之前說過運算符的優先級,「?*?」 ?的優先級低于「??」

由于「?*?」的優先級低于「?()?」的優先級,因而func首先和后面的「 () 」結合,也就意味著,func是一個函數。即:

int?*(func)(int?a,int?b)

然后這個函數的返回值的類型是「??int *?」?即:指向int類型的指針

然后我們這樣修改上面的代碼

int?(*func)(int?a,int?b)

(*func)?」說明func是一個指針,然后后面跟著「()」說明這個指針指向一個函數,即指向函數的指針。

所以

函數指針:?首先是一個指針,這個指針指向一個函數

指針函數:首先是一個函數,這個函數的返回值一個指針

用typedef聲明一個函數指針

我們聲明一個函數指針,正常方法是

int?(*pfunc)(int?a,int?b)

當我們命名很多個函數指針的時候,用上面的方法顯得非常不方便,所以我們可以這樣做

typedef?int?(*PF)?(int?a,intb) PF?pfunc;

例程:

#include?"stdio.h"typedef?int(*PF)(int,?int);int?add(int?a,?int?b) {return?a? ?b; }int?reduce(int?a,?int?b) {return?a?-?b; }int?main() {PF?pfunc?=?NULL;pfunc?=?add;printf("add:%d\n",pfunc(3,?4));pfunc?=?reduce;printf("reduce:%d\n",?pfunc(3,?4));/*getchar是用VS編寫方便查看輸出*/getchar();return?0; }

再說回上面的那個題目

void?(*f[])(char?*)

f?是個什么鬼東西了?

[]?的優先級 比?*的優先級高,所以?f首先是修飾了數組,然后跟后面的?*組合,就說明這個數組里面住的都是 指針,這些指針是什么呢,再出來看看就看到了,這個指針是 一個函數,這個函數的 參數是?char *返回值是void。

示例代碼

#include?void?(*f[3])(char?*);void?efunction(char?*?s) {printf("%s\n",s); }int?main() {f[0]?=?efunction;//void?(*f[])(char?*)?=?{efunction};?(*f[0])("hello?code");return?0; }

代碼輸出

hello?code-------------------------------- Process?exited?after?0.08441?seconds?with?return?value?0 請按任意鍵繼續.?.?.

函數指針在項目總的實際應用

這是我的android項目hal部分的代碼,這部分代碼用到的是函數指針,通過name來調用不同的函數。

懂了這些,我們就可以看懂別人的代碼了

我們有時候看別人的代碼時候,經常是一面懵逼,比如下面這個void (*p)();?還有這個(*(void(*) ())0)();

我記得我在以前的文章里面有談到一個右左原則,從p開始看,往右走直到遇到)再往左走遇到(,(*p)我們就可以看出p是一個指針,繼續分析往右走,遇到(),說明p指向一個(void)的函數,往左走,知道p指向的函數返回值是void。

ok,看下面的例子。

#include?"stdio.h"void?Function() {printf("Call????Function!\n"); }int?main() {void(*p)();*(int*)&p?=?(int)Function;(*p)();getchar();return?0; }

然后繼續分析(*(void(*) ())0)();

  • 1、void (*)()??我們上面分析了這個是一個函數指針,只是把p去掉了而已。

  • 2、把上面的void (*)()用PN代替,上面的表達式變成(*(PN)0)();PN后面有一個0,這個是讓我們咋舌的地方,然后我們向一下?(char)a;這樣的表達式,所以*(PN)0就是把0當成一個地址,強制轉換為PN類型,用*這個鑰匙取出這個地址區域的值。

  • 3、把(*(PN)0)()替換成PM,原來的表達式變成PM(),這樣大家看起來比較容易了吧,就是正常的函數調用。

給個例子自己去參透一下

#include? #include?char?*?fun1(char?*?p) {printf("%s\n",?p);return?p; }char?*?fun2(char?*?p) {printf("%s\n",?p);return?p; }char?*?fun3(char?*?p) {printf("%s\n",?p);return?p; }int?main() {char?*?(*pf[3])(char?*?p);pf[0]?=?fun1;?//?可以直接用函數名pf[1]?=?&fun2;?//?可以用函數名加上取地址符pf[2]?=?&fun3;pf[0]("fun1");pf[0]("fun2");pf[0]("fun3");getchar();return?0; }

聲明:

本文于網絡整理,版權歸原作者所有,如來源信息有誤或侵犯權益,請聯系我們刪除或授權事宜。

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的函数指针,指针函数,函数指针数组的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。