摘要:回調(diào)函數(shù)不是由該函數(shù)的實(shí)現(xiàn)方直接調(diào)用,而是在特定的事件或條件發(fā)生時(shí)由另外的一方調(diào)用的,用于對(duì)該事件或條件進(jìn)行響應(yīng)。
上次我們學(xué)習(xí)了指針的相關(guān)知識(shí),那么今天就讓我們進(jìn)一步的深入去學(xué)習(xí)指針吧!
沒有看過上一篇關(guān)于與指針的相關(guān)知識(shí)是小伙伴可以點(diǎn)擊下面的鏈接跳轉(zhuǎn)哦~
不知道小伙伴們有沒有在查詢函數(shù)的時(shí)候,看到函數(shù)的形參列表或者返回類型中,出現(xiàn)了void* 這種類型?
例如:
void qsort (void* base, size_t num, size_t size, int (*compar)(const void*,const void*));
上面最后面就出現(xiàn)了void*,那么這個(gè)是什么呢?
這個(gè)不是空指針!
空指針的表示方法為:NULL
這種類型叫做無(wú)類型指針!
無(wú)類型指針意思就是沒有具體類型的指針,也就是說(shuō),你在函數(shù)傳參的時(shí)候,傳入什么指針類型都可以。
這種指針類型并不能直接對(duì)其進(jìn)行解引用和運(yùn)算,需要強(qiáng)制類型轉(zhuǎn)化為具體類型的指針才可以!
int main() { void* p;//定義了一個(gè)無(wú)類型指針變量p int n = 10; p = &n;//把整型變量n的地址賦值給p //printf("%d/n", *p);//這是錯(cuò)誤的用法! //我們需要在解引用前把p強(qiáng)制類型轉(zhuǎn)化為int*類型才可以進(jìn)引用! printf("%d/n", *(int*)p); return 0;}
在C語(yǔ)言中,除了內(nèi)置的數(shù)據(jù)類型,我們還可以自定義數(shù)據(jù)類型。
結(jié)構(gòu)體就是自定義類型的典型代表!下面就讓我們一起來(lái)學(xué)習(xí)結(jié)構(gòu)體的指針吧!
代碼演示如下:
#include //簡(jiǎn)單的定義了一個(gè)結(jié)構(gòu)體類型struct Book { char name[20]; double price;};int main() { //用定義的結(jié)構(gòu)體類型創(chuàng)建了一個(gè)變量book,并初始化 struct Book book = { "sanguoyanyi",25.5 }; //定義了一個(gè)結(jié)構(gòu)體的指針變量,并把book的地址賦值給該結(jié)構(gòu)體指針變量 struct Book* p = &book; //利用指針找到結(jié)構(gòu)體變量 printf("%s/n", (*p).name); printf("%.2lf/n", p->price); return 0;}
上面演示了結(jié)構(gòu)體指針變量的基本使用方式,關(guān)于結(jié)構(gòu)體的相關(guān)知識(shí),我們?cè)谶@里就不展開啦,以后我們?cè)谌チ私饨Y(jié)構(gòu)體。
我們還演示了結(jié)構(gòu)體指針變量的兩種用法
- 解引用后再找到成員變量
- 直接指向成員變量
關(guān)于結(jié)構(gòu)體指針變量的用法,有一個(gè)特別重要的應(yīng)用場(chǎng)景哦~
那就是再調(diào)用函數(shù)需要再傳參時(shí)傳入結(jié)構(gòu)體變量的話,我們一般采用的是傳入結(jié)構(gòu)體變量的地址哦!
在C語(yǔ)言中,自定義類型除了結(jié)構(gòu)體還有枚舉。
枚舉類型也有屬于自己的指針哦。
看下面代碼演示:
#include //定義了一個(gè)枚舉類型enum Day//星期{ Mon, Tues, Wed, Thur, Fri, Sat, Sun};int main() { //創(chuàng)建了一個(gè)枚舉變量 enum Day day = Mon; //創(chuàng)建了一個(gè)枚舉類型的指針 enum Day* p; //把枚舉變量的地址復(fù)制給枚舉類型的指針 p = &day; printf("%d/n", *p); return 0;}
上面的代碼就演示了枚舉類型的指針,但是由于我知識(shí)儲(chǔ)備不夠,沒有想到有什么應(yīng)用場(chǎng)景,如果知道該如何使用的小伙伴可以在評(píng)論區(qū)告訴我哦~
不僅僅是變量擁有屬于自己的地址,就連函數(shù)也有地址哦!
我們先看一看下面的代碼演示:
#include void test(){printf("hehe/n");}int main(){printf("%p/n", test);printf("%p/n", &test);return 0;}
運(yùn)行上面的代碼,我們會(huì)發(fā)現(xiàn)打印出來(lái)的兩個(gè)值是一樣的。
這也就說(shuō)明
函數(shù)也有地址,而且函數(shù)名就代表著函數(shù)本身的地址!
我們?cè)撛趺礃觿?chuàng)建函數(shù)的指針變量呢?
void test(){printf("hehe/n");}//下面pfun1和pfun2哪個(gè)有能力存放test函數(shù)的地址?void (*pfun1)();void *pfun2();
上面的代碼中,pfun1是指針變量,因?yàn)樗雀?結(jié)合,說(shuō)明該變量是一個(gè)指針變量,前面的void說(shuō)明了它指向的函數(shù)的返回類型為空,后面的(),表示這個(gè)它指向的函數(shù)的形參也為空
再看下面的栗子
我們?cè)賮?lái)看一個(gè)栗子:
#include //簡(jiǎn)單定義了一個(gè)加法函數(shù)int Add(int x, int y) { return x + y;}int main() { //創(chuàng)建了兩個(gè)指針變量 int (*pfun1)(int, int); int (*pfun2)(int x, int y); //給兩個(gè)指針變量賦值 pfun1 = &Add; pfun2 = Add; //通過指針去調(diào)用函數(shù),并打印返回值 printf("%d/n", (*pfun1)(3, 4)); printf("%d/n", pfun2(6, 7)); return 0;}
通過上面的栗子我們可以知道
- 創(chuàng)建函數(shù)指針變量時(shí),后面形參列表的形參變量符號(hào)可以省略
- 給指針變量賦值的時(shí)候,函數(shù)名和&函數(shù)名的實(shí)際效果都一樣
- 函數(shù)指針調(diào)用函數(shù)的時(shí)候可以解引用,也可以直接通過指針變量名來(lái)調(diào)用函數(shù)
通過函數(shù)指針,我們就可以用來(lái)調(diào)用函數(shù)了。
回調(diào)函數(shù)就是一個(gè)通過函數(shù)指針調(diào)用的函數(shù)。
如果你把函數(shù)的指針(地址)作為參數(shù)傳遞給另一個(gè)函數(shù),當(dāng)這個(gè)指針被用來(lái)調(diào)用其所指向的函數(shù)時(shí),我們就說(shuō)這是回調(diào)函數(shù)。
回調(diào)函數(shù)不是由該函數(shù)的實(shí)現(xiàn)方直接調(diào)用,而是在特定的事件或條件發(fā)生時(shí)由另外的一方調(diào)用的,用于對(duì)該事件或條件進(jìn)行響應(yīng)。
其中,庫(kù)函數(shù)qsort的形參列表,就是使用了回調(diào)函數(shù)的方法哦!
有興趣的小伙伴也可以自己去研究一下這個(gè)庫(kù)函數(shù),有時(shí)間的話,我也會(huì)分享一篇關(guān)于qsort函數(shù)的使用的博客哦~
同樣的,數(shù)組也有自己的地址,用來(lái)存放數(shù)組的地址的指針,就是數(shù)組指針啦~
int main(){ //定義了一個(gè)整型數(shù)組 int arr[10] = { 0 }; //定義了一個(gè)整數(shù)數(shù)組的指針 int(*p)[10]; //給整型數(shù)組的指針賦值 p = &arr; return 0;}
栗子如下:
int *arr[10];//數(shù)組的每個(gè)元素是int*
那要把函數(shù)的地址存到一個(gè)數(shù)組中,那這個(gè)數(shù)組就叫函數(shù)指針數(shù)組,那函數(shù)指針的數(shù)組如何定義呢?
int (*parr1[10])();int *parr2[10]();int (*)() parr3[10];
大家覺得哪個(gè)才是正確的指針數(shù)組的創(chuàng)建呢?
答案是:parr1
parr1 先和 [] 結(jié)合,說(shuō)明parr1是數(shù)組,數(shù)組的內(nèi)容是什么呢?
是 int (*)() 類型的函數(shù)指針。
今天的內(nèi)容到這里就要結(jié)束啦!
由于今天的內(nèi)容難度比較大,而且本人的水平有限,難免會(huì)有出錯(cuò)的地方,如果有錯(cuò)的地方,還請(qǐng)小伙伴們?cè)僭u(píng)論區(qū)提出哦~
讓我們一起學(xué)習(xí),一起進(jìn)步吧!
創(chuàng)作不易呀,希望小伙伴們可以動(dòng)動(dòng)小手,給我一個(gè)關(guān)注、一個(gè)贊還有評(píng)論哦~
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/122194.html
摘要:當(dāng)集合為空時(shí),稱該二叉樹為空二叉樹。也就是說(shuō),如果一個(gè)二叉樹的層數(shù)為,且結(jié)點(diǎn)總數(shù)是,則它就是滿二叉樹。完全二叉樹完全二叉樹是效率很高的數(shù)據(jù)結(jié)構(gòu),完全二叉樹是由滿二叉樹而引出來(lái)的。 ...
閱讀 3573·2021-10-11 10:59
閱讀 1591·2021-09-29 09:35
閱讀 2259·2021-09-26 09:46
閱讀 3771·2021-09-10 10:50
閱讀 952·2019-08-29 12:17
閱讀 821·2019-08-26 13:40
閱讀 2433·2019-08-26 11:44
閱讀 2103·2019-08-26 11:22