Re: [閒聊] 尋求比nest-if更優美的解決辦法
※ 引述《yauhh (喲)》之銘言:
: ※ 引述《wowtiger (小虎)》之銘言:
: : 兩三年前會用這個怪格式寫 XD
: : (data == NULL) ? printf("Data not found."):
: : (checkData(data) != 0) ? printf("Data is invaild."):
: : (modifyData(data) != 0) ? printf("Data modification failed."):
: : (fireDataChanged(data) != 0) ? printf("Observer call failed."):
: : (saveDataIntoFile(data) != 0) ? printf("Data storage failed."):
: : /* success */ ? printf("Finally succeed...");
: : 不過後來發現很多人看不懂就沒用了
: : code 還是簡單明瞭最好
: 當然善用shortcut-circuit evaluation寫邏輯句子很容易:
: (data == NULL) && printf("Data not found.")
: || (checkData(data) != 0) && printf("Data is invaild.")
: || (modifyData(data) != 0) && printf("Data modification failed.")
: || (fireDataChanged(data) != 0) && printf("Observer call failed.")
: || (saveDataIntoFile(data) != 0) && printf("Data storage failed.")
: || printf("Finally succeed...");
: 邏輯運算一般是 && 優先權高於 ||.
: 使用 ? : 還可以把stage埋進去,或者把部份處理完的資料傳回來.
: 至於看起來是不是簡單明瞭,邏輯句基本上是最簡單明瞭的,
: 看不懂這種句子的人是自己基礎學科沒有學好.
就是要回你這篇!
什麼叫做「會」一個語言?Noam Chomsky認為應該具有語言
知識或語言能力,也就是對語言結構規律的掌握,有人將之
稱為「語感」。有興趣可以參考「當代語言學概論」
if-else →「若狀態為..則作什麼事」你想從不同的角度去
解讀他也是可以,不過我想既然大家都有約定俗
成的觀念,你在小括號裡放某個函式呼叫,把要
做的事全擺在裡面,雖然標新立異,但是「語感
」很差。
當然 ?: 也是同樣的道理,所有需要判定真偽的敘述,都應
該只被用來做狀態的判定而不是主要的演算法部分。
編譯器會讓你過就表示你可以這樣寫?其實錯了!我之前也
提倡過學程式語言應該用學自然語言的態度去對待,因為如
果只是為了跟機器溝通,大可以不用搞那麼多奇奇怪怪的關
鍵字(for、goto),因為他正是人與人交流的工具。
你能掌握這樣的語法,實屬可嘉;但是你可以用非常漂亮罵
人婊子不帶髒字的話在婚禮上對新娘說,表示語言能力還有
待加強。
能夠達成目的的程式碼有百百種,每個人各有所好。不過需
要像小說一樣,讓人花錢花時間,看得到作者的用心、精采
的劇情、嘆為觀止的文筆。賣座的作品無一不是如此,他們
絕不是語言學家,卻通俗的連阿嬷都會掏腰包來買。
再快的演算法都沒用,再簡短的碼也不是辦法。只要肯用心
、用愛灌溉你的程式,它絕對不是中了T病毒的行屍走肉而
已,它也會有靈魂,有自己的故事..
「我看到一個空殼」
──────────────────────────
既然你都專程寄站內信給我了,我也認真來回一下,關於第
#1C_ECk7k 那篇
: 像這個情況可以整理一下:
: int check = 0;
: check += (data != NULL)? 0: 16;
: check += (checkData(data) == 0)? 0: 8;
: check += (modifyData(data) == 0)? 0: 4;
: check += (fireDataChanged(data) == 0)? 0: 2;
: check += (saveDataIntoFile(data) == 0)? 0: 1;
: if (check >= 16)
: printf("No data.\n");
: else if (check >= 8)
: printf("Data invalid.\n");
: else if (check >= 4)
: printf("Data modification failed.\n");
: else if (check >= 2)
: printf("Observer call failed.\n");
: else if (check >= 1)
: printf("Data storing failed.\n");
: else
: printf("Eventually work is done.\n");
單就執行順序來看,是從 checkData → saveDataIntoFile
沒錯,不過原PO要的是「當checkData執行錯誤時,不執行
modifyData」,而你這是全部跑完才最後算一次總帳,不太
對喔!
: 不過看起來也是寫太長,不怎麼好.
: 或者是先有一些函數像這樣:
: string null(string data) {
: if (data == "#nil" || data == NULL) {
: printf("No data.\n");
: return "#nil";
: }
: return data;
: }
: string check(string data) {
: if (data == "#nil") {
: return "#nil";
: }
: string result = data;
: ... //checking
: if (result == "#bad") {
: printf("Data invalid.\n");
: return "#nil";
: }
: return result;
: }
: string modify(string data) {
: if (data == "#nil") {
: return "#nil";
: }
: string result = data;
: ... //modifying
: if (result == "#bad") {
: printf("Data modification failed.\n");
: return "#nil";
: }
: return result;
: }
: string fireChangedEvent(string data) {
: if (data == "#nil") {
: return "#nil";
: }
: string result = data;
: ... //fire event and check response or status
: if (result == "#bad") {
: printf("Data observer call failed.\n");
: return "#nil";
: }
: return result;
: }
: string saveFile(string data) {
: if (data == "#nil") {
: return "#nil";
: }
: string result = data;
: ... //save and check saving status
: if (result == "#bad") {
: printf("Process failed when storing data.\n");
: return "#nil";
: }
: return result;
: }
: string complete(string data) {
: if (data != "#nil") {
: printf("Eventualy work is done.\n");
: }
: return data;
: }
: 然後你要的程式就變成:
: string result =
: complete(saveFile(fireChangedEvent(modify(check(null(data))))));
: 不過這樣有點癟腳之處,是通常是比較想要拿到部份處理完的的結果.
: 例如,經過modify卻無法fireChangedEvent的資料.
: 傳遞過程基本是傳遞信號,同樣一個簡單的傳回值,就沒辦法傳出片斷完成的資料了.
: 而如果包裝成struct,包含信號與資料,就可以傳回片斷完成資料了.
這個就比較像衛句的寫法,先不論裡面頻繁的建構string物
件帶來的問題,但是「當checkData執行錯誤時,不執行mo-
difyData」這個語意你完全沒保留,因為即使中途發生錯誤
,你還是照常呼叫了下一支函式,只是都不做事而已。
另外關於 #1C_MBdo5 那篇
: (data == NULL) && printf("Data not found.")
: || (checkData(data) != 0) && printf("Data is invaild.")
: || (modifyData(data) != 0) && printf("Data modification failed.")
: || (fireDataChanged(data) != 0) && printf("Observer call failed.")
: || (saveDataIntoFile(data) != 0) && printf("Data storage failed.")
: || printf("Finally succeed...");
: 邏輯運算一般是 && 優先權高於 ||.
: 使用 ? : 還可以把stage埋進去,或者把部份處理完的資料傳回來.
: 至於看起來是不是簡單明瞭,邏輯句基本上是最簡單明瞭的,
: 看不懂這種句子的人是自己基礎學科沒有學好.
先大致看一下結構,「有&&、||」表示這邊應該是作「狀態
的檢驗」,而且最後面有一個分號,就意義上來說形同一個
沒有用的指令如 true;它在跟讀者說「我可以被忽略唷,請
你繼續往下看」。
不料他發現後面沒程式碼了,原來你整個演算法直接嵌到這
個敘述裡。
這段程式要這樣看:以&&連接起來的子句為單位,把它切成
六個部份(狀態檢查用黃色,其他動作指令用藍色):
檢查1 || 檢查2 || 檢查3 || 檢查4 || 檢查5 || 動作1
希望這麼簡單就好了,但它真正是長成這樣:
檢查1 || 檢查2 || 檢查3 || 檢查4 || 檢查5 || 動作1
不論程式的邏輯,讀者的腦袋必須做多次的Context Switch
才能理解你在作什麼,這樣破壞讀者的第一印象以及玩弄他
大腦的程式碼,你覺得他肯幫你維護的機率是多少?
你當然都有完成原PO想要的功能,但是你達到的僅僅是「功
能」,沒有包含讀者的觀感。我再重申:程式不是自己寫得
爽就好。希望你回覆不是為了洗文章數才對..
看程式碼真的看得出原作者有沒有用心去寫,是不是只專注
某種技巧的運用而忽略了知識傳承這一環。
--
◢████ ◢█ ◢██◣ ◢█ ◢███ ◢█ T-ara版怎麼去
████◤ ██ ◢██◣█ ██ ████ ██ s ~> T-ara
█/███ ██ ██ ██ █/█ ◢███ █/█ 歡迎您的光臨
████◤ ██ ██ ██ ██◤ ███◤ ██◤ 恩靜、智妍、孝敏
█/███ ██ █/██◤ ██ █/██ ██ 素妍、居麗、寶藍
████◤ █◤ ◥██◤ █◤ ████◤█◤ 花英 ψmakigoto123
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.121.197.115
推
12/08 00:17, , 1F
12/08 00:17, 1F
→
12/08 00:23, , 2F
12/08 00:23, 2F
推
12/08 00:28, , 3F
12/08 00:28, 3F
推
12/08 06:13, , 4F
12/08 06:13, 4F
→
12/08 06:14, , 5F
12/08 06:14, 5F
→
12/08 06:15, , 6F
12/08 06:15, 6F
→
12/08 06:16, , 7F
12/08 06:16, 7F
※ 編輯: loveme00835 來自: 140.121.197.115 (12/08 08:54)
推
12/08 09:10, , 8F
12/08 09:10, 8F
推
12/08 09:44, , 9F
12/08 09:44, 9F
→
12/08 10:36, , 10F
12/08 10:36, 10F
→
12/08 10:36, , 11F
12/08 10:36, 11F
→
12/08 10:37, , 12F
12/08 10:37, 12F
推
12/08 11:21, , 13F
12/08 11:21, 13F
→
12/08 11:32, , 14F
12/08 11:32, 14F
→
12/08 11:33, , 15F
12/08 11:33, 15F
→
12/08 11:35, , 16F
12/08 11:35, 16F
推
12/08 11:49, , 17F
12/08 11:49, 17F
→
12/08 11:49, , 18F
12/08 11:49, 18F
討論串 (同標題文章)
完整討論串 (本文為第 15 之 21 篇):