我有许多信号可以是真,假或无效,但只有其中一条可以为真,否则就是错误。
我想知道是否有办法轻松检查,而不是需要做一个大的if语句
enum sig_type
{
sig_invalid, sig_true, sig_false
};
sig_type sig1 = GetSignal("sig1");
sig_type sig2 = GetSignal("sig1");
sig_type sig3 = GetSignal("sig1");
sig_type sig4 = GetSignal("sig1");
if (sig1 == sig_true)
{
if (sig2 == sig_true || sig3 == sig_true || sig4 == sig_true)
{
// Error
}
}
else if (sig2 == sig_true)
{
if (sig1 == sig_true || sig3 == sig_true || sig4 == sig_true)
{
// Error
}
}
等......这是一个重要的代码量,只是随着我添加信号而增加,因此在这种状态下将无法管理
答案 0 :(得分:6)
您可以使用C中的逻辑表达式求值为0表示false或1表示true表示的事实,并将它们加在一起。如果总数大于1,则表示您有错误,否则您不会。
另外,如果您认为将来可能需要更多(或仅可变数量)信号,我会使用数组来保存它们而不是单独的变量。然后可以在for
循环内完成测试:
sig_type sig[NSIGNALS];
int t = 0;
for (int i = 0; i < NSIGNALS; ++i) {
char buf[50]; /* Make sure your buffer is large enough, of course */
sprintf(buf, "sig%d", i + 1); /* Or however you want to generate it */
sig[i] = GetSignal(buf);
t += sig[i] == sig_true;
}
if (t > 1) {
/* Complain */
}
如果您的意思是1个信号必须为真,请将t > 1
测试替换为t != 1
。
编辑:错误处理程序中最初有一个throw
,但这不是C。
答案 1 :(得分:3)
没有必要以模糊,无效和不必要的复杂方式解决这个问题。
将所有信号存储在一个数组中,或者如果不可能,则存储一个指针数组,如下所示:
const sig_type* sigs [number_of_sig] =
{
&sig1,
&sig2,
...
};
然后遍历这个数组。
bool one_sig_true = false;
for(int i=0; i<number_of_sig; i++)
{
if(*sigs[i] == sig_true)
{
if(one_sig_true) // if one was already true from before
{
error();
break;
}
one_sig_true = true; // otherwise, set this flag
}
}
// if the loop finished without error, everything is fine
答案 2 :(得分:2)
有一个简单的技巧可断言给定的value
将多个位设置为1:
value & (value-1)
以下是如何使用此技巧以使用单个if
语句实现目标:
enum sig_type
{
sig_inv = 0,
sig_true = 1,
sig_false = 2,
};
int b0 = (int)GetSignal("sig1") & 1;
int b1 = (int)GetSignal("sig1") & 1;
int b2 = (int)GetSignal("sig1") & 1;
int b3 = (int)GetSignal("sig1") & 1;
int value = (b0<<0) | (b1<<1) | (b2<<2) | (b3<<3);
if (value & (value-1))
{
// Error
}
答案 3 :(得分:1)
让你的代码记住&#34;状态&#34;在变量中。
enum sig_type
{
sig_invalid, sig_true, sig_false
};
sig_type sig1 = GetSignal("sig1");
sig_type sig2 = GetSignal("sig1");
sig_type sig3 = GetSignal("sig1");
sig_type sig4 = GetSignal("sig1");
int count = 0;
if (sig1 == sig_true) {
count++;
}
if (sig2 == sig_true) {
count++;
}
if (sig3 == sig_true) {
count++;
}
if( sig4 == sig_true) {
count++;
}
if (count > 1) {
/* your error code here */
}
答案 4 :(得分:1)
我会提出一个算术解决方案。我有好处,你也可以为有效的案件找到一个好地方。此外,您不需要任何可以刷新指令管道的循环。
enum sig_type
{
sig_invalid, sig_true, sig_false
};
sig_type sig1 = GetSignal("sig1");
sig_type sig2 = GetSignal("sig1");
sig_type sig3 = GetSignal("sig1");
sig_type sig4 = GetSignal("sig1");
// This can be rewritten as needed and the personal preferences.
// The arithmetic that is described in this answer remains.
int cumulative_result =
((sig1 == sig_true) << 0) |
((sig2 == sig_true) << 1) |
((sig3 == sig_true) << 2) |
((sig4 == sig_true) << 3));
switch (cumulative_result)
{
case 0:
case 1:
case 2:
case 4:
case 8:
break;
default:
/* your error code here */
break;
}
对于“更邪恶”的案件,你可以更具体。