日韩三级在线福州江閩儀器技術有限公司
·
·
· 
  
 
 
 
·
産品(pin)搜索(suo):

技(ji)術交(jiao)流

周(zhou)立功(gong):設計(ji)良好(hao)💘日韩三级在线🛌🏻的程(cheng)序接(jie)口需(xu)注意(yi)的5個(ge)事項(xiang)
來源(yuan):   發布(bu)時間(jian):2025-11-21   浏覽(lan)量:66

周(zhou)立功(gong)教授(shou)數年(nian)之心(xin)血之(zhi)作《程(cheng)序設(she)計與(yu)數據(ju)結構(gou)》,電👻子(zi)版已(yi)無償(chang)性分(fen)享到(dao)電子(zi)工程(cheng)師與(yu)高校(xiao)群🥑️體(ti)。書本(ben)内容(rong)公開(kai)後,在(zai)電子(zi)行業(ye)掀起(qi)一片(pian)學習(xi)熱💁🏼‍♀️潮(chao)。經周(zhou)立功(gong)教✍🏻授(shou)授權(quan),特對(dui)本書(shu)内容(rong)進行(hang)連載(zai),願共(gong)勉之(zhi)。

第一(yi)章爲(wei)程序(xu)設計(ji)基礎(chu),本文(wen)爲1.5.2/1.5.3共(gong)性與(yu)可變(bian)性分(fen)析:建(jian)立抽(chou)象和(he)建立(li)接口(kou)。

>>>> 1.5.2 建立(li)抽象(xiang)

抽象(xiang)化的(de)目的(de)是使(shi)調用(yong)者無(wu)需知(zhi)道模(mo)塊的(de)内部(bu)✋細節(jie)🏃🏿‍♀️‍➡️,隻需(xu)要☠️知(zhi)道模(mo)塊或(huo)函數(shu)的名(ming)字,因(yin)此将(jiang)其稱(cheng)爲黑(hei)盒化(hua)。調用(yong)者隻(zhi)需要(yao)知道(dao)黑盒(he)子的(de)輸入(ru)和輸(shu)出,而(er)過程(cheng)的細(xi)節是(shi)隐👱🏼‍♂️藏(cang)的。由(you)于建(jian)立了(le)一個(ge)由黑(hei)盒子(zi)組成(cheng)的系(xi)統,因(yin)此複(fu)雜的(de)👱🏼‍♂️結構(gou)就被(bei)黑盒(he)子隐(yin)藏起(qi)來了(le),則理(li)解系(xi)統的(de)整體(ti)結構(gou)就變(bian)得更(geng)容易(yi)🏊🏿‍♀️了。

從(cong)概念(nian)的視(shi)角來(lai)看,建(jian)立抽(chou)象關(guan)注的(de)不是(shi)如何(he)實現(xian)⛹🏻‍♀️,而是(shi)函♌️數(shu)要做(zuo)什麽(me),過早(zao)地關(guan)注實(shi)現細(xi)節,将(jiang)實現(xian)細節(jie)隐藏(cang)起來(lai),進而(er)幫㊙️助(zhu)我們(men)構建(jian)更易(yi)于修(xiu)改的(de)軟件(jian)🧎🏻‍♀️‍➡️。因此(ci),我們(men)首先(xian)應該(gai)選擇(ze)一個(ge)具有(you)描述(shu)性的(de)符合(he)需求(qiu)的名(ming)字,雖(sui)然可(ke)以選(xuan)擇的(de)名字(zi)有swapByte、swapWord和(he)swap,但🙂‍↕️swap更(geng)簡潔(jie)更貼(tie)切。其(qi)次,可(ke)以用(yong)一句(ju)話概(gai)念性(xing)地描(miao)述🚶🏾‍♀️‍➡️swap的(de)數據(ju)抽象(xiang)🧑🏾‍🎄——swap是實(shi)現兩(liang)個數(shu)據交(jiao)換的(de)函數(shu)。

