從函式指標陣列的運用來看程式結構化設計

2022-03-30 22:36:11 字數 4214 閱讀 1953

我們之前從底層研究了c

語言,也學習了

c語言的組成部分和使用方法,但是

c語言是一門程式語言,它是要用來編寫程式的。要編寫乙個好的程式,首先要弄清這個程式要幹什麼,也就是需求分析,之後要思考及確定實現這個目標的方法,怎麼樣讓程式簡短、高效、易懂、可移植、方便維護和修改,這涉及到要怎麼實現演算法、怎樣放置資料和**、怎麼寫函式、怎麼呼叫函式等等,這就是程式設計。程式設計是乙個程式設計師綜合實力的體現,要想設計出好的程式,要有程式設計思想。

我們來看程式1

,程式的功能是:可以接收使用者依次輸入,乙個字串

a、乙個字元

ch、乙個字串

b,這些內容分別描述乙個整型資料、乙個運算子、乙個整型資料,然後根據字元

ch所描述的運算子如:「

+」、「

-」,對字串a和

b的描述資料進行運算,將運算結果顯示出來。

程式的執行結果如下:

這個程式的功能是使用者先輸入乙個數,按回車後再輸入加號或減號,再輸入乙個數,然後輸出結果。這個功能有有幾個重點:(1

)輸入方式,用什麼函式輸入(

2)輸入的字串怎麼轉換成乙個數輸出(

3)怎麼進行輸入檢驗。我們來看看上面的程式是怎麼實現的:

(1)對於字串使用gets

()函式輸出,對於符號使用

getch

()函式輸出,因為

c語言裡沒有字串型別,所以這裡定義的是兩個字元陣列,在這裡定義的陣列長度為

20,也就是說使用者最多能輸入長度為

20個位元組的資料。

gets

()函式可以無限讀取,不會判斷上限,以回車結束讀取。getch()函式可以從控制台讀取乙個字元,但是不顯示在螢幕上,但是我們希望能把輸入的符號也顯示出來,所以程式在這裡使用了乙個

printf

()函式輸出

getch

()函式得到的字元,其實這裡也可以使用

getche

()函式,它是可以自動將輸入的字元顯示在螢幕上的。

(2)程式裡是用atoi

()函式處理輸入的字串陣列的,它的功能是把字串轉換成整型數,它的引數是const char *,如果第乙個非空格字元存在,是數字或者正負號則開始做型別轉換,之後檢測到非數字(

包括結束符 

\0) 

字元時停止轉換,返回整型數。否則,返回零。因為陣列名可以看成乙個指標,所以這裡的型別是對應的。但是如果使用者輸入的包含不是數字的字元,那麼轉換的結果是0

,但是這裡沒有對這種錯誤的檢驗和報錯。

(3)程式對第二個輸入的變數進行了判斷,如果輸入的字元不是加號和減號,那麼會輸出錯誤提示「error

!」然後返回程式。

整個程式的邏輯就是先定義陣列和變數,再輸入,再判斷輸入,再輸出。所以這裡運算子的地位都是平等的,要將程式擴充為識別「*

」、「/

」,要在判斷和輸出裡加上「

如果要寫錯誤判斷,可以用迴圈判斷陣列a和b

裡的每個字元,如果為字母,則輸出錯誤提示。

再來看第二個程式:它功能與程式1

的相同:

程式二是定義了兩個運算函式add

、sub

,分別實現將兩個數相加和將兩個數相減的功能。又定義了乙個函式指標陣列存放這兩個函式的位址。這樣可以通過陣列來選擇並呼叫函式。另外我們定義了乙個字元指標

code

,並初始化為「

+-」,然後在

main

函式裡用

for語句判斷輸入的符號是加號還是減號,如果是加號,則

for語句結束後

n的值為

0,如果是減號,則

for語句結束後

n的值為

1。但是這裡有個問題:如果我們輸入的符號不是加號或減號,那麼

for語句怎麼跳出呢?我發現把

for語句裡的第乙個

code[n]

去掉之後,程式就無法進行下面

if語句的判斷了,是不是

code[n]

指的是迴圈中

n的值最大只能達到陣列的長度呢?我們寫乙個程式來驗證一下:

輸出結果為:

果然,這樣寫可以限制迴圈的次數在陣列的長度以內,那麼這是為什麼呢?因為之前我覺得有問題是p[i]

