我有一个(些)大的事实表/国家机,我需要实现在我的代码(嵌入C)。我预期的行为规范的这个国家机器改变未来,所以我想保持这很容易地修改的未来。

我真值表4有输入和4的产出。我拥有这一切在Excel电子表格,并且如果我可能只是得到我的代码有一个小的格式,这将是理想的。

我想我想访问我的事实表,像这样:

u8 newState[] = decisionTable[input1][input2][input3][input4];

然后我就可以接入输出的数值:

setOutputPin( LINE_0, newState[0] );
setOutputPin( LINE_1, newState[1] );
setOutputPin( LINE_2, newState[2] );
setOutputPin( LINE_3, newState[3] );

但是为了得到这一点,它看起来像我必须做的一个相当令人困惑的表像这样:

static u8 decisionTable[][][][][] =
 {{{{ 0, 0, 0, 0 },
    { 0, 0, 0, 0 }},
   {{ 0, 0, 0, 0 },
    { 0, 0, 0, 0 }}},
  {{{ 0, 0, 1, 1 },
    { 0, 1, 1, 1 }},
   {{ 0, 1, 0, 1 },
    { 1, 1, 1, 1 }}}},
 {{{{ 0, 1, 0, 1 },
    { 1, 1, 1, 1 }},
   {{ 0, 1, 0, 1 },
    { 1, 1, 1, 1 }}},
  {{{ 0, 1, 1, 1 },
    { 0, 1, 1, 1 }},
   {{ 0, 1, 0, 1 },
    { 1, 1, 1, 1 }}}};

这些嵌套的方括号可能有些混乱--任何人都不会有一个更好的主意我怎么可以保持一个漂亮的表在我的代码?

谢谢!

编辑的基础上HUAGHAGUAH的回答:

使用合并的每个人的输入(谢谢-我希望我能"接受"3或4的这些问题的答案),我认为我试试它作为一个两维阵列。我会索引入我的阵列,使用一个小点移宏:

#define SM_INPUTS( in0, in1, in2, in3 ) ((in0 << 0) | (in1 << 1) | (in2 << 2) | (in3 << 3))

这会让我的真实表阵列是这样的:

static u8 decisionTable[][] = {
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 1, 1 },
{ 0, 1, 1, 1 },
{ 0, 1, 0, 1 },
{ 1, 1, 1, 1 },
{ 0, 1, 0, 1 },
{ 1, 1, 1, 1 },
{ 0, 1, 0, 1 },
{ 1, 1, 1, 1 },
{ 0, 1, 1, 1 },
{ 0, 1, 1, 1 },
{ 0, 1, 0, 1 },
{ 1, 1, 1, 1 }};

我可以访问我的事实表,像这样:

decisionTable[ SM_INPUTS( line1, line2, line3, line4 ) ]

我会给那枪,看看它是如何工作。我也会替换0和1的更有用的#定义,表达各国意味着,随着/**/评论中解释的投入对每个线的产出。谢谢你的帮助,每一个人!

有帮助吗?

解决方案

不需要多维表。用4位=&gt; 4位映射,您可以将单个u8 [16]阵列映射输入到输出。状态查找将更便宜,您可以使用一些移位和掩码操作来提取单个位。

如果填充行的算法很容易编纂,你可以#define一个宏来按索引号填充每一行。

其他提示

我建议(优选方法的第一个):

  • 使用宏intialize每个"行",这将隐藏括号内的宏呼吁。
  • 使用评论意见,打破了行。
  • 使用的一个初始功能的初始化的背景下明确,也许使用功能来初始化各个部分。这是类似于上面的第一个选项,但有一个缺点,即初始功能的必须援用国家机器可以使用。

就个人而言,我是从配置文件中读取的。也许,CSV很容易从Excel导出。或者您可以只从Excel复制并粘贴到纯文本中,这样就可以获得以空格分隔的值,同样易于导入。

这也意味着,假设您正在使用C,那么每次决策表更改时都不必重新编译代码。

如果你的真值表都是布尔值,你可以把它折叠成一对列表,例如。

1111,0000
1110,0110
...

用于数据压缩,将值表示为字节(两个nybbles)......

在特定的嵌入式系统配置中,如何/如何存储它以进行软编码,只有你可以说; - )

如果真值表真的只有4x4x4x4那么我会使用宏。如果它能够超越它,我会使用 Ragel 。有可能会制作比你更小,更快的C代码。

我没有看到任何对当前状态的引用以获得输出状态。这意味着它不是状态机,而只是一个真值表。有四个输入,因此只有16种可能的输入组合。因此,有16个职位的表应该这样做。

通常当你遇到这样的问题时,会尝试将其简化为一个简单的布尔公式。我不明白为什么这不是最好的方法。它会更紧凑,更具可读性,而且它有可能更快(我想象一些AND和OR的执行速度比查找表方法所需的乘法/移位+内存访问的集合更快)。将此表格缩减为布尔公式的最简单方法是使用 K-Map

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top