顯然(ran),調用(yong)者僅(jin)需一(yi)般性(xing)地在(zai)概念(nian)層次(ci)上與(yu)實現(xian)者交(jiao)🔞流,因(yin)爲調(diao)用者(zhe)的意(yi)圖是(shi)如何(he)使用(yong)swap()實現(xian)兩個(ge)數據(ju)的交(jiao)👩🏽‍🐰‍👩🏿換,所(suo)以無(wu)🙂‍↕️需準(zhun)确地(di)知道(dao)實現(xian)的細(xi)節。而(er)具體(ti)如何(he)完成(cheng)數據(ju)的交(jiao)換,這(zhe)是在(zai)實現(xian)層次(ci)進行(hang)的。由(you)此可(ke)🤑見,将(jiang)模塊(kuai)的目(mu)的與(yu)實現(xian)分離(li)的抽(chou)象揭(jie)👿示了(le)問題(ti)的本(ben)質,并(bing)沒有(you)提供(gong)解決(jue)方案(an)。隻說(shuo)明需(xu)要做(zuo)什麽(me),并不(bu)😝會指(zhi)出如(ru)何實(shi)🤶🏾現某(mou)個模(mo)塊。隻(zhi)要概(gai)念不(bu)變,調(diao)用者(zhe)與實(shi)現細(xi)節的(de)變化(hua)就徹(che)底隔(ge)離了(le)。當某(mou)個模(mo)塊完(wan)成編(bian)碼後(hou),隻要(yao)說明(ming)該模(mo)塊的(de)目的(de)和參(can)數就(jiu)可以(yi)使用(yong)它,無(wu)需知(zhi)道具(ju)體的(de)實現(xian)。

函數(shu)抽象(xiang)對團(tuan)隊項(xiang)目非(fei)常重(zhong)要,因(yin)爲在(zai)團隊(dui)中必(bi)須使(shi)用其(qi)他🧑🏽‍❤️‍💋‍🧑🏻成(cheng)員編(bian)寫的(de)模塊(kuai)。比如(ru),編程(cheng)語言(yan)本身(shen)自帶(dai)的庫(ku)函數(shu),由于(yu)已經(jing)被預(yu)編譯(yi),因此(ci)無法(fa)訪問(wen)它的(de)源代(dai)碼。同(tong)時庫(ku)函數(shu)不一(yi)定是(shi)用C編(bian)寫的(de),因此(ci)隻要(yao)知道(dao)其調(diao)用規(gui)👨🏻‍🏭範,就(jiu)可以(yi)在程(cheng)序中(zhong)毫無(wu)顧忌(ji)地使(shi)用這(zhe)個函(han)數。實(shi)際上(shang),在使(shi)用scanf()函(han)數🛌🏻的(de)過程(cheng)中,我(wo)們考(kao)慮過(guo)scanf()是如(ru)何實(shi)現的(de)嗎?無(wu)關緊(jin)要。盡(jin)管不(bu)同系(xi)統實(shi)現scanf()的(de)方法(fa)可能(neng)不一(yi)👽樣,但(dan)其中(zhong)的不(bu)同對(dui)于程(cheng)序員(yuan)來說(shuo)是透(tou)明的(de)。

>>>> 1.5.3 建立(li)接口(kou)

接口(kou)是由(you)公開(kai)訪問(wen)的方(fang)法和(he)數據(ju)組成(cheng)的,接(jie)口描(miao)述了(le)與模(mo)塊交(jiao)互的(de)唯一(yi)途徑(jing)。最小(xiao)化的(de)接口(kou)隻包(bao)含對(dui)于接(jie)口的(de)任務(wu)非常(chang)重要(yao)的參(can)數,最(zui)小化(hua)的接(jie)🧑🏻‍❤️‍🧑🏼口便(bian)于學(xue)習如(ru)何與(yu)之交(jiao)互,且(qie)🧑🏾‍🎄隻需(xu)要👽理(li)解少(shao)量的(de)參數(shu),同時(shi)易于(yu)擴展(zhan)和維(wei)護,因(yin)😌此設(she)計良(liang)好的(de)接口(kou)是一(yi)項重(zhong)要的(de)技能(neng)。

>>> 1. 函數(shu)調用(yong)

(1)傳值(zhi)調用(yong)

如何(he)調用(yong)swap()函數(shu)呢?實(shi)參将(jiang)值從(cong)主調(diao)函數(shu)傳遞(di)給被(bei)調🎅🏿函(han)數,也(ye)許其(qi)調用(yong)形式(shi)是下(xia)面這(zhe)樣的(de):
swap(a, b);

