0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

周立功教你學(xué)程序設(shè)計技術(shù):做好軟件模塊的分層設(shè)計,回調(diào)函數(shù)要這樣寫

AGk5_ZLG_zhiyua ? 來源:未知 ? 作者:電子大兵 ? 2017-08-30 10:24 ? 次閱讀

第二章為程序設(shè)計技術(shù),本文為2.1.3 回調(diào)函數(shù)。

>>>>2.1.3 回調(diào)函數(shù)

>>>1.分層設(shè)計

分層設(shè)計就是將軟件分成具有某種上下級關(guān)系的模塊,由于每一層都是相對獨立的,因此只要定義好層與層之間的接口,從而每層都可以單獨實現(xiàn)。比如,設(shè)計一個保險箱電子密碼鎖,其硬件部分大致包括鍵盤、顯示器、蜂鳴器、鎖與存儲器等驅(qū)動電路,因此根據(jù)需求將軟件劃分為硬件驅(qū)動層、虛擬層與應(yīng)用層三大模塊,當(dāng)然每個大模塊又可以劃分為幾個小模塊,下面將以鍵盤掃描為例予以說明。

(1)硬件驅(qū)動層

硬件驅(qū)動層處于模塊的最底層,直接與硬件打交道。其任務(wù)是識別哪個鍵按下了,實現(xiàn)與硬件電路緊密相關(guān)的部分軟件,更高級的功能將在其它層實現(xiàn)。雖然通過硬件驅(qū)動層可以直達(dá)應(yīng)用層,由于硬件電路變化多樣,如果應(yīng)用層直接操作硬件驅(qū)動層,則應(yīng)用層勢必依賴于硬件層,則最好的方法是增加一個虛擬層應(yīng)對硬件的變化。顯然,只要鍵盤掃描的方法不變,則產(chǎn)生的鍵值始終保持不變,那么虛擬層的軟件也永遠(yuǎn)不會改變。

(2)虛擬層

它是依據(jù)應(yīng)用層的需求劃分的,主要用于屏蔽對象的細(xì)節(jié)和變化,則應(yīng)用層就可以用統(tǒng)一的方法來實現(xiàn)了。即便控制方法改變了,也無需重新編寫應(yīng)用層的代碼。

(3)應(yīng)用層

應(yīng)用層處于模塊的最上層,直接用于功能的實現(xiàn),比如,應(yīng)用層對外只有一個“人機(jī)交互”模塊,當(dāng)然內(nèi)部還可以劃分幾個模塊供自己使用。三層之間數(shù)據(jù)傳遞的關(guān)系非常清晰,即應(yīng)用層->虛擬層->硬件驅(qū)動層,詳見圖 2.2,圖中的實線代表依賴關(guān)系,即應(yīng)用層依賴于虛擬層,虛擬層依賴于硬件驅(qū)動層?;诜謱拥募軜?gòu)具有以下優(yōu)點:

  • 降低系統(tǒng)的復(fù)雜度:由于每層都是相對獨立的,層與層之間通過定義良好接口交互,每層都可以單獨實現(xiàn),從而降低了模塊之間的耦合度;

  • 隔離變化:軟件的變化通常發(fā)生在最上層與最下層,最上層是圖形用戶界面,需求的變化通常直接影響用戶界面,大部分軟件的新老版本在用戶界面上都會有很大差異。最下層是硬件,硬件的變化比軟件的發(fā)展更快,通過分層設(shè)計可以將這些變化的部分獨立開來,讓它們的變化不會給其它部分帶來大的影響;

  • 有利于自動測試:由于每一層具有獨立的功能,則更易于編寫測試用例;

  • 有利于提高程序的可移植性:通過分層設(shè)計將各種平臺不同的部分放在獨立的層里。比如,下層模塊是對操作系統(tǒng)提供的接口進(jìn)行包裝的包裝層,上層是針對不同平臺所實現(xiàn)的圖形用戶界面。當(dāng)移植到不同的平臺時,只需要實現(xiàn)不同的部分,而中間層都可以重用。

圖 2.2 三層結(jié)構(gòu)示意

