Why is the output showing d=4 instead of d=8 [duplicate] - c

This question already has answers here:
Short-circuit evaluation evaluating if( (a = 4) || (b = 6) || (c = 7) || (d = 8) )
(4 answers)
Closed 1 year ago.
Why is the output showing d=4 instead of d=8 in the first printf statement
#include <stdio.h>
int main() {
int a = 3, b = 4, c = 3, d = 4;
int y = (c = 5) || (d = 8);
printf("a=%d, b=%d, c=%d, d=%d\n", a, b, c, d);
}

|| short circuits, so in:
y = (c = 5) || (d = 8);
The d = 8 is never evaluated.
That is, since (c = 5) evaluates as true, there is no reason to evaluate the (d = 8) to determine the truthiness of the expression; so it is not evaluated.

Related

examples of The precedence of && is higher than that of ||

The K&R c says: The precedence of && is higher than that of ||
but why The following code, the c and d is still -1:
int a, b = -1, c = -1, d = -1;
a = (b = 1) || (0, c = 0) && (1, d = 0);
Because && has higher precedence than ||, your statement parses like this:
a = ((b = 1) || ((0, c = 0) && (1, d = 0)));
So you have (b = 1) as the left operand to || and (0, c = 0) && (1, d = 0) as the right operand. The left operand is evaluated first, so you have 1 on the left side. Because of that, the value of the entire || expression is known so the right side, i.e. (0, c = 0) && (1, d = 0), is not evaluated.
So c and d are not updated.

Write a program that loads integer variables that have values ​0 or 1 and then tells if the expression is true or false

I just started programming and I have the following task: Write a program that loads integer variables that have values ​​0 or 1 and then tells if (!a)&b&c + a&(!b)&c + a&b&(!c) + a&b&c is true or false. I wrote this:
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");
I simplified the expression from the beginning and I got: b(a+c)+a*c. When I run this program, the output is not as expected; it is not 0 or 1 even though I take for example a=0, b=1, c=1 (which is what should work according to task, but the output is 4327). Can somebody help me? I use C.
Your problem is that the printf() format string has 6 %d conversion specifications, but you only pass 4 values (a, b, c and the expression). You either need to use the POSIX n$ notation (see printf()), like this:
#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;
}
or you need to repeat the arguments as required:
#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 = %d, b = %d, c = %d: (%d && (%d || %d)) || (%d && %d) = %d\n",
a, b, c, b, a, c, a, c, (b && (a || c)) || (a && c));
else
printf("Numbers are not correct!\n");
return 0;
}
The output from both programs is the same. I used a shell script to test b41 (created from b41.c) like this:
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]:'
The grep removes the prompt lines (they're boring!) and the output is:
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
Note that GCC set fussy recommended extra parentheses in the expression mixing && and || operators. It's good to know the precedence rules; it's better to write code to avoid making those reading the code have to remember the rules.
The original expression ((!a)&b&c + a&(!b)&c + a&b&(!c) + a&b&c) is symmetric in a, b, c, yet the revision is not, and I suggested that the simplification was wrong, but it isn't. The original expression is true if any two of a, b, c are true, or if all three are true. On further scrutiny, the alternative (b(a+c) + a*c) does the same — but it could equivalently be written c(a+b) + a*b or a(b+c) + b*c; all three should produce the same output.
but the output is 4327
printf() lacks matching each "%d" with an int argument. Result: undefined behavior (UB): anything may happen including garbage output.
// 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 );
Instead:
// 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);
}
The following proposed code:
cleanly compiles
performs the desired functionality, using a table as input
displays the results of the logic equation
and now the proposed code:
// 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" );
}
}
}
a run of the proposed code results in:
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

what does this function do that helps it to take input differently and how are the conditions in for loop executed