從黑(hei)盒視(shi)角來(lai)看,形(xing)參和(he)其它(ta)局部(bu)變量(liang)都是(shi)函數(shu)私有(you)💕的,聲(sheng)明在(zai)不同(tong)函數(shu)中的(de)同名(ming)變量(liang)是完(wan)全不(bu)同的(de)變量(liang),而且(qie)函數(shu)無法(fa)直接(jie)訪問(wen)其它(ta)函數(shu)中的(de)變量(liang),這種(zhong)限制(zhi)訪問(wen)保護(hu)了數(shu)據的(de)完整(zheng)性,黑(hei)盒發(fa)生了(le)什麽(me)對主(zhu)調函(han)🏊🏾‍♀️數是(shi)不可(ke)見的(de)。

一個(ge)變量(liang)的有(you)效範(fan)圍稱(cheng)作它(ta)的作(zuo)用域(yu),變量(liang)的作(zuo)用😁域(yu)指可(ke)以通(tong)過變(bian)量名(ming)稱引(yin)用變(bian)量的(de)區域(yu),在函(han)數内(nei)部聲(sheng)明的(de)變量(liang)隻在(zai)該函(han)數内(nei)部有(you)效。當(dang)主調(diao)函數(shu)調用(yong)子函(han)數時(shi),主函(han)數内(nei)聲明(ming)的變(bian)量在(zai)子函(han)數内(nei)無效(xiao),子函(han)數内(nei)^聲明(ming)的變(bian)量也(ye)隻在(zai)♌️該子(zi)函數(shu)内部(bu)有效(xiao)。

由于(yu)傳遞(di)給函(han)數的(de)是變(bian)量的(de)替身(shen),因此(ci)改變(bian)函數(shu)參數(shu)對👨‍🦰原(yuan)始變(bian)量沒(mei)有影(ying)響。當(dang)變量(liang)傳遞(di)給函(han)數時(shi),變量(liang)的值(zhi)被複(fu)制給(gei)函數(shu)參數(shu)。由此(ci)可見(jian),通過(guo)“傳值(zhi)👽調用(yong)”方式(shi)交換(huan)a、b的值(zhi),無法(fa)改變(bian)主調(diao)函👺數(shu)相應(ying)變量(liang)的值(zhi)。

(2)傳址(zhi)調用(yong)

如果(guo)希望(wang)通過(guo)被調(diao)函數(shu)将更(geng)多的(de)值傳(chuan)回主(zhu)調函(han)👻數而(er)改變(bian)主調(diao)函數(shu)中的(de)變量(liang),則使(shi)用“傳(chuan)址調(diao)用”——将(jiang)🧜🏼‍♂️&a、&b作爲(wei)實參(can)傳遞(di)給形(xing)參。其(qi)調用(yong)形式(shi)如下(xia):
swap(&a, &b);

利用(yong)指針(zhen)作爲(wei)函數(shu)參數(shu)傳遞(di)數據(ju)的本(ben)質,就(jiu)是在(zai)主調(diao)函數(shu)🙂‍↕️和被(bei)調函(han)數中(zhong),通過(guo)不同(tong)的指(zhi)針指(zhi)向同(tong)一内(nei)存地(di)址訪(fang)♌️問相(xiang)同的(de)内存(cun)區域(yu),即它(ta)們背(bei)後共(gong)享相(xiang)同的(de)内存(cun),從而(er)實現(xian)數據(ju)的傳(chuan)遞和(he)交換(huan)。

>>> 2. 函數(shu)原型(xing)

函數(shu)原型(xing)是C語(yu)言的(de)一個(ge)強有(you)力的(de)工具(ju),它讓(rang)編譯(yi)器捕(bu)♌️獲在(zai)使用(yong)函數(shu)時可(ke)能出(chu)現的(de)許多(duo)錯誤(wu)或疏(shu)漏。如(ru)💞果編(bian)譯器(qi)沒有(you)發現(xian)這些(xie)問題(ti),就很(hen)難察(cha)覺出(chu)來。函(han)數💯原(yuan)型包(bao)括函(han)數🔞返(fan)回值(zhi)的類(lei)型、函(han)數名(ming)和形(xing)參列(lie)表(參(can)數的(de)數量(liang)和每(mei)個參(can)數的(de)類型(xing)),有了(le)這些(xie)🧎🏻‍♀️‍➡️信息(xi),編譯(yi)器就(jiu)可以(yi)檢查(cha)函數(shu)調用(yong)與函(han)數原(yuan)型是(shi)👩🏼‍❤️‍👨🏾否匹(pi)配?比(bi)如,參(can)數的(de)數量(liang)是否(fou)正确(que)?參數(shu)的類(lei)型是(shi)否匹(pi)配?如(ru)果類(lei)型😸不(bu)匹配(pei)🙈,編譯(yi)器會(hui)将實(shi)參的(de)類型(xing)轉換(huan)成形(xing)參的(de)類型(xing)。

