Re: [問題] swith_case 用法

看板C_and_CPP作者 (藍影)時間10年前發表 (2015/06/02 14:39), 10年前編輯推噓2(207)
留言9則, 4人參與, 最新討論串2/4 (看更多)
※ 引述《totemist (totem)》之銘言: <恕刪> : input是相同的512筆data : 經由case去選擇不同的處理方式 <恕刪> : 補充說明(Supplement): : 因為我是要做濾波器(fir filter - bandpass) : 我希望能給使用者自己選擇頻率(0~540hz,每60hz為一單位) : 所以我總共要做C10取2 有 45個case要做 <恕刪> : ex: : printf("enter A=100_500 or D=200_600 = "); : 就是直接給使用者看著指令選擇 : 但是我想做到的是給使用者自動輸入想要的頻寬 : 只是覺得這樣對使用者比較方便,不用把我45個代號看完就可以自動輸入這樣 對於敘述其實有點看不懂,因裡面算出來的數字我真沒辦法對上 Orz 0~540 , 每 60 hz 為一個單位 , 這樣只會切成 10 分, 為什麼後面多出了 C(10,2) = 45 個 conditions ? A=100_500 代表若輸入的是 'A', filter 範圍是 (100,500) D=200_600 代表若輸入的是 'D', filter 範圍是 (200,600) 以下的敘述猜測就是 Feis 所提的方法。 根據最後一段敘述,我假設你需要的是 要做45次判斷,依序執行相對應之函式, 那你倒是可以這麼做 const int iBoundCount = 45; const int iLowerBand[iBoundCount] = { 100,200,150,180,200, .... } ; const int iUpperBand[iBoundCount] = { 500.700.600.400.600. .... } ; iLowerBand 和 iUpperBand 可以用 struct stBand { int m_iLower , m_iUpper}; 這裡不贅述。另上面這些常數可以寫到檔案裡面去,程式初始化時從檔案讀出, 這裡也不贅述。值得注意的是,如果你的 Bound 範圍是有規律的,事實上,上面的表 可以不用建立,只是為了說明方便,我還是以建表方式說明。 再來是使用者輸入的時候,你可以讓使用者自己去輸入 lower bound 及 upper bound ,再去搜尋對應到的是哪一個 index int iUserLower , iUserUpper ; // 假設已拿到數值 int iSelIndex ; // 判斷輸入數值落在陣列裡的哪個區間。 for(iSelIndex = 0 ; iSelIndex < iBoundCount ; ++iSelIndex) if( iLowerBound[iSelIndex] == iUserLower && iUpperBound[iSelIndex] == iUserUpper ) break; if(iSelIndex == iBoundCount) { // 這裡是使用者輸入的值沒在兩個 array 找到 } else { // 這裡是使用者輸入的值剛好在 Lower[iSelIndex]/Upper[iSelIndex] } 換句話說,到這裡得到的 iSelIndex 會是 [ 0, iBoundCount ] 之連續整數。 如果硬要用 switch 寫的話還是可以,就變成了 switch(iSelIndex) { case 0 : func0() ; break; case 1 : func1() ; break; case 2 : func2() ; break; ... case 44 : func44() ; break; default : InputError(); break; // 這裡是 iSelIndex == 45 } 這樣看起來好像沒什麼改變對不對? 不對唷!關鍵是 iSelIndex 已經調整成 0~45, 它又可以拿來當陣列的索引值了,這時候就需要 函式指標陣列 了。 假設你的 function 每個都長得一樣,都是長成 void func(void) ; (長其他樣子也行, 重點是要長得一樣),上面的 switch 可被拿掉變成 typedef void (*pFilterFunc)(void) ; pFilterFunc pFuncAry[iBoundCount] = { func1 , func2 , func3 , func4 , func5 , ... , func45 }; if(iSelIndex != iBoundCount) // 別忘了剛剛的 iSelIndex 怎來的 { // User Input Error Process } else { pFuncAry[iSelIndex] () ; // 使用函式指標陣列進行呼叫函式 } 好了,你要的東西上面應該已經提供一套 solution 給你了,但其他更好的架構 方式,像是 struct { int iLowerBound ; int iUpperBound ; void (*pFilter)() ; }FilterInfo[] = { {100,200, func1}, {200,500, func2}, ... {150,700, func45} }; 資料結構和詳細作法我也不再贅述了,也只是上述的東西再包過而已。然後這是用 純 C 的刻法,另一種解法是 C++ template ,這個我也不贅述。 重點是…嗯…你可以先確認一下,知不知道什麼是函式指標,什麼是函式指標陣列。 不知道的話必須先補起來,才能討論比較簡潔、"好一點點" 的架構。 但.是 (如果沒有但是的話下面可以不用看了...) 但.是. 如果好死不死,那些 func1 , func2 的 prototype 長得不一樣的話呢? 像是 void func1(int, int) , double func2(double, int) , ... etc , 這裡其實我覺得還是直接用 45 個 switch-case 下去硬幹會比較方便, 走 C 風格的話還是可以用 函式指標陣列,只是所有函式必須改寫成 void func(void *) 或是 int func( void *) ,至於 C++ 有沒有比較好的解法? 嗯,我想是有的,只是我也沒用過,也想知道。 -- YouLoveMe() ? LetItBe() : LetMeFree(); -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 123.195.169.158 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1433255961.A.7DA.html ※ 編輯: tropical72 (123.195.169.158), 06/02/2015 22:45:16

06/02 22:48, , 1F
好久沒看到這帳號
06/02 22:48, 1F

06/02 22:49, , 2F
我也好久沒看到 loveme~ 發言了 Orz
06/02 22:49, 2F

06/02 23:05, , 3F
我沒猜錯的話, 他不同的範圍只是選不同的陣列.
06/02 23:05, 3F

06/02 23:05, , 4F
所以還用不上函式指標陣列 Orz
06/02 23:05, 4F

06/02 23:08, , 5F
啊!好吧, 我又發廢文了 Orz
06/02 23:08, 5F

06/03 00:04, , 6F
感謝T大分享想法~ 我會好好從中學習,因為我C不強,就
06/03 00:04, 6F

06/03 00:05, , 7F
是邊做邊學這樣。
06/03 00:05, 7F

06/03 00:09, , 8F
抱歉我在敘述上可能沒有講得很明確仔細,不過真的很感謝
06/03 00:09, 8F

06/03 00:10, , 9F
T大寫了這篇文章,絕對不會是廢文~ 原文我也有再修過了
06/03 00:10, 9F
文章代碼(AID): #1LRS0PVQ (C_and_CPP)
討論串 (同標題文章)
以下文章回應了本文 (最舊先):
問題
3
9
完整討論串 (本文為第 2 之 4 篇):
問題
3
9
問題
4
16
文章代碼(AID): #1LRS0PVQ (C_and_CPP)