我在開始學習程式設計的時候,其實往往腦子並不需要思考什麼內容,特別是瀏覽網路課程的時候,往往老師敲什麼,我就跟着敲什麼。
至於爲什麼那麼敲,大概也只是爲了演示語法罷了,跟老師打着一樣的結果,除非粗心大意,大多數也都會有和老師一樣的結果,過後也就不再深究爲什麼要這麼做了。
甚至我還開始期待起了下一個要敲的程式碼是什麼,這個功能又會有什麼樣的神奇效果。
這便是我對於程式碼的初印象,大概就是一個程式設計、執行、偵錯再執行的過程。甚至有了什麼程式需要編寫之後,我便有些手癢癢,躍躍欲試。
直到最近,我要在一個較短的時間內,完成一個對於我來說較爲複雜的專案。
當我看到任務需求的時候,我就被一一羅列出來的任務概述吸引了。我意識到,單單靠以前的野路子YY出一個程式的可能性不太大。
因此,我也嘗試以一次實踐爲例,粗淺地分析一下,程式設計之前,我們需要做哪些準備工作
(ps:出於保密原則,我就不將具體的需求放上來了)
本次對於程式的需求大約有六七個,而且有的需求依賴於其他需求的實現之上而並不是互相獨立地,但是根據C語言的程式設計思想(程序導向),因此也將打卡機的需求按照流程分爲大約4大板塊。
即:打卡前期的初始化數據準備、上班打卡、下班打卡以及週報彙總。
▲1.思維導圖的整體框架
劃分之後,我的程式設計圖景忽然明朗了起來,不再被紙面上的規律不太明顯的六七條需求帶路線,而是將一個個零零散散的需求都歸納到四個過程當中,然後將這四個過程模組都打包成爲一個個要去實現的函數,最後通過main()函數呼叫這四大步驟的函數就可以實現需求了。
至此初步的粗糙的框架算是搭建好了。
粗俗地理解,程式大概就是通過設計變數在一定規則之下的互動從而實現一定目的工具。
所以在搭建粗略框架的步驟之後,再將注意力放在了專案的需求上,挨個閱讀了一字一句,將裏面提到的名詞都拿出來斟酌,這個是不是我需要用到的變數。
特別是在標準C語言中,變數的定義並不像C++那般的方便,C語言變數的定義需要放在程式的開頭,所以在進行程式撰寫之前分析得出需要用到哪些變數對於後續的編寫可以起到事半功倍的效果。也不再需要等到需要用到變數才向上進行變數的定義。
▲2.「下班打卡」模組需要用到的變數
而對於變數本身而言,變數大體上分爲兩種,一種是全域性變數,一種是區域性變數。
區域性變數(Local Variable):定義在函數內部,作用域僅限於函數內部, 離開該函數後就是無效的,再使用就會報錯。
全域性變數(Global Variable):定義在所有函數外部,作用域預設是整個程式,也就是所有的原始檔,包括 .c 和 .h 檔案
於是,在仔細尋找完所有變數之後,繼續進行進一步地分析,哪些變數是需要參與到其他過程的,而哪些變數僅僅只是在本過程內有效的。之後,便可以將全域性變數單獨摘出來。當然也有不定義全域性變數的辦法,但是全域性變數本身也挺容易理解與使用的(起碼對於初學者來說是這樣的)。
於是,我當初嘗試定義一個全域性陣列,並且規定了陣列的每個對應位置所對應的元素的含義。
(現在想想還是定義全域性變數更爲直觀……)。
▲3.打卡機專案中需要用到的全域性變數
但是陣列也有個比較明顯的劣勢便是,陣列的每個元素的型別都是相同的,因此也並不是特別地方便,除了形式比較一致之外。
其實前面的這些都是基礎的鋪墊,更加重要的問題便是如何在編寫程式之前,把問題徹底理解並理清所有的邏輯判斷。
一個程式是依靠這些邏輯判斷組成的語法骨架最終支撐起來的,因此不妨通過流程圖的方式,想清楚最終執行的目標結果是什麼?
比如說:從動態的執行的角度來說,這個步驟需要怎樣的輸出,這些流程會經過哪些關鍵的節點,會有哪些中間變數,我應該如何儲存它、追蹤它並且最終展示出我想要的效果。
又比如說:從三大結構的角度來說,實現這些變數流需要使用哪些結構,是順序、條件還是回圈?
以上的分析都不妨通過文字或者思維導圖的方式進行一個呈現,這樣都會讓後續在編譯程式的過程當中理清思路。
▲4."下班打卡"模組中需要用到的一些條件判斷
當然,這些並不是非此即彼的單一結構,有時候需要幾大結構互相巢狀起來配合使用,具體情況具體分析。
通過前面三大步驟的分析,這個專案的需求也不再是一盤散沙,而是有了一層層的模組化設計,需要哪些變數,然後怎麼去實現也都有了思路,至於具體的技術實現,相信用心也能百度到。
或許到了以後慢慢實踐的過程,隨着專案難度的一步步加大以及程式設計技巧的逐漸熟練。對於一個專案來說,大多數的時間可能都是在設計程式框架,考慮程式方案,隨後纔是像碼農一樣在碼程式碼來實現實現這些過程。
先磨刀的感覺就好像是在進入森林之前已經通過地圖瞭解了一遍,這樣在一頭扎進森林的時候不至於迷路而不知所措。
磨刀不誤砍柴工,雖然有時候會慢一些,但是往往慢,而堅韌。