(1)函數(shu)形參(can)

通過(guo)程序(xu)清單(dan) 1.15可以(yi)看出(chu),其相(xiang)同的(de)處理(li)部分(fen)是2個(ge)int類值(zhi)👩🏿‍❤️‍💋‍👨🏽的😌交(jiao)換^代(dai)碼,因(yin)此可(ke)以将(jiang)數據(ju)交換(huan)代碼(ma)移到(dao)swap()函數(shu)的實(shi)🏊🏾‍♀️現中(zhong),其可(ke)變的(de)數據(ju)由外(wai)部傳(chuan)進來(lai)的參(can)數應(ying)對。由(you)于&a是(shi)🏊🏾‍♀️指向(xiang)int類型(xing)變量(liang)a的指(zhi)針,&b是(shi)指向(xiang)int類型(xing)👨🏻‍🏭變量(liang)b的指(zhi)針,因(yin)此必(bi)👽須将(jiang)p1、p2形參(can)🧎🏻‍♀️‍➡️聲明(ming)爲指(zhi)向int *類(lei)型的(de)指針(zhen)變量(liang),即必(bi)須将(jiang)存儲(chu)int類型(xing)值變(bian)量的(de)地址(zhi)作爲(wei)實參(can)賦給(gei)指🏃🏻‍♀️針(zhen)😺形參(can),實參(can)與形(xing)參才(cai)能匹(pi)配。其(qi)函數(shu)原型(xing)進化(hua)如下(xia):
swap(int *p1, int *p2);

(2)返回(hui)值的(de)類型(xing)

聲明(ming)函數(shu)時必(bi)須聲(sheng)明函(han)數的(de)類型(xing),帶返(fan)回值(zhi)的函(han)👨🏻‍🏭數類(lei)型應(ying)該與(yu)其返(fan)回值(zhi)類型(xing)相同(tong),而沒(mei)有返(fan)回值(zhi)😝的函(han)數應(ying)該聲(sheng)明爲(wei)void。類型(xing)聲明(ming)是函(han)數定(ding)義的(de)一部(bu)分,函(han)數類(lei)型指(zhi)💔的是(shi)返回(hui)值的(de)類型(xing),不是(shi)函數(shu)參數(shu)🏃🏻‍♀️的類(lei)型。

雖(sui)然可(ke)以使(shi)用return返(fan)回值(zhi),但return隻(zhi)能返(fan)回一(yi)個值(zhi)給主(zhu)調函(han)數。比(bi)🧑🏾‍🎄如,如(ru)果返(fan)回值(zhi)爲整(zheng)數,則(ze)函數(shu)返回(hui)值的(de)類型(xing)爲int。當(dang)返回(hui)值爲(wei)int類✡️型(xing)時,如(ru)果返(fan)回值(zhi)爲負(fu)數,則(ze)表示(shi)失敗(bai);如果(guo)返回(hui)值爲(wei)非負(fu)數,則(ze)表示(shi)成功(gong)。當返(fan)回值(zhi)爲bool類(lei)型時(shi),如果(guo)返回(hui)值爲(wei)false,則👩🏿‍❤️‍💋‍👨🏽表(biao)示失(shi)敗,如(ru)果返(fan)回值(zhi)爲true,則(ze)表示(shi)成功(gong)。當返(fan)回值(zhi)爲指(zhi)針類(lei)型時(shi),如果(guo)返👀回(hui)值爲(wei)NULL,則表(biao)示失(shi)敗,否(fou)則返(fan)回🏊🏾‍♀️一(yi)個有(you)效的(de)指針(zhen)。