應(yīng)用層處于模塊的最上層,直接用于功能的實現(xiàn),比如,應(yīng)用層對外只有一個“人機(jī)交互”模塊,當(dāng)然內(nèi)部還可以劃分幾個模塊供自己使用。三層之間數(shù)據(jù)傳遞的關(guān)系非常清晰,即應(yīng)用層->虛擬層->硬件驅(qū)動層,詳見圖 2.2,圖中的實線代表依賴關(guān)系,即應(yīng)用層依賴于虛擬層,虛擬層依賴于硬件驅(qū)動層?;诜謱拥募軜?gòu)具有以下優(yōu)點:

  • 降低系統(tǒng)的復(fù)雜度:由于每層都是相對獨立的,層與層之間通過定義良好接口交互,每層都可以單獨實現(xiàn),從而降低了模塊之間的耦合度;

  • 隔離變化:軟件的變化通常發(fā)生在最上層與最下層,最上層是圖形用戶界面,需求的變化通常直接影響用戶界面,大部分軟件的新老版本在用戶界面上都會有很大差異。最下層是硬件,硬件的變化比軟件的發(fā)展更快,通過分層設(shè)計可以將這些變化的部分獨立開來,讓它們的變化不會給其它部分帶來大的影響;

  • 有利于自動測試:由于每一層具有獨立的功能,則更易于編寫測試用例;

  • 有利于提高程序的可移植性:通過分層設(shè)計將各種平臺不同的部分放在獨立的層里。比如,下層模塊是對操作系統(tǒng)提供的接口進(jìn)行包裝的包裝層,上層是針對不同平臺所實現(xiàn)的圖形用戶界面。當(dāng)移植到不同的平臺時,只需要實現(xiàn)不同的部分,而中間層都可以重用。

>>>2.隔離變化

(1)好萊塢原則(Hollywood)

類似鍵盤掃描這樣的模塊,其共性是各層之間的調(diào)用關(guān)系,不可能隨著時間而改變,即便上下層之間形成依賴關(guān)系,采用直接調(diào)用方式是最簡單的。為了降低層與層之間的耦合,層與層之間的通信必須按照一定的規(guī)則進(jìn)行。即上層可以直接調(diào)用下層提供的函數(shù),但下層不能直接調(diào)用上層提供的函數(shù),且層與層之間絕對不能循環(huán)調(diào)用。因為層與層之間的循環(huán)依賴會嚴(yán)重妨礙軟件的復(fù)用性和可擴(kuò)展性,使得系統(tǒng)中的每一層都無法獨立構(gòu)成一個可復(fù)用的組件。雖然上層也可以調(diào)用相鄰下層提供的函數(shù),但不能跨層調(diào)用。即下層模塊實現(xiàn)了在上層模塊中聲明并被高層模塊調(diào)用的接口,這就是著名的好萊塢(Hollywood)擴(kuò)展原則:“不要調(diào)用我,讓我調(diào)用你。”當(dāng)下層需要傳遞數(shù)據(jù)給上層時,則采用回調(diào)函數(shù)指針接口隔離變化。通過倒置依賴的接口所有權(quán),創(chuàng)建了一個更靈活、更持久和更易于修改的結(jié)構(gòu)。

實際上,由上層模塊(即調(diào)用者)提供的回調(diào)函數(shù)的表現(xiàn)形式就是在下層模塊中通過函數(shù)指針調(diào)用另一個函數(shù),即將回調(diào)函數(shù)的地址作為實參初始化下層模塊的形參,由下層模塊在某個時刻調(diào)用這個函數(shù),這個函數(shù)就是回調(diào)函數(shù),詳見圖 2.3。其調(diào)用方式有兩種:

  • 在上層模塊A調(diào)用下層模塊B的函數(shù)中,直接調(diào)用回調(diào)函數(shù)C;

  • 使用注冊的方式,當(dāng)某個事件發(fā)生時,下層模塊調(diào)用回調(diào)函數(shù)。

圖 2.3 回調(diào)函數(shù)的使用

