这个交换机案例构造有没有更好的实现?

时间:2015-09-09 09:26:06

标签: c embedded

我正在开发一个嵌入式系统,其中要访问一个寄存器,然后递增以实现我正在寻找的结果,因为机器正在通知并配置为对我的访问做出反应并且不进行更改改变旗帜。所以switch的参数必须保持原样,否则会改变嵌入式系统的行为。

但是可能会出现我不想让任何案例被调用的情况。但是我仍然需要访问并增加switch的参数。

(更深入的是我正在逐步将一系列模拟值转换为数字值转换。索引用于与当前转换保持同步并将其与相应的情况相关联以处理图形正确。可能会出现这种情况。索引与当前转换异步化的状态,因此必须运行转换序列,而不会调用任何情况(以防止设置错误的数据),直到序列完成并且可以执行重新同步化)

我目前正在这样做:

switch (RunIndex++)/*RunIndex may only be accessed one time per execution
of this construct and has to be incremented in the same step. thats given.*/
{
   if (RunIndexSyncedWithADCensured == false)
   {
     break;
   }
   case 0:
     Case0RelatedData = SomeOperationsForCase0(RawData);
     break;
   case 1:
     Case1RelatedData = SomeOperationsForCase1(RawData);
     break;
   case 2:
     Case2RelatedData = SomeOperationsForCase2(RawData);
     break;
   default:
     RunIndex = 0;
     break;
}

这个构造完成了这项工作,但它看起来有点争议,考虑到将其提交到产品代码中,我感觉不太好。

那么有没有更好的方法来实现相同的目标,而不需要额外的变量或分配?

注意:

也可能是相关的,这是由2个部分组成的中断函数的第一部分。 第一部分处理转换完成后必须发生的事件if()。第二部分,还有另外要做的事情if()这种转换也结束了序列。所以简单地从函数返回而不进入第二部分是没有选择的。并且目前没有可能突破if(...)break;的循环结构。 (这也是我将if放在交换机范围内的原因,因为它至少是标准的一种有效的方式来突破。)

3 个答案:

答案 0 :(得分:4)

首先,if()switch()永远不会被执行 请考虑以下代码段:

#include <stdio.h>

int main(int argc, char *argv[])
{
    int i = 2;

    switch(i) {
        if (i == 2) {
            printf("I M HERE\n");
        }
        case 1:
            printf("1\n");
        break;
        case 2:
            printf("2\n");
        break;
        default:
            printf("default\n");
        break;
    }
    return 0;
}

对于您的代码:您希望打印字符串 I M HERE 。但事实并非如此。
上面代码段的输出是:

2

<强> No statements before case/default(switch constructs): is executed inside switch

现在回答

  

我不想让任何案件被调用。但是我仍然需要访问并增加开关的参数

只需将if()外部移至开关()。

if (RunIndexSyncedWithADCensured) {
    switch (RunIndex++) {
        case 0:
            Case0RelatedData = SomeOperationsForCase0(RawData);
            break;
            /* Other cases here */
        default:
           RunIndex = 0;
           break;
    }
} else
    RunIndex++;

答案 1 :(得分:1)

为什么不首先保存值然后增加它并使用交换机中保存的值?顺便说一下,这还包括两次访问,首先从RunIndex读取值,第二次增加它。

int runIndex = (RunIndex++);
if (RunIndexSyncedWithADCensured )
{
    switch (runIndex)/*RunIndex may only be accessed one time per execution
    of this construct and has to be incremented in the same step. thats given.*/
    {
        case 0:
            Case0RelatedData = SomeOperationsForCase0(RawData);
            break;
        case 1:
            Case1RelatedData = SomeOperationsForCase1(RawData);
            break;
        case 2:
           Case2RelatedData = SomeOperationsForCase2(RawData);
           break;
        default:
           RunIndex = 0;
           break;
    }
}

答案 2 :(得分:1)

由于您使用的是相邻的索引号,因此您可以创建一个函数指针数组来替换该开关。这就是优化器无论如何都会将开关转变为什么。因此,不是你的模糊开关,你得到这个:

if (RunIndexSyncedWithADCensured)
{
  SomeOperationsForCase[RunIndex](RawData);
}

RunIndex++;
if (RunIndex > MAX)
{
  RunIndex = 0;
}

与switch语句设计完全无关:如果RunIndex是一个敏感的volatile变量,例如某些硬件寄存器,那么你不应该直接在任何形式的计算中使用它。复制一份:

volatile int RunIndex; 
...

int index = RunIndex; // read from RunIndex

if (RunIndexSyncedWithADCensured)
{
  SomeOperationsForCase[index](RawData);
}

index++;
if (index > MAX)
{
  index  = 0;
}

RunIndex = index; // write to RunIndex

这是所有此类易变变量的标准做法。