如果(guo)利用(yong)指針(zhen)作爲(wei)參數(shu)傳遞(di)給函(han)數,不(bu)僅可(ke)以向(xiang)函數(shu)傳入(ru)👾數據(ju),而且(qie)還可(ke)以從(cong)函數(shu)返回(hui)多個(ge)值。因(yin)爲函(han)👱🏼‍♂️數的(de)調用(yong)者和(he)函數(shu)都可(ke)以使(shi)用指(zhi)向同(tong)一内(nei)存地(di)址的(de)指針(zhen),即使(shi)用同(tong)一塊(kuai)内存(cun),所🤶🏾以(yi)使用(yong)指針(zhen)作爲(wei)函數(shu)👿參數(shu)時就(jiu)是對(dui)同一(yi)數據(ju)進行(hang)讀寫(xie)操作(zuo)。這樣(yang)不僅(jin)可以(yi)傳入(ru)數據(ju)👧🏾,還可(ke)以通(tong)過😮‍💨在(zai)函數(shu)内部(bu)修改(gai)這些(xie)數😜據(ju),将函(han)數的(de)結果(guo)傳出(chu)給調(diao)用者(zhe)。

當函(han)數的(de)實參(can)是指(zhi)針變(bian)量時(shi),有時(shi)希望(wang)函數(shu)能通(tong)過✡️指(zhi)針指(zhi)向~别(bie)處的(de)方式(shi)改變(bian)此變(bian)量,則(ze)需要(yao)使用(yong)指向(xiang)指針(zhen)的指(zhi)針作(zuo)🧑🏽‍🎄爲形(xing)參。

由(you)于swap()無(wu)返回(hui)值,因(yin)此swap()返(fan)回值(zhi)的類(lei)型爲(wei)void,其函(han)數原(yuan)型如(ru)下:
void swap(int *p1, int *p2);

其(qi)被解(jie)釋爲(wei)swap是返(fan)回void的(de)函數(shu)(參數(shu)是int *p1,int *p2)。

這(zhe)是一(yi)個不(bu)斷叠(die)代優(you)化的(de)過程(cheng),用戶(hu)隻需(xu)要知(zhi)道“函(han)數名(ming)、傳入(ru)✡️函數(shu)的參(can)數和(he)函數(shu)返回(hui)值的(de)類型(xing)”,就知(zhi)道如(ru)何有(you)效地(di)調用(yong)相應(ying)的函(han)數。

>>> 3.  依(yi)賴倒(dao)置原(yuan)則

在(zai)面向(xiang)過程(cheng)編程(cheng)中,通(tong)常的(de)做法(fa)是高(gao)層模(mo)塊調(diao)用低(di)層模(mo)塊,其(qi)目的(de)之一(yi)就是(shi)要定(ding)義子(zi)程序(xu)層次(ci)結構(gou)。當高(gao)層模(mo)塊依(yi)賴于(yu)低層(ceng)模塊(kuai)時,對(dui)低層(ceng)模塊(kuai)的改(gai)動會(hui)直接(jie)影響(xiang)高層(ceng)模塊(kuai),從而(er)迫使(shi)它們(men)依次(ci)做出(chu)修改(gai)。如果(guo)高層(ceng)模塊(kuai)獨立(li)于低(di)層模(mo)塊,則(ze)高層(ceng)模塊(kuai)更容(rong)易重(zhong)用,這(zhe)就是(shi)分💔層(ceng)架構(gou)設計(ji)的核(he)心原(yuan)則,即(ji)依賴(lai)倒置(zhi)原則(ze)(Dependence Inversion Principle,DIP):

● 高層(ceng)模塊(kuai)不應(ying)該依(yi)賴低(di)層模(mo)塊,兩(liang)者都(dou)應該(gai)依賴(lai)于抽(chou)象接(jie)口;

● 抽(chou)象接(jie)口不(bu)應該(gai)依賴(lai)于細(xi)節,細(xi)節應(ying)該依(yi)賴抽(chou)象接(jie)口。

當(dang)在分(fen)層架(jia)構中(zhong)使用(yong)依賴(lai)倒置(zhi)原則(ze)時,将(jiang)會發(fa)現“不(bu)再存(cun)在分(fen)層”的(de)概念(nian)了。無(wu)論是(shi)高層(ceng)還是(shi)低層(ceng),它😘們(men)都依(yi)賴于(yu)抽象(xiang)接口(kou),好像(xiang)将整(zheng)個分(fen)層架(jia)構推(tui)平🔞一(yi)樣。