在初始化時,上層模塊A將回調(diào)函數(shù)C的地址作為實參傳遞給下層模塊B。在運行中,當(dāng)下層模塊需要與上層模塊通信時,調(diào)用這個回調(diào)函數(shù)。其調(diào)用方式為A→B→C,上層模塊A調(diào)用下層模塊B,在B的執(zhí)行過程中,調(diào)用回調(diào)函數(shù)將信息返回給上層模塊。對于上層模塊來說,C不僅監(jiān)視B的運行狀態(tài),而且干預(yù)B的運行,其本質(zhì)上依然是上層模塊調(diào)用下層模塊。由于增加了回調(diào)函數(shù),即可在運行中實現(xiàn)動態(tài)綁定,下面將以標(biāo)準(zhǔn)的冒泡排序函數(shù)對一個任意類型的數(shù)據(jù)進(jìn)行排序為例予以說明。

(2)數(shù)據(jù)比較函數(shù)

假設(shè)待排序的數(shù)據(jù)為int型,即可通過比較相鄰數(shù)據(jù)的大小,做出是否交換數(shù)據(jù)的處理。當(dāng)給定兩個指向int型變量的指針e1和e2時,則比較函數(shù)返回一個數(shù)。如果*e1小于*e2,那么返回的數(shù)為負(fù)數(shù);如果*e1大于*e2,那么返回的數(shù)為正數(shù);如果*e1等于*e2,那么返回的數(shù)為0,詳見程序清單 2.4。

程序清單2.4 compare_int()數(shù)據(jù)比較函數(shù)

1 int compare_int(const int *e1, const int *e2)

2 {

3 return *e1 - *e2;//升序比較

4 }

5

6 int compare_int(const int *e1, const int *e2)

7 {

8 return *e2 - *e1; //降序比較

9 }

由于任何數(shù)據(jù)類型的指針都可以給void*指針賦值,因此可以利用這一特性,將void*指針作為數(shù)據(jù)比較函數(shù)的形參。當(dāng)函數(shù)的形參聲明為void *類型時,雖然bubbleSort()冒泡排序函數(shù)內(nèi)部不知道調(diào)用者會傳遞什么類型的數(shù)據(jù)過來,但調(diào)用者知道數(shù)據(jù)的類型和對數(shù)據(jù)的操作方法,那就由調(diào)用者編寫數(shù)據(jù)比較函數(shù)。

由于在運行時調(diào)用者要根據(jù)實際情況才能決定調(diào)用哪個數(shù)據(jù)比較函數(shù),因此根據(jù)比較操作的要求,其函數(shù)原型如下:

typedef int (*COMPARE)(const void *e1, const void *e2);

其中的e1、e2是指向2個需要進(jìn)行比較的值的指針。當(dāng)返回值< 0時,表示e1 < e2;當(dāng)返回值= 0時,表示e1 = e2;當(dāng)返回值> 0時,表示e1 > e2。

當(dāng)用typedef聲明后,COMPARE就成了函數(shù)指針類型,有了類型就可以定義該類型的函數(shù)指針變量。比如:

COMPARE compare;

此時,只要將函數(shù)名(比如,compare_int)作為實參初始化函數(shù)的形參,即可調(diào)用相應(yīng)的數(shù)據(jù)比較函數(shù)。比如:

COMPARE compare=compare_int;

雖然編譯器看到的是一個compare,但調(diào)用者實現(xiàn)了多種不同類型的compare,即可根據(jù)接口函數(shù)中的類型改變函數(shù)的行為方式,通用數(shù)據(jù)比較函數(shù)的實現(xiàn)詳見程序清單 2.5。

程序清單 2.5 compare數(shù)據(jù)比較函數(shù)的實現(xiàn)

1 int compare_int(const void *e1, const void *e2)

2 {

3 return (*((int *)e1) - *((int *)e2)); //升序比較

4 }

5

6 int compare_int_invert(const void *e1, const void *e2)

7 {

8 return *(int *)e2 - *(int *)e1; //降序比較

9 }

10

11 int compare_vstrcmp(const void *e1, const void *e2)

12 {

13 return strcmp(*(char**)e1, *(char**)e2); //字符串比較

14 }

注意,如果e1是很大的正數(shù),而e2是大負(fù)數(shù),或者相反,則計算結(jié)果可能會溢出。由于這里假設(shè)它們都是正整數(shù),從而避免了風(fēng)險。

