日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務,提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

函數(shù)指針

函數(shù)也有自己的地址,函數(shù)名/&函數(shù)名 就是函數(shù)的地址


 

1.1基本形式

在 數(shù)組指針的學習中我們了解到

int arr[5]; int (*pa)[5] = &arr;//pa是數(shù)組指針

指針變量pa的類型是int(*)[5]

那么函數(shù)指針的形式是怎樣的呢?

void test(char* str) {} int main() { void (*pt)(char*) = test; //pt是一個函數(shù)指針 return 0; }

pt的類型是void (*)(char*)

下面哪個代碼有能力存放函數(shù)的地址呢?

void (*pfun1)(); void *pfun2();

答:pfun1可以存放

 

pfun1先和*結(jié)合,說明pfun1是指針,指針指向的是一個函數(shù),指向的函數(shù)無 參數(shù),返回值類型為void pfun2先和()結(jié)合,判斷為一個返回值為int*類型的函數(shù)

 

那么,如何書寫一個函數(shù)指針呢?

int Add(int x, int y) { return x + y; }

以Add函數(shù)為例,它有兩個int類型的形參,返回類型是int

所對應的函數(shù)指針就是int(*)(int,int)類型

int (*pf)(int, int) = Add;

依據(jù)以下幾步就能正確寫出函數(shù)指針

(1)確定函數(shù)的返回類型

(2)確定函數(shù)的參數(shù)類型和個數(shù)

(3)把函數(shù)參數(shù)類型里的變量名去掉,放入括號里

(int x,int y)去掉x、y,即(int,int)

(4)在前面加上函數(shù)的返回類型

(5)最后加上(*),以及函數(shù)指針變量名

需要注意的是,(*pf)的括號不能省略,否則編譯器會報錯

 

去掉括號之后就相當于函數(shù)聲明,無法賦值

 


 

1.2用函數(shù)指針來調(diào)用函數(shù)

如下圖所示,當我們定義了一個函數(shù)指針后

就可以通過指針來訪問原函數(shù)

這時候(*pf)其實就相當于my_test


 

我們可以通過函數(shù)指針來調(diào)用上面提到過的Add函數(shù)

?int Add(int x, int y) { return x + y; } ? int main() { int (* pf)(int, int) = Add; int sum = (*pf)(2,3); int sum1 = pf(2, 3); ? int sum2 = Add(2, 3); printf("%dn", sum); printf("%dn", sum1); printf("%dn", sum2); ? return 0; }?

可以看到,sum和sum1兩種形式都正確調(diào)用了該函數(shù)


 

因為我們已經(jīng)把Add的地址轉(zhuǎn)給了pf指針,函數(shù)名Add和指針pf實際上是等價的

所以在使用函數(shù)指針的時候,可以不帶*使用。但是帶*的時候一定要加括號!

1.3兩個奇葩的代碼

奇葩代碼1

(*(void (*)())0)();

這里的0僅為示例,我們在正常使用的時候并不能訪問0的地址

看到這個代碼的時候,是不是有點懵?

別急,讓我們來慢慢分析一波!


 

奇葩代碼2

void (*signal(int , void(*)(int)))(int);


 

說人話就是,signal函數(shù)內(nèi)傳入了一個void(*)(int)的函數(shù)指針,返回值也是一個void(*)(int)的函數(shù)指針!

void fun(int num) { printf("fun-->%dn", num); } void ( *signal( int, void(*)(int) ) )(int); ? int main() { void(*pf)(int);//定義一個函數(shù)指針 pf = signal(100, fun); //為signal函數(shù)傳參,并用pf指針接收 return 0; }

“這個代碼2是真的奇葩,就沒有什么辦法把他變成人話嗎?(簡化一下)”

當然有!那就是用typedef函數(shù)來給void(*)(int)指針起一個新名字!

typedef void(*pf_t)(int); //把void(*)(int)命名為pf_tvoid(*p)(int);//p是函數(shù)指針變量的名字 typedef void(*pf_t)(int);//pf_t是一個新的類型名

這樣我們的代碼就能得到簡化

void ( *signal( int, void(*)(int) ) )(int);//源代碼 //簡化后 pf_t siganal(int,pf_t);

這樣是不是就更容易分辨了?

2函數(shù)指針數(shù)組2.1基本形式

既然函數(shù)指針也是一個指針類型,那我們就可以用指針數(shù)組來存放它

前提:這些函數(shù)的參數(shù)類型、返回類型一致

int Add(int x, int y) { return x + y; } int Sub(int x, int y) { return x - y; } int Mul(int x, int y) { return x * y; } int Div(int x, int y) { return x / y; } //函數(shù)指針數(shù)組 int (*pfArr[4])(int, int) = {Add, Sub, Mul, Div};?

相比于分開寫多次函數(shù)調(diào)用

//多次函數(shù)調(diào)用 int (*pf1)(int,int) = Add; int (*pf2)(int, int) = Sub; int (*pf3)(int, int) = Mul; int (*pf4)(int, int) = Div;

函數(shù)指針數(shù)組可以讓我們以使用數(shù)組的形式來訪問每個函數(shù)

int Add(int x, int y) { return x + y; } int Sub(int x, int y) { return x - y; } int Mul(int x, int y) { return x * y; } int Div(int x, int y) { return x / y; } ? int main() { int (*pfArr[4])(int, int) = {Add, Sub, Mul, Div};//函數(shù)指針數(shù)組 int i = 0; for (i = 0; i < 4; i++) { //int ret = (*pfArr[i])(8, 4); int ret = pfArr[i](8, 4); ? printf("%dn", ret); } return 0; }?

這樣也簡化了我們的代碼

2.2、計算器實現(xiàn)2.2.1switch語句

目的:實現(xiàn)一個計算器

菜單:用數(shù)字來選擇運算類型

方法:以switch/case語句來實現(xiàn)函數(shù)調(diào)用

結(jié)束:用do/while實現(xiàn)多組輸入,以及結(jié)束程序

int Add(int x, int y) { return x + y; } int Sub(int x, int y) { return x - y; } int Mul(int x, int y) { return x * y; } int Div(int x, int y) { return x / y; } ? ? void menu() { printf("**********************************n"); printf("***** 1. add 2. sub *****n"); printf("***** 3. mul 4. div *****n"); printf("***** 0. exit *****n"); printf("**********************************n"); } ? int main() { int input = 0; int x = 0; int y = 0; int ret = 0; do { menu(); printf("請選擇:>"); scanf("%d", &input); switch (input) { case 1: printf("輸入2個操作數(shù):>"); scanf("%d %d", &x, &y); ret = Add(x, y); printf("ret = %dn", ret); break; case 2: printf("輸入2個操作數(shù):>"); scanf("%d %d", &x, &y); ret = Sub(x, y); printf("ret = %dn", ret); break; case 3: printf("輸入2個操作數(shù):>"); scanf("%d %d", &x, &y); ret = Mul(x, y); printf("ret = %dn", ret); break; case 4: printf("輸入2個操作數(shù):>"); scanf("%d %d", &x, &y); ret = Div(x, y); printf("ret = %dn", ret); break; case 0: printf("退出計算器n"); break; default: printf("選擇錯誤n"); break; } } while (input); ? return 0; }?

這種方式需要寫非常多的重復代碼,而且代碼長度很長????

我們可以使用函數(shù)指針對它進行優(yōu)化

2.2.2函數(shù)指針形式int main() { int input = 0; int x = 0; int y = 0; int ret = 0; ? int (*pfArr[5])(int, int) = {0, Add, Sub, Mul, Div}; //pfArr是一個函數(shù)指針的數(shù)組,也叫轉(zhuǎn)移表 do { menu(); printf("請選擇:>"); scanf("%d", &input); if (input == 0) { printf("退出計算器n"); break; } else if (input >= 1 && input <= 4) { printf("輸入2個操作數(shù):>"); scanf("%d %d", &x, &y); ret = pfArr[input](x, y); printf("ret = %dn", ret); } else { printf("選擇錯誤n"); } } while (input); ? return 0; }?

這樣就避免了我們在每個case語句里都寫上輸入提示、scanf和不同的函數(shù)調(diào)用所導致的代碼冗余了

運行試試吧!


 

2.3指向函數(shù)指針數(shù)組的指針

函數(shù)指針數(shù)組是一個數(shù)組,數(shù)組可以用數(shù)組指針來存放地址

指向函數(shù)指針數(shù)組的指針:是一個指針

該指針指向一個數(shù)組,數(shù)組的每個元素都是一個函數(shù)指針

int Add(int x, int y) { return x + y; } int main() { int (*pa)(int, int) = Add;//函數(shù)指針 int (* pfA[4])(int, int);//函數(shù)指針的數(shù)組 int (* (*ppfA)[4])(int, int) = &pfA; //ppfA 是一個指針,該指針指向了一個存放函數(shù)指針的數(shù)組 return 0; }3.相關(guān)練習題

定義一個函數(shù)指針,指向的函數(shù)有兩個int形參并且返回一個函數(shù)指針,返回的指針指向一個有一個int形參且返回int的函數(shù)?下面哪個是正確的?

A. int (*(*F)(int, int))(int) B. int (*F)(int, int) C. int (*(*F)(int, int)) D. *(*F)(int, int)(int)

一步步分析題目的要求

該函數(shù)指針指向的函數(shù)有兩個int類型,即(int,int),ABCD都有,無法排除

仔細看看,D的類型沒有寫全,直接排除

返回一個函數(shù)指針,該指針指向一個有一個int形參且返回int的函數(shù)

B是一個函數(shù)指針,返回類型是int,錯誤

C的返回值是int*類型,錯誤

A選項去掉函數(shù)指針F后,剩下int (*)(int),符合題意

結(jié)語

你學廢了嗎?

分享到:
標簽:語言
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數(shù)有氧達人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定