引言
第一次聽到這個思想時,我覺得這和那些形而上的指導方針是一個套路,就是說來聽聽,沒有任何實際的應用價值。事實似乎也驗證了我的這個猜想,在開始學習碼代碼的前兩個月,我從來沒有應用過這個思想,然而這也沒有給我造成什麼困擾。究其原因,大概就是題目簡單,代碼不長。終於,在前兩天我完成了一個200行的程序,才第一次感受到了這個思想的重要性。
200行的代碼,如果不通過“自頂向下,逐步求精”,將問題具體化,那麼找bug,修改參數將是一件痛苦得不能再痛苦的事情。至此,才終於後悔“不聽老人言”,沒有在一開始就養成這個好習慣。
自頂向下,逐步求精
那麼,什麼叫自頂向下逐步求精呢?
簡單來說,就是將問題分化,將大的問題分成小的問題,將每一個要實現的操作轉變爲一個函數,然後再在函數中繼續這個過程。
圖片來自網絡
這樣的編程思路,有助於我們修正代碼,檢查中間量,同時也有助於將問題分工,實現合作。下面我就通過一個具體的例子來解釋一下。
舉個例子
比如現在我們想要解決這樣一個問題:將用戶輸入的10進制數轉化爲16進制數。(爲了更好地體現這個思想,這裏選擇的方法可能較爲複雜,請讀者不要在意這些細節,體會思想就好)
首先我們敲出main函數,即這個程序的主體。
int main() {
int number1;
char number[10];
scanf("%d", &number1);
if (number1 >= 0) {
translate(number1, 0, number);
}
else {
number[0] = '-';
number1 = -number1;
translate(number1, 1, number);
}
print(number);
system("pause");
}
這裏我們調用了兩個函數,分別是translate—具體的轉換函數,以及print—打印字符組的函數。下面我們分別敲出這兩個函數。
void translate(int n, int i, char text[]) {
int j;
int y = len(n);
for (j = 0; j < y; j++) {
int x = n % 16;
n = n / 16;
if (x < 10) text[i + y - j - 1] = '0' + x;
else text[i + y - j - 1] = 'A' + x - 10;
//printf("%c ",text[i + j]);
}
text[i + y ] = '\0';
}
void print(char text[]) {
for (int i = 0; ; i++) {
if (text[i] == '\0') break;
printf("%c", text[i]);
}
}
在實現translate函數時,我們又用到了這個一個10進制的數在16進制下的位數。遇到這樣一個問題時不急,我們先擱置,繼續完成爲剩下的部分。然後再轉過頭來實現這個新的函數len。
int len(int n) {
if (n == 0) return 1;
int count = 0;
while (n != 0) {
n = n / 16;
count++;
}
return count;
}
至此,這道題終於完成了,代碼具有很高的可讀性,而且我們完成題目的過程中思路也很清晰,不至於出現碼着碼着忘了自己要幹嘛的情況。這就是“自頂向下,逐步求精”的代碼思路了。怎麼樣,您學會了嗎?