由于該函數(shù)的參數(shù)聲明為void *類型,因此數(shù)據(jù)比較函數(shù)不再依賴于具體的數(shù)據(jù)類型。即可將算法的變化部分獨立出來,無論是升序還是降序或字符串比較完全取決于回調(diào)函數(shù)。注意,之所以不能直接用strcmp()作為字符串的比較,因為bubbleSort()傳遞的是類型為char **的數(shù)組元素的地址&array[i],而不是類型為char*的array[i]。

(3)bubbleSort()冒泡排序函數(shù)

標(biāo)準(zhǔn)函數(shù)bubbleSort()是C中使用函數(shù)指針的經(jīng)典示例,該函數(shù)是對一個具有任意類型的數(shù)組進(jìn)行排序,其中單個元素的大小和要比較的元素的函數(shù)都是給定的。其原型初定如下:

bubbleSort(參數(shù)列表);

既然bubbleSort()是對數(shù)組中的數(shù)據(jù)排序,那么bubbleSort()必須有一個參數(shù)保存數(shù)組的起始地址,且還有一個參數(shù)保存數(shù)組中元素的個數(shù)。為了通用還是在數(shù)組中存放void *類型的元素,這樣一來就可以用數(shù)組存儲用戶傳入的任意類型的數(shù)據(jù),因此用void *類型參數(shù)保存數(shù)組的起始地址。其函數(shù)原型如下:

bubbleSort(void *base, size_t nmemb);

由于數(shù)組的類型是未知的,那么數(shù)組中元素的長度也是未知的,同樣也需要一個參數(shù)來保存。其函數(shù)原型進(jìn)化為:

bubbleSort(void *base, size_t nmemb, size_t size);

其中,size_t是C標(biāo)準(zhǔn)庫中預(yù)定義的類型,專門用于保存變量的大小。參數(shù)base和nmemb標(biāo)識了這個數(shù)組,分別用于保存數(shù)組的起始地址和數(shù)組中元素的個數(shù),size存儲的是打包時單個元素的大小。

此時,如果將指向compare()的指針作為參數(shù)傳遞給bubbleSort(),即可“回調(diào)”compare()進(jìn)行值的比較。由于排序是對數(shù)據(jù)的操作,因此bubbleSort()沒有返回值,其類型為void,bubbleSort()函數(shù)接口詳見程序清單 2.6。

程序清單2.6bubbleSort()冒泡排序函數(shù)接口(bubbleSort.h)

1 #pragma once;

2 void bubbleSort(void *base, size_t nmemb, size_t size, COMPARE compare);

雖然大多數(shù)初學(xué)者也會選擇回調(diào)函數(shù),但又經(jīng)常用全局變量保存中間數(shù)據(jù)。這里提出的解決方法就是給回調(diào)函數(shù)傳遞一個稱為“回調(diào)函數(shù)上下文”的參數(shù),其變量名為base。為了能接受任何數(shù)據(jù)類型,選擇void *表示這個上下文?!吧舷挛摹钡囊馑季褪钦f,如果傳進(jìn)來的是int類型值,則回調(diào)int型數(shù)據(jù)比較函數(shù);如果傳進(jìn)來的是字符串,則回調(diào)字符串比較函數(shù)。

當(dāng)bubbleSort()將base聲明為一個void *類型時,即允許bubbleSort()用相同的代碼支持不同類型的數(shù)據(jù)比較實現(xiàn)排序,其關(guān)鍵之處是type類型域,它允許在運行時根據(jù)數(shù)據(jù)的類型調(diào)用不同的函數(shù)。這種在運行時根據(jù)數(shù)據(jù)的類型將函數(shù)體與函數(shù)調(diào)用相關(guān)聯(lián)的行為稱為動態(tài)綁定,因此將一個函數(shù)的綁定發(fā)生在運行時而非編譯期,就稱該函數(shù)是多態(tài)的。顯然,多態(tài)是一種運行時綁定機(jī)制,其目的是將函數(shù)名綁定到函數(shù)的實現(xiàn)代碼。一個函數(shù)的名字與其入口地址是緊密相連的,入口地址是該函數(shù)在內(nèi)存中的起始地址,因此多態(tài)就是將函數(shù)名動態(tài)地綁定到函數(shù)入口地址的運行時綁定機(jī)制,bubbleSort()的接口與實現(xiàn)詳見程序清單 2.7和程序清單 2.8。

程序清單2.7bubbleSort()接口(bubbleSort.h)

