Fw: [問卦] C語言最難的部分是哪一個
※ [本文轉錄自 Gossiping 看板 #1SFuJUH6 ]
作者: jserv (松鼠) 看板: Gossiping
標題: Re: [問卦] C語言最難的部分是哪一個
時間: Thu Jan 17 03:24:08 2019
※ 引述《yuponkimo (皇甫尊)》之銘言:
: 內葛,
(學期即將結束,我終於有空上來發廢文了)
葛,是豆科多年生草本植物,莖長二、三丈,纏繞他物上,花紫紅色。用途多樣,
莖可編籃做繩,纖維可織葛布。根可提製澱粉,又供藥用。葛根,能解饑退熱,
治高血壓、頸項強痛、冠心病等。
《詩經.國風.周南.葛覃》開頭寫道「葛之覃兮,施于中谷,維葉萋萋」,意思是
長長的葛藤生長,蔓延到谷中,伴隨著茂盛的葉子。兄台用「葛」來點題,訴說 C
語言近 50 年歷久彌新的發展,實在高竿啊!
: 我自己覺得是Linked list啦,
: 射來射去的豆頁真的疼,
: 花了好長時間才寫出一題來,
: 好好的structure為什麼要再加上指到自己的指標呢?
這裡又用「豆」提醒大家,「葛」屬於豆科,用心良苦。
Linux 核心之父 Linus Torvalds 在 TED 2016 的訪談 [1] 中,用 linked list 程式碼
作為解說「程式設計的品味」,在有限的訪談中,Linus 不去解釋程式碼的運作,而僅用
程式碼的長度變化,讓會眾體驗到「一個目的有著多條路徑,但我們該如何取捨呢?」,
我想,這也是 C 語言程式設計中,最為困難的地方,也就是「品味」。
考慮以下自給定的 linked list 中刪去特定節點的程式碼: (佔用 10 行)
void remove_list_node(List *list, Node *target) {
Node *prev = NULL;
Node *current = list->head;
while (current != target) {
prev = current;
current = current->next;
}
if (!prev)
list->head = target->next;
else
prev->next = target->next;
}
但 Linus 說,其實可改寫為以下功能一致,但更有「品味」的實作: (僅用 4 行)
void remove_list_node(List *list, Node *target) {
Node **indirect = &list->head;
while (*indirect != target)
indirect = &(*indirect)->next;
*indirect = target->next;
}
上述程式碼從「要更新什麼位置的資料」思考,無論是 head 或者非 head,更新的是
同一類型的資料,不用特別操作,自然省下額外的處理。
也許你會好奇,那麼新增節點的程式碼是否也可運用類似技巧呢?當然可以!請見以下:
void insert_list_node(List **head, int val) {
while (*head) {
head = &((*head)->next);
}
*head = calloc(1, sizeof(List));
(*head)->val = val;
}
要掌握這樣的「品味」之前,務必先征服 C 罩杯。依據 Wikipedia 的解說 [2]:
> 根據製造商的不同,版型可能有所不同因而穿著效果上有所差異。
> 罩杯尺寸大致是下列公式換算可得知:罩杯尺寸 = 上胸圍 - 下胸圍
上述「上圍」和「下圍」就對應到 C 語言規格的 data type,而在 C 語言中基礎運算
型態和對應修飾字均有資料範圍規範,千萬不要小看數值範圍對程式設計的影響,傾家
蕩產或國破家亡都有可能。
1996 年 6 月 4 日,在風和日麗的法屬蓋亞那太空中心 (法文: Centre Spatial
Guyanais),歐洲太空總署發射了一艘名為 Ariane 5 的火箭,預計運送 4 顆太陽風觀察
衛星到軌道。火箭本身加上載運的人造衛星及科學儀器值 USD 7.5 billion (台幣約2250
億)。Ariane 名稱來源於神話人物阿麗雅杜妮 (Ariadne) 的法語拼寫。
在當時,Ariane 系列火箭承包了全球商業衛星的發射約 50% 的業務量,而人們萬萬沒想
到,Ariane 5 發射後 37 秒,升空到 4 公里處,火箭偏離預定飛行軌跡,解體並爆炸,
2 名法國士兵當場死亡。
失事調查報告指出:水平加速偵測儀傳了一個 64-bit 浮點數給電腦,但飛行電腦用
16-bit 有號整數來接受這個浮點數,很不巧傳來的數字大於 32767,發生溢位 (Overflow)
例外,這樣的軟體設計缺失很常見,但對 Ariane 5 來說,下場竟是火箭的推進向量噴嘴
忽然朝某個方向轉到底,在高速偏航後,最終火箭解體。
開發 Ariane 5 火箭的軟體工程師在前一代 Ariane 4 中,小心翼翼地確認數值分佈,
確保水平速率的數值絕不會超過 16-bit 表達範圍以外。這些工程師在 Ariane 5 系統
沿用這段程式碼,卻沒有檢查前述假設是否符合新的設計。
上述 Ariane 5 火箭事故對應的展示用 C 語言程式如下:
void show_info(double d, int16_t n) {
n = (int16_t) d;
printf("d = %f, n = %d \n", d, n);
}
int main() {
double d1 = 32767.0, d2 = 32768.0;
int16_t n = 0;
show_info(d1, n); show_info(d2, n);
return(0);
}
第 1 個輸出是 n = 32767; 第 2 個輸出則是 n = -32768
差之毫釐,失之千里!
更多這類軟體缺失造成巨大危害的案例可見 [3],問題的根源竟然是「沒掌握好罩杯」,
你說,是不是該誠實面對自己,學好數值系統呢?可參照線上講座 [4]
回到之前提及的 linked list,這不全然是資料結構相關議題,在真實世界中,我們還要
討論這類非連續記憶體的資料操作效率和正確性,尤其是 Throughput (吞吐量; 單位時
間內可處理多少的資料量) 和 Scalability (擴展性; 隨著硬體資源的投入,可處理越來
越多的資料或工作時的能力或潛力),相當值得大書特書,可參見線上講座 [5] [6]。
歡迎關注「你所不知道的 C 語言」系列講座: http://hackfoldr.org/dykc/
[1] https://www.ted.com/talks/linus_torvalds_the_mind_behind_linux
Linus 在 2001 年之後幾乎就沒有公開演講,只接受訪談對話形式,這次在 TED
竟然出動了 TED 總監 Chris Anderson 來訪談,可能是頭一遭
[2] https://zh.wikipedia.org/wiki/%E7%BD%A9%E6%9D%AF
[3] https://hackmd.io/s/B1eo44C1-
[4] https://hackmd.io/s/BkRKhQGae
[5] https://hackmd.io/s/SkE33UTHf
[6] https://hackmd.io/s/H19V4eyfV
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 140.116.82.61
※ 文章網址: https://www.ptt.cc/bbs/Gossiping/M.1547666654.A.446.html
推
01/17 03:24,
5年前
, 1F
01/17 03:24, 1F
推
01/17 03:26,
5年前
, 2F
01/17 03:26, 2F
推
01/17 03:27,
5年前
, 3F
01/17 03:27, 3F
推
01/17 03:27,
5年前
, 4F
01/17 03:27, 4F
推
01/17 03:27,
5年前
, 5F
01/17 03:27, 5F
推
01/17 03:28,
5年前
, 6F
01/17 03:28, 6F
推
01/17 03:28,
5年前
, 7F
01/17 03:28, 7F
推
01/17 03:28,
5年前
, 8F
01/17 03:28, 8F
推
01/17 03:29,
5年前
, 9F
01/17 03:29, 9F
噓
01/17 03:31,
5年前
, 10F
01/17 03:31, 10F
推
01/17 03:31,
5年前
, 11F
01/17 03:31, 11F
→
01/17 03:31,
5年前
, 12F
01/17 03:31, 12F
推
01/17 03:32,
5年前
, 13F
01/17 03:32, 13F
推
01/17 03:33,
5年前
, 14F
01/17 03:33, 14F
推
01/17 03:33,
5年前
, 15F
01/17 03:33, 15F
推
01/17 03:33,
5年前
, 16F
01/17 03:33, 16F
→
01/17 03:35,
5年前
, 17F
01/17 03:35, 17F
推
01/17 03:36,
5年前
, 18F
01/17 03:36, 18F
→
01/17 03:36,
5年前
, 19F
01/17 03:36, 19F
→
01/17 03:37,
5年前
, 20F
01/17 03:37, 20F
推
01/17 03:38,
5年前
, 21F
01/17 03:38, 21F
推
01/17 03:38,
5年前
, 22F
01/17 03:38, 22F
→
01/17 03:40,
5年前
, 23F
01/17 03:40, 23F
推
01/17 03:42,
5年前
, 24F
01/17 03:42, 24F
推
01/17 03:42,
5年前
, 25F
01/17 03:42, 25F
推
01/17 03:43,
5年前
, 26F
01/17 03:43, 26F
→
01/17 03:44,
5年前
, 27F
01/17 03:44, 27F
推
01/17 03:53,
5年前
, 28F
01/17 03:53, 28F
推
01/17 03:54,
5年前
, 29F
01/17 03:54, 29F
→
01/17 03:58,
5年前
, 30F
01/17 03:58, 30F
推
01/17 04:00,
5年前
, 31F
01/17 04:00, 31F
推
01/17 04:02,
5年前
, 32F
01/17 04:02, 32F
推
01/17 04:03,
5年前
, 33F
01/17 04:03, 33F
→
01/17 04:07,
5年前
, 34F
01/17 04:07, 34F
→
01/17 04:08,
5年前
, 35F
01/17 04:08, 35F
推
01/17 04:08,
5年前
, 36F
01/17 04:08, 36F
→
01/17 04:08,
5年前
, 37F
01/17 04:08, 37F
推
01/17 04:09,
5年前
, 38F
01/17 04:09, 38F
→
01/17 04:09,
5年前
, 39F
01/17 04:09, 39F
還有 118 則推文
推
01/17 10:31,
5年前
, 158F
01/17 10:31, 158F
推
01/17 10:31,
5年前
, 159F
01/17 10:31, 159F
→
01/17 10:33,
5年前
, 160F
01/17 10:33, 160F
推
01/17 10:33,
5年前
, 161F
01/17 10:33, 161F
→
01/17 10:36,
5年前
, 162F
01/17 10:36, 162F
推
01/17 10:37,
5年前
, 163F
01/17 10:37, 163F
推
01/17 10:47,
5年前
, 164F
01/17 10:47, 164F
推
01/17 11:06,
5年前
, 165F
01/17 11:06, 165F
推
01/17 11:10,
5年前
, 166F
01/17 11:10, 166F
推
01/17 11:15,
5年前
, 167F
01/17 11:15, 167F
推
01/17 11:16,
5年前
, 168F
01/17 11:16, 168F
推
01/17 11:18,
5年前
, 169F
01/17 11:18, 169F
推
01/17 11:24,
5年前
, 170F
01/17 11:24, 170F
推
01/17 11:24,
5年前
, 171F
01/17 11:24, 171F
推
01/17 11:26,
5年前
, 172F
01/17 11:26, 172F
推
01/17 11:41,
5年前
, 173F
01/17 11:41, 173F
推
01/17 11:45,
5年前
, 174F
01/17 11:45, 174F
推
01/17 11:45,
5年前
, 175F
01/17 11:45, 175F
推
01/17 12:11,
5年前
, 176F
01/17 12:11, 176F
推
01/17 12:15,
5年前
, 177F
01/17 12:15, 177F
推
01/17 12:15,
5年前
, 178F
01/17 12:15, 178F
推
01/17 12:32,
5年前
, 179F
01/17 12:32, 179F
推
01/17 12:32,
5年前
, 180F
01/17 12:32, 180F
推
01/17 12:38,
5年前
, 181F
01/17 12:38, 181F
推
01/17 12:41,
5年前
, 182F
01/17 12:41, 182F
推
01/17 12:45,
5年前
, 183F
01/17 12:45, 183F
推
01/17 12:49,
5年前
, 184F
01/17 12:49, 184F
推
01/17 12:54,
5年前
, 185F
01/17 12:54, 185F
推
01/17 13:00,
5年前
, 186F
01/17 13:00, 186F
推
01/17 13:06,
5年前
, 187F
01/17 13:06, 187F
推
01/17 13:15,
5年前
, 188F
01/17 13:15, 188F
推
01/17 13:54,
5年前
, 189F
01/17 13:54, 189F
→
01/17 14:49,
5年前
, 190F
01/17 14:49, 190F
推
01/17 16:22,
5年前
, 191F
01/17 16:22, 191F
推
01/17 17:36,
5年前
, 192F
01/17 17:36, 192F
推
01/17 19:02,
5年前
, 193F
01/17 19:02, 193F
推
01/17 19:30,
5年前
, 194F
01/17 19:30, 194F
推
01/17 20:56,
5年前
, 195F
01/17 20:56, 195F
推
01/17 20:58,
5年前
, 196F
01/17 20:58, 196F
※ 發信站: 批踢踢實業坊(ptt.cc)
※ 轉錄者: okcool (1.171.52.12), 01/17/2019 21:20:29