Re: [问题] swith_case 用法

楼主: tropical72 (蓝影)   2015-06-02 22:39:12
※ 引述《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++ 有没有比较好的解法?
嗯,我想是有的,只是我也没用过,也想知道。
作者: loveme00835 (发箍)   2015-06-02 22:48:00
好久没看到这帐号
楼主: tropical72 (蓝影)   2015-06-02 22:49:00
我也好久没看到 loveme~ 发言了 Orz
作者: Feis (永远睡不着 @@)   2015-06-02 23:05:00
我没猜错的话, 他不同的范围只是选不同的阵列.所以还用不上函式指标阵列 Orz
楼主: tropical72 (蓝影)   2015-06-02 23:08:00
啊!好吧, 我又发废文了 Orz
作者: totemist (totem)   2015-06-03 00:04:00
感谢T大分享想法~ 我会好好从中学习,因为我C不强,就是边做边学这样。抱歉我在叙述上可能没有讲得很明确仔细,不过真的很感谢T大写了这篇文章,绝对不会是废文~ 原文我也有再修过了

Links booklink

Contact Us: admin [ a t ] ucptt.com