1 #pragma once

2 #include

3

4 typedef int(*COMPARE)(const void * e1, const void *e2);

5 void bubbleSort(void * base, size_t nmemb, size_t size, COMPARE compare);

程序清單2.8bubbleSort()接口的實現(xiàn)(bubbleSort.c)

1 #include"bubbleSort.h"

2

3 void byte_swap(void *pData1, void *pData2, size_t stSize)

4 {

5 unsigned char *pcData1 = pData1;

6 unsigned char *pcData2 = pData2;

7 unsigned char ucTemp;

8

9 while (stSize--){

10 ucTemp = *pcData1; *pcData1 = *pcData2; *pcData2 = ucTemp;

11 pcData1++; pcData2++;

12 }

13 }

14

15 void bubbleSort(void * base, size_t nmemb, size_t size, COMPARE compare)

16 {

17 int hasSwap=1;

18

19 for (size_t i = 1; hasSwap&&i < nmemb; i++) {

20 hasSwap = 0;

21 for (size_t j = 0; j < numData - 1; j++) {

22 void *pThis = ((unsigned char *)base) + size*j;

23 void *pNext = ((unsigned char *)base) + size*(j+1);

24 if (compare(pThis, pNext) > 0) {

25 hasSwap = 1;

26 byte_swap(pThis, pNext, size);

27 }

28 }

29 }

30 }

靜態(tài)類型和動態(tài)類型

類型的靜態(tài)和動態(tài)指的是名字與類型綁定的時間,如果所有的變量和表達(dá)式的類型在編譯時就固定了,則稱之為靜態(tài)綁定;如果所有的變量和表達(dá)式的類型直到運行時才知道,則稱之為動態(tài)綁定。

假設(shè)要實現(xiàn)一個用于任意數(shù)據(jù)類型的冒泡排序函數(shù)并簡單測試,其要求是同一個函數(shù)既可以從大到小排列,也可以從小到大排列,且同時支持多種數(shù)據(jù)類型。比如:

int array[] = {39, 33, 18, 64, 73, 30, 49, 51, 81};

顯然,只要將比較函數(shù)的入口地址compare_int傳遞給compare,即可調(diào)用bubbleSort():

int array[] = {39, 33, 18, 64, 73, 30, 49, 51, 81};

bubbleSort(array, numArray , sizeof(array[0]), compare_int);

在數(shù)量不大時,所有排序算法性能差別不大,因為高級算法只有在元素個數(shù)多于1000時,性能才出現(xiàn)顯著提升。其實90%以上的情況下,我們存儲的元素個數(shù)只有幾十到幾百個,冒泡排序可能是更好的選擇,bubbleSort()的實現(xiàn)與使用范例程序詳見程序清單 2.9。

程序清單 2.9 bubbleSort()冒泡排序范例程序

1 #include

2 #include

3 #include"bubbleSort.h"

4

5 int compare_int(const void * e1, const void * e2)

6 {

7 return *(int *)e1 - *(int *)e2;

8 }

9

10 int compare_int_r(const void * e1, const void * e2)

11 {

12 return *(int *)e2 - *(int *)e1 ;

13 }

14

15 int compare_str(const void * e1, const void *e2)

16 {

17 return strcmp(*(char **)e1, *(char **)e2);

18 }

19

20 void main()

21 {

22 int arrayInt[] = { 39, 33, 18, 64, 73, 30, 49, 51, 81 };

23 int numArray = sizeof(arrayInt) / sizeof(arrayInt[0]);

24 bubbleSort(arrayInt, numArray, sizeof(arrayInt[0]), compare_int);

25 for (int i = 0; i

26 printf("%d ", arrayInt[i]);

27 }

28 printf("\n");

29

30 bubbleSort(arrayInt, numArray, sizeof(arrayInt[0]), compare_int_r);

31 for (int i = 0; i

32 printf("%d ", arrayInt[i]);

33 }

34 printf("\n");

35

36 char * arrayStr[] = { "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday" };

37 numArray = sizeof(arrayStr) / sizeof(arrayStr[0]);

38 bubbleSort(arrayStr, numArray, sizeof(arrayStr[0]), compare_str);

39 for (int i = 0; i < numArray; i++) {?

40 printf("%s\n", arrayStr[i]);

41 }

42 }