其(qi)實從(cong)“Hello World”程序(xu)開始(shi),我們(men)就已(yi)經在(zai)使用(yong)stdio.h包含(han)的“抽(chou)象接(jie)口”了(le),即以(yi)後凡(fan)是用(yong)#include文件(jian)的擴(kuo)展名(ming)叫.h(頭(tou)文件(jian))。如果(guo)源代(dai)碼中(zhong)要用(yong)到stdio标(biao)準輸(shu)入輸(shu)出函(han)數時(shi),那麽(me)就要(yao)包含(han)這個(ge)頭文(wen)件,比(bi)ˇ如,“scanf("%d",&i);”函(han)數㊙️,其(qi)目的(de)是告(gao)訴編(bian)譯器(qi)要使(shi)用stdio庫(ku)。庫是(shi)一種(zhong)工具(ju)的集(ji)合,這(zhe)些工(gong)具是(shi)由其(qi)它程(cheng)序員(yuan)編寫(xie)的,用(yong)于實(shi)現特(te)定的(de)功能(neng)。盡管(guan)實現(xian)者無(wu)需關(guan)👱🏼‍♂️心用(yong)戶将(jiang)如何(he)使ˇ用(yong)庫,且(qie)不會(hui)直接(jie)開✍🏻放(fang)源代(dai)碼給(gei)用戶(hu)使用(yong),但必(bi)須給(gei)用戶(hu)提供(gong)調用(yong)函💞數(shu)所需(xu)要的(de)信息(xi)。顯然(ran)隻要(yao)将頭(tou)文件(jian)開放(fang)給用(yong)戶,即(ji)可讓(rang)用戶(hu)了解(jie)接口(kou)的所(suo)有細(xi)節,詳(xiang)見程(cheng)序清(qing)單 1.16。

程(cheng)序清(qing)單 1.16 swap數(shu)據交(jiao)換接(jie)口(swap.h)
1     #ifndef  _SWAP_H
2     #define  _SWAP_H
3     // 前(qian)置條(tiao)件:實(shi)參必(bi)須是(shi)int類型(xing)變量(liang)的地(di)址
4     // 後(hou)置條(tiao)件:p1、p2作(zuo)爲輸(shu)出參(can)數,改(gai)變主(zhu)調函(han)數中(zhong)相應(ying)的🙆🏿變(bian)量
5     void swap(int *p1, int *p2);
6     // 調(diao)用形(xing)式:swap(&a, &b)
7     #endif

其(qi)中,每(mei)個頭(tou)文件(jian)都指(zhi)出了(le)一個(ge)用戶(hu)可見(jian)的外(wai)部函(han)數接(jie)口,主(zhu)要包(bao)括函(han)數名(ming)、所需(xu)的參(can)數、參(can)數的(de)類型(xing)和返(fan)回💑🏾結(jie)果😥的(de)類型(xing)。其中(zhong),swap是庫(ku)的名(ming)字,程(cheng)序清(qing)單👽 1.16(1~2)與(yu)(8)是幫(bang)助編(bian)譯器(qi)記錄(lu)它所(suo)讀取(qu)的接(jie)🔞口,當(dang)寫一(yi)個接(jie)口時(shi),必須(xu)包含(han)#ifndef、#define和#ednif。#include行(hang)部分(fen)僅當(dang)接口(kou)本身(shen)需要(yao)其它(ta)庫時(shi)才使(shi)用,它(ta)由标(biao)準的(de)#include行組(zu)成。程(cheng)💑🏾序清(qing)單 1.16(6)接(jie)口項(xiang)表示(shi)庫輸(shu)出的(de)函數(shu)的原(yuan)型、常(chang)量和(he)類型(xing)等。不(bu)管你(ni)是否(fou)理🏊🏿‍♀️解(jie),這些(xie)行是(shi)接口(kou)的模(mo)闆💕文(wen)件,這(zhe)就是(shi)信息(xi)隐藏(cang)。

>>> 4. 前/後(hou)置條(tiao)件

