格而知之15 我所理解的Block(1)

2022-03-23 13:51:11 字數 2711 閱讀 9080

1、block 本質上是乙個struct結構體,在這個結構體中,最重要的成員是乙個函式(當然除函式外還有其他重要的成員)。

(1)、block物件的格式;

(2)、block變數的格式;

3、對於block物件,它有幾種常見的格式:

(1)、乙個完整的block物件的格式如下:

比如這個block物件:

可以發現,完整的block物件和函式的定義非常相似,比如這個函式:

兩者之間的區別僅僅是:block物件多了乙個「^」符號,並且不需要像函式一樣指定函式名;

(2)、在完整的格式中有一些專案是可以省略的,比如「返回值型別」。不管block物件是否有返回值,這個專案都是可以省略的,省略之後,只要表示式中有return語句就會自動使用該返回值的型別,如果沒有return語句就會使用void型別。

在這種情況下,block物件的格式就變成了:

所以上文(1)中的block物件可以寫成這樣:

(3)、除此之外,如果block物件不需要引數的話,那麼「引數列表」這個專案也是可以省略的,這時候block物件的格式就變成了:

比如這樣的乙個block物件:

4、定義了block物件之後,還要定義block變數來持有它,才能更方便地使用block物件。回顧一下3(1)的函式:

對於這種函式,可以宣告這樣乙個函式指標型別變數來使用它:

這時使用*funcptr的就相當於在使用func函式了。

同樣的,對於3(1)中的block物件,也可以宣告這麼乙個block變數:

這時使用block()的時候就相當於在使用這個block物件了。

對比函式指標和block變數的宣告,可以發現兩者也是非常相似的,區別僅僅是將*號換成^

5、如果要將block變數當做引數來傳遞的話,每次使用都完整地定義它顯然是很麻煩的事。比如想要在乙個函式裡使用block變數型別的引數,完整的定義方式應該是這樣的:

這顯然是很繁瑣的,這時候就可以通過typedef來簡化變數:

那麼這個函式就可以定義成:

這時就可以非常方便地使用block變數了。

6、回顧完block 相關的格式,接下來開始來討論block的實現。

在前文提到過,block最重要的組成部分是乙個函式,這也就意味著,大部分block能實現的功能,其實使用函式也可以實現的。接下來就先來試一試要如何在不使用block的情況下實現block的功能。

思考這麼乙個問題:假設有兩個按鈕button1和button2,要求實現以下功能:

(1)、按鈕有編號;

(2)、編號可修改;

(3)、點選按鈕輸出自己的編號。

7、首先簡單的方法可以通過使用兩個函式來實現:

兩個函式分別對應兩個按鈕的點選,呼叫函式時把按鈕的編號作為引數傳進去,便能列印出對應編號。

看起來似乎能滿足功能了,但是這種方法的問題也是很明顯的:按鈕並不持有自己的編號,需要呼叫函式的時候才將編號傳進去。

這種方法顯然還不夠完善。

8、根據物件導向的思考方式,通過將按鈕抽象成類並把編號定義成按鈕類的例項變數是可以實現這個功能的。但是這裡只想要使用普通c語言來實現,那麼可以這麼處理,把每個按鈕的編號定義成全域性變數來進行儲存,修改的**如下:

這樣按鈕就「持有」了編號,實現了問題的3個要求。

9、回過頭來看一看問題,如果要使用block來實現這3個要求的話,**會是這樣的:

這段**所實現的功能,和8的**所實現的功能其實就是一樣的了。

10、事實上,這兩段**幾乎就是等價的了,8的**幾乎就是9的**轉換成普通c語言後的樣子(注意「幾乎」這個字眼,實際上5的**轉換成普通c語言後與4的**還是有不少差別的)。

而對於問題中所提的3個要求,其實就是block的3個主要功能點:

(1)、能截獲變數;

(2)、能截獲可變的變數;

(3)、**。

遞迴之我所理解

遞迴在實際程式設計中有著很重要的用處,最常見的用途莫過於檔案搜尋目錄遍歷了,我曾花了很長時間研究遞迴的性質,發現所有遞迴都可以用樹的結構描述出來,這只是我的發現,並沒有嚴格的證明,至少在我所研究過的所有遞迴應用例項中是成立的。遞迴的效率顯然不是很高,因為每次遞迴的時候,呼叫函式時得分配棧空間,函式返...

我所理解的前端

轉眼間,在鵝廠的實習已經過去三個多月,涉及到實習生轉正留用的考核流程也逐步開始了。帶著一堆疑問,以及自己實習期間的心得體會,與導師暢談了一番。他作為資深前端工程師,就前端領域及我個人未來的職業規劃等方面分享了他自己的經驗。這次與導師的溝通讓我受益匪淺,現簡單總結如下。前端知識學習路線 首先,當然是就...

我所理解的陣列

陣列 一 一維陣列 1 陣列的建立 陣列顧名思義是含有相同元素的集合,類似我們高中數學所學習的集合 例如int arr 10 char arr1 2 float arr2 3 double arr3 5 注意 切記 這個中要給常量,不能使用變數。2 陣列的初始化 初始化是指 在陣列的建立同時並賦予合...