作者loveme00835 (最愛朴素妍)
看板C_and_CPP
標題Re: [閒聊] 尋求比nest-if更優美的解決辦法
時間Wed Dec 8 00:14:55 2010
※ 引述《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
推 purpose:保必 12/08 00:17
→ loveme00835:樓上也知道那首!! 感動阿~~ Orz.. 12/08 00:23
推 purpose:就是最近常有人討論這首,才終於看懂love大的簽名檔 12/08 00:28
推 yauhh:是啊,我那樣寫明明就語感還不錯,不懂你在講什麼. 12/08 06:13
→ yauhh:而電腦程式語言,你把它講成人與人交流的工具,未免延伸太多了 12/08 06:14
→ yauhh:我覺得你想講一個小點,結果整篇扯到很無關的道理,也沒意義 12/08 06:15
→ yauhh:所以,就這樣一篇來看,我也看到一個空殼子喔 12/08 06:16
※ 編輯: loveme00835 來自: 140.121.197.115 (12/08 08:54)
推 purpose:好激烈的對話 XD 12/08 09:10
推 sandr1983:讚,因為我之前也看到這樣的程式碼,差點昏倒... 12/08 09:44
→ yoco315:你白癡喔?每個初學者都可以寫出給compiler看的程式碼 12/08 10:36
→ yoco315:但是寫出給人看的程式碼才是高手跟低能兒的差別 =,= 12/08 10:36
→ yoco315:都寫這麼久程式了講話卻還是真智障一樣 -_____- 12/08 10:37
推 ledia:yoco 大, 認真就輸了, be care of your wording ... 囧 12/08 11:21
→ yoco315:這樣他才會有快感啦,他就是故意來討罵的才會發這些文 12/08 11:32
→ yoco315:不然你們還真的以為他是白痴嗎,當然不是.. 12/08 11:33
→ yoco315:對了我發現你是文瀚的同學耶 XD 我現在跟他當同事 XD 12/08 11:35
推 ledia:被認出來了我應該要 >////< 嗎? XD 12/08 11:49
→ loveme00835:@_@! 12/08 11:49