處(chu)理信(xin)息隐(yin)藏還(hai)涉及(ji)到另(ling)一個(ge)技術(shu),那就(jiu)是使(shi)用前(qian)置😗條(tiao)件和(he)後置(zhi)條件(jian)描述(shu)函數(shu)的行(hang)爲。在(zai)編寫(xie)一個(ge)完整(zheng)的函(han)數定(ding)義時(shi),需要(yao)描述(shu)該函(han)數是(shi)如何(he)執行(hang)計算(suan)的。但(dan)在使(shi)用函(han)數時(shi),隻😝需(xu)考慮(lü)😵‍💫該函(han)數能(neng)做💁🏼‍♀️什(shi)麽,無(wu)需知(zhi)道是(shi)如何(he)完成(cheng)的。當(dang)不知(zhi)道😗函(han)數是(shi)如何(he)實現(xian)時,就(jiu)是在(zai)使用(yong)一種(zhong)名爲(wei)過程(cheng)抽象(xiang)的信(xin)息👨🏻‍🏭隐(yin)藏形(xing)式,它(ta)抽象(xiang)掉的(de)是函(han)數如(ru)何工(gong)作的(de)細節(jie)。計算(suan)機科(ke)學家(jia)使用(yong)👽“過程(cheng)”表示(shi)任意(yi)指👨🏻‍🏭令(ling)集,因(yin)此使(shi)用術(shu)語過(guo)程抽(chou)象。過(guo)程抽(chou)象是(shi)一種(zhong)強大(da)的🧜🏼‍♂️工(gong)具,使(shi)得我(wo)們一(yi)次隻(zhi)考慮(lü)一個(ge)😮‍💨而不(bu)是所(suo)有的(de)函數(shu),從而(er)使問(wen)題求(qiu)解簡(jian)單化(hua)。

爲了(le)使描(miao)述更(geng)準确(que),則需(xu)要遵(zun)循固(gu)定的(de)格式(shi),它包(bao)含兩(liang)部分(fen)信息(xi):函數(shu)的前(qian)置條(tiao)件和(he)後置(zhi)條件(jian)。前置(zhi)條件(jian)🎅🏿就是(shi)🧑🏽‍🎄調用(yong)該函(han)數必(bi)須成(cheng)立的(de)條件(jian),當函(han)數被(bei)調用(yong)時😁,該(gai)語句(ju)⛹🏻‍♀️給出(chu)要求(qiu)爲真(zhen)的條(tiao)件。除(chu)非前(qian)置條(tiao)件爲(wei)真,否(fou)則無(wu)法保(bao)證函(han)數能(neng)正确(que)執行(hang)。在調(diao)用swap()函(han)數時(shi),實參(can)必須(xu)是int類(lei)型變(bian)量的(de)地址(zhi),這👽是(shi)調用(yong)者的(de)ˇ職責(ze)。通常(chang)在函(han)數開(kai)始處(chu)檢查(cha)是否(fou)滿足(zu)?如果(guo)不滿(man)足,說(shuo)明調(diao)用代(dai)碼有(you)問題(ti),抛出(chu)一個(ge)異常(chang)。

後置(zhi)條件(jian)就是(shi)該操(cao)作完(wan)成後(hou)必須(xu)成立(li)的條(tiao)件,當(dang)函數(shu)調🧑🏾‍🎄用(yong)時,如(ru)果函(han)數是(shi)正确(que)的,而(er)且前(qian)置條(tiao)件爲(wei)真,那(na)麽該(gai)函數(shu)調用(yong)将可(ke)以執(zhi)行完(wan)成。當(dang)函數(shu)調用(yong)完成(cheng)後,後(hou)置條(tiao)件爲(wei)真。如(ru)果不(bu)😌滿足(zu)後置(zhi)條件(jian),則說(shuo)明業(ye)務邏(luo)輯有(you)問題(ti)。

當滿(man)足調(diao)用swap()函(han)數的(de)前置(zhi)條件(jian)時,必(bi)須同(tong)時确(que)保其(qi)結👾束(shu)時滿(man)足它(ta)的後(hou)置條(tiao)件,其(qi)後置(zhi)條件(jian)是被(bei)調函(han)數将(jiang)🏊🏾‍♀️返回(hui)👺值傳(chuan)👩‍🍼回主(zhu)調函(han)數,改(gai)變主(zhu)調函(han)數中(zhong)變量(liang)的值(zhi)。

前後(hou)置條(tiao)件不(bu)隻是(shi)概括(kuo)地描(miao)述函(han)數的(de)行爲(wei),聲明(ming)這些(xie)條件(jian)應該(gai)是設(she)計任(ren)何函(han)數的(de)第一(yi)步。在(zai)開始(shi)考慮(lü)某個(ge)函數(shu)的算(suan)法和(he)代碼(ma)之前(qian),應該(gai)寫出(chu)該函(han)數的(de)原型(xing),其中(zhong)包括(kuo)函數(shu)的返(fan)回類(lei)型、名(ming)稱和(he)參數(shu)列表(biao),最後(hou)👩🏽‍🐰‍👩🏿緊跟(gen)一個(ge)分号(hao)。直接(jie)來自(zi)于用(yong)戶的(de)輸入(ru)不能(neng)作爲(wei)前置(zhi)條件(jian),通常(chang)前/後(hou)置條(tiao)件🙂‍↔️都(dou)可以(yi)轉化(hua)爲assert語(yu)句。編(bian)寫函(han)數原(yuan)型時(shi),應該(gai)以注(zhu)釋的(de)形式(shi)描述(shu)👩🏽‍🐰‍👩🏿該函(han)數的(de)前置(zhi)條件(jian)和後(hou)置條(tiao)件。

