摆脱“if” - 布尔逻辑

时间:2014-11-18 23:52:59

标签: c boolean logic

我想知道我们是否可以摆脱所有" if"语句只能使用布尔逻辑。

int main() {
    int a,b,c,d;
    char e;

    scanf("%d %d %d", &a, &b, &c);
    scanf("%d", &d);

    if (d == 0)
    {
        e = 'O'*((a+b == c) || (a+c == b) || (b+c == a));
        e += (e == 0)*'X';

        printf("%c\n",e);
    }

    if (d == 1)
    {
        e = 'O'*((a*b == c) || (a*c == b) || (b*c == a));
        e += (e == 0)*'X';

        printf("%c\n",e);
    }
}

到目前为止,我已经能够取代

if ((a+b == c) || (a+c == b) || (b+c == a))
{
e = '0';
}

else
{
e = 'X';
}

通过

e = 'O'*((a+b == c) || (a+c == b) || (b+c == a));
e += (e == 0)*'X';

有没有办法摆脱行

if (d == 0)

if (d == 1)

使用相同的逻辑?

2 个答案:

答案 0 :(得分:1)

如您所愿,没有if - 声明:

!d && (
    (e = 'O'*((a+b == c) || (a+c == b) || (b+c == a))),
    (e += (e == 0)*'X'),
    printf("%c\n",e)
);

d-1 || (
    (e = 'O'*((a*b == c) || (a*c == b) || (b*c == a))),
    (e += (e == 0)*'X'),
    printf("%c\n",e)
);

我滥用了||&&和逗号运算符,的短路。

无论如何,如果你想看到混淆的主人,看看
The International Obfuscated C Code Contest

答案 1 :(得分:0)

谈到这一点的动机,如果你关注效率是一件好事,因为条件分支非常耗时(这就是分支预测有一些复杂机制的原因)。但是在通常的代码中这不是一个好习惯,因为对于您的读者来说可能很难理解,因此您的代码变得非常难以维护。此外,由于你是初学者,这是一个非常好的练习。

现在,请记住,始终有一种方法。值得一提的是,您具有逻辑,按位和算术运算的组合。它可以纯粹通过按位运算来完成。

让我们尝试使用按位运算。假设您的代码是:

if (d == 0)
    e = A;
if (d == 1)
    e = B;

,其中A和B是您为e计算的2个值。

首先,将最后一个有效位扩展到所有的s位(如果d为1,则应为0xFFFFFFFF,如果为0,则应为0x00000000)。然后,做手术。我将它们分成多行,但它可以做得更紧凑。

d = d << 1 + d;
d = d << 2 + d;
d = d << 4 + d;
d = d << 8 + d;
d = d << 16 + d;
e = (B & d) || (A & ~d);

注意,这里我假设一个int是32位,这不是很便携。但是,这只是一个练习。