C 编写一个程序,加载具有值;0或1,然后告诉表达式是真还是假
我刚开始编程,我有以下任务:编写一个程序,加载具有值的整数变量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=
(!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
和表达式)。您需要使用POSIXn$
表示法(请参阅),如下所示:
#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