事(shi)實上(shang),前置(zhi)條件(jian)和後(hou)置條(tiao)件在(zai)使用(yong)函數(shu)的程(cheng)序員(yuan)和編(bian)🛌🏻寫函(han)數的(de)程序(xu)員之(zhi)間形(xing)成了(le)一個(ge)契約(yue),也就(jiu)是😵‍💫爲(wei)什麽(me)需要(yao)這個(ge)函數(shu)?接口(kou)通過(guo)前置(zhi)條件(jian)和👩‍🍼後(hou)置條(tiao)件以(yi)契約(yue)的形(xing)式表(biao)達需(xu)求,承(cheng)👹諾在(zai)滿足(zu)前🧑🏾‍🎄置(zhi)條件(jian)時開(kai)始,按(an)照🧑🏻‍❤️‍🧑🏼程(cheng)序的(de)流程(cheng)運行(hang),系統(tong)就能(neng)到👻達(da)後置(zhi)條件(jian)。

雖然(ran)注釋(shi)是一(yi)種很(hen)好的(de)溝通(tong)形式(shi),但在(zai)代碼(ma)可以(yi)🤑傳遞(di)意圖(tu)⛹🏻‍♀️的地(di)方不(bu)要寫(xie)注釋(shi)。因爲(wei)代碼(ma)解釋(shi)做了(le)什麽(me),再注(zhu)釋也(ye)沒有(you)什麽(me)用處(chu),相反(fan)注釋(shi)要說(shuo)明爲(wei)什麽(me)會這(zhe)樣寫(xie)代碼(ma)?

>>> 5. 開閉(bi)原則(ze)

接口(kou)僅需(xu)指明(ming)用戶(hu)調用(yong)程序(xu)可能(neng)調用(yong)的标(biao)識符(fu),應盡(jin)可🤶🏾能(neng)地将(jiang)算法(fa)以及(ji)一些(xie)與具(ju)體的(de)實現(xian)細節(jie)⛹🏻‍♀️無關(guan)的信(xin)息隐(yin)藏起(qi)來,這(zhe)樣用(yong)戶在(zai)調用(yong)程序(xu)時也(ye)👼🏾就不(bu)必依(yi)賴特(te)定的(de)實現(xian)細節(jie)了。當(dang)接口(kou)一旦(dan)發布(bu)㊙️後,也(ye)就不(bu)能改(gai)變了(le),因爲(wei)改變(bian)接口(kou)勢必(bi)引起(qi)用戶(hu)👌程序(xu)的改(gai)變。如(ru)果此(ci)前定(ding)😜義的(de)接口(kou)滿足(zu)不了(le)需求(qiu)✍🏻,怎麽(me)辦?隻(zhi)能擴(kuo)🙂‍↔️展新(xin)的接(jie)口,但(dan)不能(neng)修改(gai)或廢(fei)除原(yuan)有的(de)接口(kou),這就(jiu)是“對(dui)修改(gai)關閉(bi),對擴(kuo)展開(kai)放”的(de)開閉(bi)🙂‍↕️原則(ze)(Open-Closed Princple,OCP)。顯然(ran),依賴(lai)倒置(zhi)🧑🏽‍❤️‍💋‍🧑🏻原則(ze)更加(jia)精确(que)的定(ding)義就(jiu)是面(mian)向接(jie)口的(de)編程(cheng),它是(shi)實現(xian)開閉(bi)原則(ze)的重(zhong)要途(tu)徑。如(ru)😁果DIP依(yi)賴倒(dao)置原(yuan)則沒(mei)有實(shi)現,就(jiu)别想(xiang)實現(xian)對擴(kuo)展開(kai)🧑🏽‍🎄放,對(dui)修改(gai)關閉(bi)。

·
·
·
·
 ·