由此可見,調(diào)用者main()與compare_int()回調(diào)函數(shù)都同屬于上層模塊,bubbleSort()屬于下層模塊。當(dāng)上層模塊調(diào)用下層模塊bubbleSort()時,將回調(diào)函數(shù)的地址compare_int作為參數(shù)傳遞給bubbleSort(),進(jìn)而調(diào)用compare_int()。顯然,使用參數(shù)傳遞回調(diào)函數(shù)的方式,下層模塊不必知道需要調(diào)用上層模塊的哪個函數(shù),從而減少了上下層之間的聯(lián)系,這樣上下層可以獨立修改,而不影響另一層代碼的實現(xiàn)。這樣一來,在每次調(diào)用bubbleSort()時,只要給出不同的函數(shù)名作為實參,則bubbleSort()不必做任何修改。

使用回調(diào)函數(shù)的最大優(yōu)點就是便于軟件模塊的分層設(shè)計,降低軟件模塊之間的耦合度。即回調(diào)函數(shù)可以將調(diào)用者與被調(diào)用者隔離,調(diào)用者無需關(guān)心誰是被調(diào)用者。當(dāng)特定的事件或條件發(fā)生時,調(diào)用者將使用函數(shù)指針調(diào)用回調(diào)函數(shù)對事件進(jìn)行處理。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴

原文標(biāo)題:周立功:做好軟件模塊的分層設(shè)計必須掌握的回調(diào)函數(shù)

