語言的使用,會訓練並影嚮我們的思考方式。在電腦程式語言中,特別突顯這個現象
有人拿著一道程式語言的題目來問我如何解?我想了一下解法,再看了一下他原來的解法,發現語言的使用,會訓練並影嚮我們的思考方式。在電腦程式語言中,特別突顯這個現象。例如,一個熟悉組合語言的人 (例如我),在處理下面這個問題時,就算同樣用 C 語言,他的答案就和一個不曾使用過組合語言的人 (我朋友) 完全不同。
問題: 將10進位數字表示文字轉換成16進位數字表示文字。例: 輸入 255 ,輸出 0xFF 。讓我們看看一個用過組合語言的人,是如何寫出答案 (就是我寫的)。
/* C Language */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char**argv) {
int n;
int bytes, len, f, r;
char HEX[256], *pHEX;
const char *HEX_TABLE = "0123456789ABCDEF";
/*
本例只換算32bit整數。
透過適當的字串轉數值的動作,下面的方式經過簡單地
套上另一個迴圈後,可以處理無限大的數字。
(字串轉換後的數值,放在 int 陣列中,並回傳總 bytes 。)
*/
if (argc < 2) {
printf("Usage: %s octNumber\n", argv[0]);
exit(1);
}
sscanf(argv[1], "%d", &n);
printf("Input: %d\n", n);
bytes = size_t(n);
for (pHEX = HEX, len = 0; n && len < bytes; ++len, ++pHEX, n = n >> 4 ) {
*pHEX = HEX_TABLE[n & 0xF];
}
*pHEX = '\0';
/* 現在儲存的字串,是倒過來表示的,接下來將頭尾對調。 */
len = strlen(HEX);
for( f = 0, r = len -1; f < (len/2); f++, r--) {
HEX[f] ^= HEX[r]; /*swap HEX[f], HEX[r] */
HEX[r] ^= HEX[f];
HEX[f] ^= HEX[r];
}
printf("Output: 0x%s\n", HEX);
/*END*/
}
我是直接用遮罩的方式,再查表取字,以位元運算為主,這是組合語言式的正統做法。而我朋友是用數學換算,那似乎是數學式的正統做法。從計算機原理來看,我的方法最佳。在此無意說明計算機原理,僅討論語言與思維方式。兩種方法毫無疑問地都是邏輯結構 (不論數學或是電腦程式語言,這是語言本身的限定) ,但符號型式卻相差很大,這是因為語言使用上的特性,訓練並影嚮了我們的思維。
組合語言的使用,訓練了我對16進位數值與位元運算的思考習慣。一般數學,並不是這樣教人演算的。以前還有個數學研究所的人,問過我「超長整數」 (超過 unsigned long long 範圍的數) 相加的 C 語言程式怎麼寫。我一看他的構想就知道他還沒擺脫數學思考,我告訴他這不能直接用數值 (內建數值型態) 去做,要用字串儲存數,一字元對一字元地相加與進位。其實用過組合語言的話,非常快就想通了 (用組合語言寫更快)。
我數學不好,所以有個怪僻,只要有人拿什麼函數模型來請我幫他寫出電腦程式,我就會要他先把模型中的所有運算過程 (特別是微積分的) ,全部轉成只有加減乘除及邏輯運算的型式 (連指數、對數都不能用) ,我才能幫他寫程式。幾乎每個人都被這要求打退堂鼓。我數學不好,不了解原因。有任何數學好的人,可以告訴我這要求很難做到嗎?
樂多舊回應