C 编写一个程序,加载具有值​;0或1,然后告诉表达式是真还是假

C 编写一个程序,加载具有值​;0或1,然后告诉表达式是真还是假,c,C,我刚开始编程,我有以下任务:编写一个程序,加载具有值的整数变量​​0或1,然后告诉(!a)&b&c+a&(!b)&c+a&b&(!c)+a&b&c是真是假。我写道: int a, b, c; printf ("a: \n"); scanf ("%d", &a); printf ("b: \n"); scanf ("%d", &b); printf ("c: \n"); scanf ("%d", &c); if ((a==1 || a==0) && (b=

我刚开始编程,我有以下任务:编写一个程序,加载具有值的整数变量​​0或1,然后告诉
(!a)&b&c+a&(!b)&c+a&b&(!c)+a&b&c
是真是假。我写道:

int a, b, c;
printf ("a: \n");
scanf ("%d", &a);
printf ("b: \n");
scanf ("%d", &b);
printf ("c: \n");
scanf ("%d", &c);

if ((a==1 || a==0) && (b==1 || b==0) && (c==0 || c==1))
    printf ("%d &&(%d||%d) || %d&&%d=%d\n", a, b, c, b &&(a||c) || a&&c );
else
    printf ("Numbers are not correct!\n");
我从一开始就简化了表达式,得到:
b(a+c)+a*c
。当我运行这个程序时,输出不符合预期;它不是0或1,即使我以a=0,b=1,c=1为例(这是根据任务应该工作的,但输出是4327)。有人能帮我吗?我用C

但产量是4327

printf()。结果:未定义行为(UB):任何事情都可能发生,包括垃圾输出

//       1     2   3      4   5  6      1  2  3  v-----4----------v  (missing  5 and 6)
printf ("%d &&(%d||%d) || %d&&%d=%d\n", a, b, c, b &&(a||c) || a&&c );
相反:

// For clarity, do one at a time.
{
printf("a:%d\n", a);
printf("b:%d\n", b);
printf("c:%d\n", b);
printf("Formula: %s\n", "(!a)&b&c + a&(!b)&c + a&b&(!c) + a&b&c");
printf("Formula result: %d\n", (!a)&b&c + a&(!b)&c + a&b&(!c) + a&b&c);
}

您的问题是
printf()
格式字符串有6个
%d
转换规范,但您只传递4个值(
a
b
c
和表达式)。您需要使用POSIX
n$
表示法(请参阅),如下所示:

#include <stdio.h>

int main(void)
{
    int a, b, c;
    printf("a: \n");
    scanf("%d", &a);
    printf("b: \n");
    scanf("%d", &b);
    printf("c: \n");
    scanf("%d", &c);

    if ((a == 1 || a == 0) && (b == 1 || b == 0) && (c == 0 || c == 1))
        printf("a = %1$d, b = %2$d, c = %3$d:  (%2$d && (%1$d || %3$d)) || (%1$d && %3$d) = %4$d\n",
               a, b, c, (b && (a || c)) || (a && c));
    else
        printf("Numbers are not correct!\n");
    return 0;
}
for a in 0 1
do
    for b in 0 1
    do
        for c in 0 1
        do
            echo $a $b $c | b41
        done
    done
done | grep -v '^[abc]:'
grep
删除提示行(它们很无聊!),输出为:

a = 0, b = 0, c = 0:  (0 && (0 || 0)) || (0 && 0) = 0
a = 0, b = 0, c = 1:  (0 && (0 || 1)) || (0 && 1) = 0
a = 0, b = 1, c = 0:  (1 && (0 || 0)) || (0 && 0) = 0
a = 0, b = 1, c = 1:  (1 && (0 || 1)) || (0 && 1) = 1
a = 1, b = 0, c = 0:  (0 && (1 || 0)) || (1 && 0) = 0
a = 1, b = 0, c = 1:  (0 && (1 || 1)) || (1 && 1) = 1
a = 1, b = 1, c = 0:  (1 && (1 || 0)) || (1 && 0) = 1
a = 1, b = 1, c = 1:  (1 && (1 || 1)) || (1 && 1) = 1
请注意,GCC在表达式中设置了模糊的建议附加括号,将
&
|
运算符混合在一起。知道优先规则很好;最好是编写代码,以免让那些阅读代码的人不得不记住规则


原始表达式(
(!a)&b&c+a&(!b)&c+a&b&(!c)+a&b&c
)在
a
b
c
中是对称的,但修订不是,我认为简化是错误的,但它不是。如果
a
b
c
中的任意两个为真,或者如果这三个都为真,则原始表达式为真。经进一步审查,备选方案(
b(a+c)+a*c
)也有同样的作用,但可以等效地写成
c(a+b)+a*b
a(b+c)+b*c
;所有三个都应产生相同的输出。

以下建议代码:

 // the equation to solve
 //  if (!a)&b&c + a&(!b)&c + a&b&(!c) + a&b&c
 // where: `!` is a symbol for logical not, `&` is logical and, and `+` is logical or.

 #include <stdio.h>

int main( void )
{
     int a;
     int b;
     int c;

    #if 0 
     a = getchar();
     getchar();
     b = getchar();
     getchar();
     c = getchar();
    #endif

    int data[][3] =
    {
        { 0, 0, 0 },
        { 0, 0, 1 },
        { 0, 1, 0 },
        { 0, 1, 1 },
        { 1, 0, 0 },
        { 1, 0, 1 },
        { 1, 1, 0 },
        { 1, 1, 1 },
    };

    for( size_t i=0; i< sizeof( data ) / sizeof( data[0] ); i++ )
    {
        a = data[i][0];
        b = data[i][1];
        c = data[i][2];

        printf( "a=%d; b=%d: c=%d:\n", a, b, c);

        if ( (!a && b && c)   ||  (a && b && !c)  || (a && b && c) )
        {
            puts( "true\n" );
        }

        else
        {
            puts( "false\n" );
        }

    }
}
  • 干净地编译
  • 使用表格作为输入,执行所需的功能
  • 显示逻辑方程的结果
  • 现在建议的守则是:

     // the equation to solve
     //  if (!a)&b&c + a&(!b)&c + a&b&(!c) + a&b&c
     // where: `!` is a symbol for logical not, `&` is logical and, and `+` is logical or.
    
     #include <stdio.h>
    
    int main( void )
    {
         int a;
         int b;
         int c;
    
        #if 0 
         a = getchar();
         getchar();
         b = getchar();
         getchar();
         c = getchar();
        #endif
    
        int data[][3] =
        {
            { 0, 0, 0 },
            { 0, 0, 1 },
            { 0, 1, 0 },
            { 0, 1, 1 },
            { 1, 0, 0 },
            { 1, 0, 1 },
            { 1, 1, 0 },
            { 1, 1, 1 },
        };
    
        for( size_t i=0; i< sizeof( data ) / sizeof( data[0] ); i++ )
        {
            a = data[i][0];
            b = data[i][1];
            c = data[i][2];
    
            printf( "a=%d; b=%d: c=%d:\n", a, b, c);
    
            if ( (!a && b && c)   ||  (a && b && !c)  || (a && b && c) )
            {
                puts( "true\n" );
            }
    
            else
            {
                puts( "false\n" );
            }
    
        }
    }
    

    %d&(%d | |%d)| |%d&%d=%d\n“
    有6个
    %d”
    但只有4个
    int
    参数。Mia09,你的意图是什么?“工作不正常。”含糊不清。发布示例输入、输出和预期输出。请再次阅读@chux注释。请提供精确输入、预期输出(“1或0”不是给定输入的精确输出)和实际输出。原始布尔表达式是对称的;你推导的简化表达式是不对称的。这有力地说明问题之一在于你的简化。我认为简化是错误的,但事实并非如此。如果
    a
    b
    c
    中的任意两个为真,或者如果这三个都为真,则原始表达式为真。经过进一步审查,替代方案也会这样做——但它可以等价地写成
    c(a+b)+a*b
    a(b+c)+b*c
    ;所有这些都应该产生相同的输出。主要问题是您的
    printf()
    语句,正如@chux在一篇文章中指出的那样。当你解决这个问题时,你应该是可以的。长手条件与问题中的条件不匹配,因此程序输出'false'表示
    a=1;b=0;c=1
    何时应输出“true”。缺少的术语是
    | |(a&&!b&&c)
    。哎呀,我错过了一个逻辑组,答案的目的是展示如何编写代码。注意,我也没有包括值(0,1)的验证。然而,这应该为OP(似乎是一名学生,这是一项家庭作业)指出正确的方向,而不会泄露一切
    a=0; b=0: c=0:
    false
    
    a=0; b=0: c=1:
    false
    
    a=0; b=1: c=0:
    false
    
    a=0; b=1: c=1:
    true
    
    a=1; b=0: c=0:
    false
    
    a=1; b=0: c=1:
    false
    
    a=1; b=1: c=0:
    true
    
    a=1; b=1: c=1:
    true