文章出處:【微信號:ZLG_zhiyuan,微信公眾號:ZLG致遠(yuǎn)電子】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    程序設(shè)計與數(shù)據(jù)結(jié)構(gòu)》立功數(shù)十年心血力作

    為了將實際開發(fā)過程中總結(jié)的有價值的技術(shù)應(yīng)用分享給大家,立功及其團(tuán)隊整理出《程序設(shè)計與數(shù)據(jù)結(jié)構(gòu)》這本書,其內(nèi)容如同培訓(xùn)講師的教案,是
    發(fā)表于 05-26 10:06 ?29次閱讀

    立功程序設(shè)計與數(shù)據(jù)結(jié)構(gòu)”:深度解剖動態(tài)分布內(nèi)存的free()函數(shù)與realloc()函數(shù)

    立功教授數(shù)年之心血之作《程序設(shè)計與數(shù)據(jù)結(jié)構(gòu)》,書本內(nèi)容公開后,在電子行業(yè)掀起一片學(xué)習(xí)熱潮。
    的頭像 發(fā)表于 08-25 14:22 ?1.5w次閱讀

    立功教你學(xué)C語言編程與程序設(shè)計這樣函數(shù)指針數(shù)組最好用

    立功教授數(shù)年之心血之作《程序設(shè)計與數(shù)據(jù)結(jié)構(gòu)》以及《面向AMetal框架與接口的編程(上)》,電子版已無償性分享到電子工程師與高校群體,在公眾號回復(fù)【編程】即可在線閱讀。
    的頭像 發(fā)表于 08-31 14:06 ?6793次閱讀
    <b class='flag-5'>周</b><b class='flag-5'>立功</b><b class='flag-5'>教你</b><b class='flag-5'>學(xué)</b>C語言編程與<b class='flag-5'>程序設(shè)計</b>:<b class='flag-5'>這樣</b><b class='flag-5'>寫</b><b class='flag-5'>函數(shù)</b>指針數(shù)組最好用

    算法的泛化問題,這些坑你可能都經(jīng)歷過!|立功教你學(xué)軟件設(shè)計

    立功教授數(shù)年之心血之作《程序設(shè)計與數(shù)據(jù)結(jié)構(gòu)》,電子版已無償性分享到電子工程師與高校群體,在公眾號回復(fù)【程序設(shè)計】即可在線閱讀。書本內(nèi)容公開后,在電子行業(yè)掀起一片學(xué)習(xí)熱潮。經(jīng)
    的頭像 發(fā)表于 09-01 09:18 ?6093次閱讀

    μCOS-II程序設(shè)計基礎(chǔ) 立功公司編著

    μCOS-II程序設(shè)計基礎(chǔ)立功公司編著
    發(fā)表于 08-20 13:41

    新書創(chuàng)作談:立功教授數(shù)十年之心血力作《程序設(shè)計與數(shù)據(jù)結(jié)構(gòu)》

    ` 近日,立功教授公開了數(shù)十年之心血力作《程序設(shè)計與數(shù)據(jù)結(jié)構(gòu)》,此書在4月28日落筆,電子版已無償性分享到電子工程師與高校群體,在致遠(yuǎn)電子公眾號后臺回復(fù)關(guān)鍵字【程序設(shè)計】可在線閱讀。
    發(fā)表于 05-15 18:04

    【完整資料】《程序設(shè)計與數(shù)據(jù)結(jié)構(gòu)》立功數(shù)十年心血力作

    ,如何有效提高技術(shù)人員軟技能,避免蠻力開發(fā)現(xiàn)象,甚至成為一位閱讀程序者。為了將實際開發(fā)過程中總結(jié)的有價值的技術(shù)應(yīng)用分享給大家,立功及其團(tuán)隊
    發(fā)表于 05-16 16:43

    調(diào)函數(shù)程序開發(fā)中有何作用呢

    調(diào)函數(shù)程序開發(fā)中是一個非常重要的概念,所謂的調(diào)其實就是不同
    發(fā)表于 03-01 07:13

    μCOS-II程序設(shè)計基礎(chǔ)_立功公司編著

    μCOS-II程序設(shè)計基礎(chǔ) 立功公司編著
    發(fā)表于 12-28 15:01 ?13次下載

    立功:動態(tài)分布內(nèi)存——malloc()函數(shù)與calloc()函數(shù)

    立功教授數(shù)年之心血之作《程序設(shè)計與數(shù)據(jù)結(jié)構(gòu)》,電子版已無償性分享到電子工程師與高校群體,在公眾號回復(fù)【程序設(shè)計】即可在線閱讀。書本內(nèi)容公開后,在電子行業(yè)掀起一片學(xué)習(xí)熱潮。經(jīng)
    的頭像 發(fā)表于 08-22 17:01 ?4792次閱讀

    LabWindows/CVI 程序 調(diào)函數(shù)設(shè)計

    調(diào)函數(shù)是系統(tǒng)框架設(shè)計中非常重要的一種手段,所謂調(diào)函數(shù)(callback )是指一個通過
    發(fā)表于 05-03 16:54 ?1.1w次閱讀
    LabWindows/CVI <b class='flag-5'>程序</b> <b class='flag-5'>回</b><b class='flag-5'>調(diào)</b><b class='flag-5'>函數(shù)</b>設(shè)計

    調(diào)函數(shù)的詳細(xì)資料說明

    異步事件的處理,首先將異步事件發(fā)生時需要執(zhí)行的代碼編寫成一個函數(shù),并將該函數(shù)注冊成為調(diào)函數(shù),這樣
    發(fā)表于 02-28 08:00 ?6次下載
    <b class='flag-5'>回</b><b class='flag-5'>調(diào)</b><b class='flag-5'>函數(shù)</b>的詳細(xì)資料說明

    C語言函數(shù)調(diào)函數(shù)

    來源:嵌入式客棧 1 什么是調(diào)函數(shù)?首先什么是調(diào)呢? 我的理解是:把一段可執(zhí)行的代碼像參數(shù)傳遞那樣傳給其他代碼,而這段代碼會在某個時刻被
    的頭像 發(fā)表于 09-11 09:57 ?4076次閱讀

    c語言調(diào)函數(shù)的使用及實際作用詳解

    大家好,我是無際。今天給大家講一下芯片/模塊廠家SDK必須會使用的一種技術(shù)調(diào)函數(shù)。
    發(fā)表于 11-20 19:51 ?13次下載
    c語言<b class='flag-5'>回</b><b class='flag-5'>調(diào)</b><b class='flag-5'>函數(shù)</b>的使用及實際作用詳解

    函數(shù)指針和調(diào)函數(shù)的使用方法

    了解開發(fā)語言的朋友應(yīng)該都會對調(diào)函數(shù)有所了解,在很多的程序開發(fā)語言中都能看到調(diào)的身影。很多場景
    的頭像 發(fā)表于 04-10 15:08 ?1024次閱讀