What does this function do that helps it to take input differently and how are the conditions in for loop executed?
void scanint(int &x)
{
int flag=0;
register int c = gc();
if(c == '-') flag=1;
x = 0;
for(;(c<48 || c>57);c = gc());//why is this used?
for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}//how is this executed ?
if(flag == 1)x=-x;
}
It's not c.
void scanint(int &x) {/* Whatever */}
// ^^
This defines a function accepting a reference to an int and there are no references in c, the arguments are passed by value to functions. You could of course use a pointer to an int, but then the body of the function should be changed accordingly, using *x instead of ant occurrences of x.
The following assumes that gc() stands for a function similar to getchar(), so that the posted code is a very bad way of extracting an int value from stdin:
void scanint(int &x) // Or 'int *x' in C
{
int c = gc(); // register was deprecated in C++17
bool is_negative = (c == '-'); // C has bool from C99 too
x = 0; // '*x = 0;' in C. The same applies to the following code
// Considering only ASCII, ignores non-digit characters
// E.g. from " 123" it ignores the first two spaces,
// but, given " -123", it will ignore the sign too. Bad, as I said.
for( ;
( c < '0' || c > '9');
c = gc() )
;
// Now computes the actual number using an old trick that should
// be left to the compiler to be exploited:
// 10 * x = (2 + 8) * x = 2 * x + 8 * x = x << 1 + x << 3 (bit shifts)
for( ;
'0' <= c && c <= '9';
c = gc() )
{
x = (x << 1) + (x << 3) + c - '0';
}
if ( is_negative )
x = -x;
}

Get rid of "if" - Boolean Logic

I was wondering if we could get rid of all the "if" statements only by using boolean logic.
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);
}
}
So far I've been able to replace
if ((a+b == c) || (a+c == b) || (b+c == a))
{
e = '0';
}
else
{
e = 'X';
}
by
e = 'O'*((a+b == c) || (a+c == b) || (b+c == a));
e += (e == 0)*'X';
is there any way to get rid of the lines
if (d == 0)
and
if (d == 1)
using the same logic?
As you wish, no if-statement left:
!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)
);
I abused short-circuiting of ||, && and the comma-operator ,.
Anyway, if you want to see the masters in obfuscation, look at
The International Obfuscated C Code Contest .
Speaking about the motivation of this, it is a good thing if you are concerned about efficiency, as conditional branches are very time-consuming (this is the reason there are some complicated mechanisms for branch prediction). But it is not a good practice in usual code, as it might be very hard to understand for your reader, so your code becomes very hard to maintain. Also, as you are a beginner, it is a very good exercise.
Now, keep in mind that there is always a way. It is worth mentioning that you have a combination of logical, bitwise and arithmetic operation. It could be done purely with bitwise operations.
Let's try to make it using just bitwise operations. Assume your code is:
if (d == 0)
e = A;
if (d == 1)
e = B;
, where A and B are those 2 values you compute for e.
Firstly, extend the last significant bit to all of the d's bits (so if d is 1, it should be 0xFFFFFFFF and if it is 0, it should be 0x00000000). Then, do the operation. I splitted them into multiple lines, but it could be done more compact.
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);
Note that here I assume an int is 32 bits, which is not very portable. But, it is just an exercise.

how does "==" operator work in an expression?

#include <stdio.h>
int main()
{
int a = 10, b = 5, c = 5;
int d;
d = b + c == a;
printf("%d", d);
}
In the above code,could any one please explain to me how d = b + c == a works?
Because of operator precedence, it is parsed as
d = ((b + c) == a);
b + c is 10, which is equal to a, so d receives the value of 1, which is how C represents true comparisons.
Based on precedence of operators, binary + has higher precedence than ==. So the statement will be grouped as,
d = ( b + c ) == a;
Which becomes,
d = ( ( b + c ) == a ); // ==> d = ( 10 == 10 );
So, d holds the truth value based on the comparison (b+c) == a which is 1 because in C comparison operators will return 1 for true and 0 for false.
Its works like this
d = (b+c) == a --> (5+5) == 10 ---> 1
Which returns 1
+ operator has higher precedence than ==.So d=b+c==a; parsed as d=((b+c)==a);. b+c is 10.
so (10==a) evaluates true .So d=1;

Resources