指向的是記憶體的值,所以如果字串之後的記憶體如果儲存了別的資料判斷就會出錯。但是我忽略了字串後面會加乙個轉義字元「\0」

,即數字

0,所以這時

code[i]為0

,即為false

,所以迴圈會停止,而!

code[n]為1

,則if

語句裡判斷能通過,所以會輸出錯誤資訊「

error

!」。如果輸入是加號或者減號,則不會執行if

語句裡的語句。呼叫函式指標陣列

func[c](atoi(a),atoi(b));根據n

的值可以呼叫實現相加或相減的函式,然後輸出函式返回的值即運算的結果。

那麼我們根據程式的實現思路,如果要增加操作符,需要寫乙個實現該操作的函式,並將它加入到函式指標陣列中,這樣我們就可以通過函式指標陣列來呼叫函式實現功能。修改後的程式如下:

執行的結果如下:

對比程式1

和程式2

,可以發現程式

1的語句都是在

main

函式裡,它使用的方法比較簡單,但是要增加操作符比較麻煩,要修改程式需要再增加輸出語句並修改判斷方法,而程式

2是用子函式來實現乙個單獨的功能,並使用函式指標來進行函式的呼叫,使用函式指標陣列來管理函式,這樣所有的輸入、輸出、判斷語句都在

main

函式中,關於演算法的語句都在子函式裡,如果我們要增加新的操作符,只需要寫乙個新的子函式並在函式指標陣列裡將函式名寫入,在字元指標裡加入要新增的操作符,不需要修改

main

函式。這樣可以看出兩個函式的設計思想是不同的,程式1

比較符合人的思維,即定義、輸入、判斷、輸出,這樣整合度高,思路清晰,易於實現,但是如果對於比較複雜的程式會造成難以修改和維護的情況,程式

2採用模組化的程式設計思想,用到了比較高階的方法,將功能模組化,而且用陣列進行管理更加有序,便於修改和維護,有更強大的擴充套件性和通用性。

與程式1

相比,程式

2中的共性實現在

main

函式裡,即輸入、判斷、輸出的功能,個性實現在子函式,即

add、

sub函式裡。它的模組化的設計思想對於大型程式的開發、管理和維護有十分重要的作用,對於程式設計和優化有很強的指導意義。

有人將程式設計總結成了一些原則,我們來看看這些原則是什麼:

(1)「開-

閉」原則:我們設計的程式應當在不被修改的情況下進行擴充套件,即要做到當增加新功能時不修改原來的程式,只增加新的函式或子程式。上面的程式

2就符合這個原則。

(2)迪公尺特法則:又叫做最少知識原則,即乙個子程式最好與其他子程式有最少的溝通和了解,同樣的,乙個函式最好盡可能少的呼叫其他函式或者使用全域性變數。

(3)單一職責原則:乙個函式應該盡可能地完成單一的工作。

還有一些原則是針對高階語言總結的,這裡就不做**了。

我們現在寫的程式都是一些小程式,除錯和修改都比較容易,所以比較少涉及到程式設計思想。當我們開發大型程式時,程式設計思想就比較重要了。所以我們平時一定要注意培養好的程式設計習慣和正確的程式設計思想。好的設計思路可以減少我們犯錯的頻率和除錯的難度。

函式指標的運用於程式示例

obsession 1162732624 qq.com 20160720 多交流如有誤請各位技術前輩指正 函式指標 函式指標是存放函式的位址的指標,函式位址是乙個函式的入口位址。注 函式名就是函式的入口位址 非常重要 當乙個函式指標指向了乙個函式,就可以通過這個指標來呼叫該函式,可以將函式作為引數傳...

從main函式學指標陣列和指標的指標

指標陣列格式定義如下 int p 10 再看看main函式寫法,argv定義為指標陣列 int main int argc,char argv 因為char是字元的基本單位,而main函式輸入的函式都是字串,因此要用字元指標去指向字串 又因為輸入的引數不指乙個,所以要用陣列儲存。兩個因素結合起來,就...

陣列 指標 函式 結構的組合

定義乙個結構體 typedef struct studentstudent 結構陣列 student st n 該陣列st中有n個student,每個student都有相應的num name score.如 st 0 num表示第乙個學生的學號結構指標 student st student st s...