Re: [問題] 請教有無方法簡化我的code

看板C_and_CPP作者 (最愛朴素妍)時間13年前 (2010/10/05 10:01), 編輯推噓13(13045)
留言58則, 6人參與, 最新討論串3/5 (看更多)
※ 引述《chessjim (jim)》之銘言: : ( *[1m *[m 為色碼,可以按 Ctrl+V 預覽會顯示的顏色 ) : ( 未必需要依照此格式,文章條理清楚即可 ) : 遇到的問題: (題意請描述清楚) : 我寫了一段code : 發現code中重複的地方很多 : 不知道有沒有方法簡化它 : 希望得到的正確結果: : 能夠簡化我case1,case2,case3中的code : 因為重複的地方很多 : 我的code片段如下 : //pre:level,type分別控制三角形層級與種類 : //post:印出三角形 : void printTriangle(int level,int type){ : int line,cnt; : switch(type){ : case 1: : for(line=1;line<=level;line++){ : for(cnt=1;cnt<=line;cnt++){ : printf("1"); : }//end for-cnt : printf("\n"); : }//end for-line : break; : case 2: : for(line=1;line<=level;line++){ : for(cnt=1;cnt<=line;cnt++){ : printf("%d",cnt); : }//end for-cnt : printf("\n"); : }//end for-line : break; : case 3: : for(line=1;line<=level;line++){ : for(cnt=1;cnt<=line;cnt++){ : printf("%d",line); : }//end for-cnt : printf("\n"); : }//end for-line : break; : default: : printf("你輸入了錯誤的三角形種類!!"); : break; : }//enf switch : }//end 出現type code了, 首先需要做的就是把 int type這個參數 換成列舉型態, 提升可讀性並且也提供靜態型別檢查, 不用 呼叫之後才用default去檢查合法與否(雖然我還想不到這三 種三角形該怎麼敘述他). http://codepad.org/MCGDiB5G 裡面三個巢狀迴圈可以分開寫成不同函式, 並且使用清楚的 名稱去命名它們 : http://codepad.org/IL2Kb3by 再來就是 switch 的問題, 如果新增了一種三角形, 這邊是 一定要改的, 所以可以用函數指標陣列, 利用列舉值當索引 來選擇呼叫特定的函式, 這樣要新增也比較方便 : http://codepad.org/whCDsD8u 以上, 簡化多少不是問題, 能不能讓你未來能少打一點程式 碼, 以及程式好不好加入新功能, 才是最重要的. -- ◢████ ◢█ ◢██◣ ◢█ ◢███ ◢█ T-ara版怎麼去 ████◢█████s ~> T-ara ███ █ ◢█歡迎您的光臨 ███████████恩靜智妍孝敏 ███ ██ 素妍居麗寶藍 ████◥██◤ █████ψmakigoto123 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.121.197.115 ※ 編輯: loveme00835 來自: 140.121.197.115 (10/05 10:08)

10/05 10:11, , 1F
三個巢狀迴圈可以寫成一個函式吧
10/05 10:11, 1F

10/05 10:19, , 2F
強者的見解就是不一樣 獲益良多
10/05 10:19, 2F

10/05 12:24, , 3F
推love大
10/05 12:24, 3F

10/05 12:38, , 4F
三個"不同功能"的部分寫在一起, 這是很常見的"責任分
10/05 12:38, 4F

10/05 12:39, , 5F
配不均" 的行為, 會造成擴充不易, 且會有if switch的
10/05 12:39, 5F

10/05 12:40, , 6F
結構重複出現
10/05 12:40, 6F

10/05 12:41, , 7F
同一樓,我也覺得巢狀迴圈應該在switch-case的外面
10/05 12:41, 7F

10/05 12:42, , 8F
這三個三角形「不同」的部份只有印出來的東西不一樣
10/05 12:42, 8F

10/05 12:42, , 9F
你在抽取函式的時侯應該把同功能的部份保留,只抽取不同
10/05 12:42, 9F

10/05 12:42, , 10F
功能的部份 不然會造成redundant code反而維護不易
10/05 12:42, 10F

10/05 12:45, , 11F
可是如果要改動這裡印出的數字的規則, 迴圈裏面就會變
10/05 12:45, 11F

10/05 12:45, , 12F
的更複雜
10/05 12:45, 12F

10/05 12:46, , 13F
在改程式碼的時候也沒辦法分開來做, 假如是別的使用者
10/05 12:46, 13F

10/05 12:47, , 14F
勢必要動到你的原始碼
10/05 12:47, 14F

10/05 12:51, , 15F
不會更複雜啊 只是把三個function合成一個來寫
10/05 12:51, 15F

10/05 12:51, , 16F
假如你有第四種三角形 而且它的形狀真的不一樣而不是只
10/05 12:51, 16F

10/05 12:52, , 17F
有印出來的東西不一樣的話,才需要再寫另一個函式...
10/05 12:52, 17F

10/05 12:56, , 18F
我就是說樓上這種情形, 加上一個倒三角就變成兩個函式
10/05 12:56, 18F

10/05 12:58, , 19F
就算有倒三角的需求,也應該要把三個正三角的寫成一個函
10/05 12:58, 19F

10/05 12:58, , 20F
式啊...
10/05 12:58, 20F

10/05 13:02, , 21F
然後client端因為相依於這樣的改變, 選擇的地方又要作
10/05 13:02, 21F

10/05 13:03, , 22F
改動, 你著重在邏輯簡化, 我著重在擴充上 0.0
10/05 13:03, 22F

10/05 13:03, , 23F
學到很多重要觀念,大謝
10/05 13:03, 23F

10/05 13:04, , 24F
選擇的地方不用改動吧 是printTriangle要傳兩個參數進去
10/05 13:04, 24F

10/05 13:05, , 25F
啊…我不是說你的printTriangle 我是說三個合成一個之後
10/05 13:05, 25F

10/05 13:05, , 26F
要傳兩個參數 然後該函式在迴圈裡判斷要印什麼東西
10/05 13:05, 26F

10/05 13:06, , 27F
加上倒三角之後, 本來從三選一變四選一的地方啦~
10/05 13:06, 27F

10/05 13:07, , 28F
對啊 那裡不用動啊= = 是你的三個函式要合成一個啊
10/05 13:07, 28F

10/05 13:10, , 29F
吼~ :( 我知道你說三個合成一個的地方, 就是上篇推文
10/05 13:10, 29F

10/05 13:10, , 30F
中的程式碼, 我是指加上新三角之後, 就要做兩種函式的
10/05 13:10, 30F

10/05 13:11, , 31F
切換, 加入新的正三角數字規則, 就要改變本來的三合一
10/05 13:11, 31F

10/05 13:12, , 32F
函式, 然後切換函式的地方會變得複雜
10/05 13:12, 32F

10/05 13:12, , 33F
不用啊= = 本來三合一的函式不用改 再加一個新函式就好
10/05 13:12, 33F

10/05 13:12, , 34F
一樣在你選函式的地方加上另一個case呼叫新的函式而已
10/05 13:12, 34F

10/05 13:13, , 35F
就是加入新的函式, 就要if(type= 1 ~ 3 )呼叫三合一
10/05 13:13, 35F

10/05 13:14, , 36F
if(case=3) 呼叫新函式, 但是如果新的三角形是使用者
10/05 13:14, 36F

10/05 13:15, , 37F
自己想加的話, 他就還要改到這個印出的函式, 或是還要
10/05 13:15, 37F

10/05 13:15, , 38F
再包一層, 不是很麻煩嗎?
10/05 13:15, 38F

10/05 13:15, , 39F
第 2 個 if 打錯 = =
10/05 13:15, 39F

10/05 13:16, , 40F
不用改印出的函式 只要再加一個新的函式就好....
10/05 13:16, 40F

10/05 13:16, , 41F
原本的三個函式大部份的功能相同就該寫成一個 新加的函
10/05 13:16, 41F

10/05 13:16, , 42F
式如果沒辦法共用原本的功能就再寫另一個而已 這邏輯沒
10/05 13:16, 42F

10/05 13:16, , 43F
有很複雜吧..
10/05 13:16, 43F

10/05 13:18, , 44F
我知道你說的阿= =, 想想寫選擇的函式跟加新三角形的
10/05 13:18, 44F

10/05 13:18, , 45F
作者是不同人的情況, 為了讓他的三角形你的選擇函式要
10/05 13:18, 45F

10/05 13:19, , 46F
多一個case, 然後多一堆稀奇古怪的圖形, 就更多case,
10/05 13:19, 46F

10/05 13:20, , 47F
這樣就顯示不出來當初三合一的好處了
10/05 13:20, 47F

10/05 13:20, , 48F
那不就是你的printTriangle函式在做的事嗎XD 我沒有反對
10/05 13:20, 48F

10/05 13:20, , 49F
這塊啊
10/05 13:20, 49F

10/05 13:20, , 50F
我說的是你的printOne Two Three應該要合成一個
10/05 13:20, 50F

10/05 13:21, , 51F
可以合阿~ 只不過不這樣分很清楚的話比較不能突顯這
10/05 13:21, 51F

10/05 13:22, , 52F
個方法的用途
10/05 13:22, 52F

10/05 13:22, , 53F
寫法本來就很多,像遊戲外掛被封鎖,換個寫法又是活龍
10/05 13:22, 53F

10/05 13:28, , 54F
只不過我習慣上還是會分開寫啦, 再加上函式名稱說明
10/05 13:28, 54F

10/05 13:29, , 55F
各種不同三角形的特徵, 如果這邊用的是繼承 + 多型,很
10/05 13:29, 55F

10/05 13:29, , 56F
容易看出分開寫優點
10/05 13:29, 56F

10/05 13:32, , 57F
另外發現一點: 三合一函式相依於 type 的實際值, 假如
10/05 13:32, 57F

10/05 13:33, , 58F
這個數值分佈有需要變動, 三合一的部份就要改寫
10/05 13:33, 58F
※ 編輯: loveme00835 來自: 140.121.197.115 (10/05 13:38)
文章代碼(AID): #1CgeRubc (C_and_CPP)
討論串 (同標題文章)
文章代碼(AID): #1CgeRubc (C_and_CPP)