回覆列表
  • 1 # 使用者8247884274131

    C 語言發明的時間很早,當時人們對"型別系統" 還很陌生,很多人還習慣將二進位制位元組作為唯一的資料型別。設計 C 語言的語法時,也不知是誰想出來的,有種設計哲學:讓宣告的形式與它的使用形式儘可能相似。在這種設計哲學下,是先想如何使用,再來逆推如何宣告,這樣 C 語言的宣告語法顯得有點古怪,

    比如:

    宣告 int a; 使用時,a 的型別就是 int。宣告指標 int *b; 使用時,*b 的型別就是 int。宣告陣列 int b[10]; 使用時用 b[0]; 定義函式指標,int (*ptr)(int a, int b); 使用時,就是 (*ptr)(a, b); 可以簡寫成 ptr(a, b);

    C 這種語法設計,在今天看來是不好。使用這種語法,程式設計師不可以直接從左往右讀,有時甚至需要從中間往兩邊讀。只是 C 語言的影響太大,人們常見類 C 的語法,C 語言有些不好的地方也就忍了。C++ 就繼承了這種語法,甚至這種語法的設計哲學,反正我總記不住成員函式指標是怎麼宣告的。

    到今天,人們對“型別系統" 很熟悉了,也積累了幾十年的語言使用經驗。現在設計的語言,語法上傾向將型別放到後面,而並非放到前面。這樣比較統一,也可以從左往右讀。比如

    對比 C 語法

    特別最後一個型別,沒有什麼人可以一眼可以看出它的含義(我懷疑已經寫錯了)。這種情況,在 C 中會用 typedef 來簡化。

    -----------------

    語言有型別推導,很多時候不用顯式寫型別。型別放在前面或者後面,對基本的資料型別影響還不算大。只是對複合型別,特別是函式(或者類似概念),語法上還是有影響的。怎麼從語法上表示一個函式呢?使用前置型別,從語法上,大致可以寫成:

    你也可以去掉括號,寫成,

    規定前面是引數型別,最後的是返回型別。但這種方式,從形式上是看不出那些是返回值,那些是引數。

    你很難去掉這個 Func 的記號,去掉會引起歧義。更進一步,怎麼去表示一個函式,它傳入一個函式作為引數,而返回一個函式呢?大致為:

    這種語法,就會引起 Func 的巢狀,而 Func 純粹多餘。

    更進一步,我增強了語言,可以支援多返回值。按照 C 的語法方式,大致定義成:

    那怎麼表示這種函式型別呢。你可以寫成:

    那再繼續,怎麼表示這種,定義一個函式,傳入一個多返回值的函式作為引數,而再次返回一個多返回值的函式作為引數。這樣,不單單是 Func 會引起巢狀,連那些括號也會引起巢狀,而這些是語法噪音。為避免巢狀,語言中就會傾向於先定義某個型別,比如

    型別寫在後面,可以輕易地去掉 Func 噪音。比如

    並且它的形式並非是巢狀的,而是一個線狀,並且可以統一地連鎖下去。

    另外還有更具價值觀的解釋,程式設計時更應該關注變數用途,而不是變數的型別。變數的名字反應了用途,既然用途比型別更重要,名字就應該放在最開始。當然這種解釋見仁見智,有點站不住腳。

  • 中秋節和大豐收的關聯?
  • 戶外爬山怎麼控制自己的行走節奏?