Unusual behavior of ternary operator? - c

i was just playing around with the ternary operator in my c class today. And found this odd behavior.
#include <stdio.h>
#include <stdbool.h>
main()
{
int x='0' ? 1 : 2;
printf("%i",x);
}
returns 1 as expected.But
#include <stdio.h>
#include <stdbool.h>
main()
{
int x='0'==true ? 1 : 2;
printf("%i",x);
}
returns 2 while i expect it to return 1.

The value of '0' is not zero, it is whatever integer value encodes the digit '0' on your system. Typically 48 (in encodings borring from ASCII), which is then not equal to true when interpreted as an integer, which is 1.
So the first of your code lines is equivalent to
int x = (48 != 0) ? 1 : 2;
which clearly evaluates to 1. The second is
int x = (48 == 1) ? 1 : 2;
which just as clearly evaluates to 2.

Maybe you are confusing '\0' and '0'
The value of the character constant
'\0'
is always 0 in C.
The value of the character constant
'0'
is implementation defined and depends on the character set. For ASCII, it is 0x30.
Also note that the macro true is defined to the value 1 and not 0.

That's because (assuming ASCII) '0' represents the integer 0x30, i.e. 48, and true represents the integer 1. So they're not equal.
In C, any nonzero value is considered true, but true itself is 1, and 1 is what you get from any built-in Boolean test (for example, 0 == 0 is 1).

true is defined as 1. '0' in ASCII is 0x30 which is not equal to 1.
Therefore the condition '0'==true is not true.

That's because '0' != true. The boolean value gets promoted to an integer type and is equal to 1 whereas '0' is equal to 48

'0' does not equal true, so the result of '0'==true is 0 (false). This is assigned to x and passed to the ternary operator, giving the result you see.
If you intended something else, you should use brackets to clarify the order of precedence you want, or break your code up into multiple statements.

Related

Why does it print 1 at the end?

I don't understand why it prints 1 at the end.
#include <stdio.h>
int main(){
printf("%d\n", -2&&2);
return 0;
}
&& is a Boolean operator, not an integer operator. In C any non-zero value is interpreted as true when applied to a Boolean operation, while zero is the only integer value regarded as false when applied to a Boolean operation.
So:
(<non-zero> && <non-zero>) == true
then conversely when a true result is treated as an integer (as the %d format specifier dictates in this case), true is represented by 1, while false is zero. So in this case true becomes 1.
If you want to print a Boolean result, then:
printf( "%s\n", (-2 && 2) == 0 ? "false" : "true" ) ;
Strictly the expression:
-2 && 2
is equivalent to:
(-2 != 0) && (2 != 0)
Which has strict type agreement since != has a Boolean result from integer operands, and so && is presented with Boolean operands only with no implicit conversion.
Because -2&&2 is evaluated to true = 1 (when you AND two numbers together you will get true unless one or both of the numbers is 0).
Try changing -2&&2 to true && false; it will print 0.
The expression -2&&2 resumes to 1 or true (true is always != 0, while false == 0) based on the boolean arithmetic opration.
And here is how it resumes to 1:
&& represents the logical AND, not bitwise AND, which is &, in C. So you are logical ANDing the values of -2 and 2.
Let´s consider the following sentence as one of the statements for the Logical AND (&&)-operation:
If both the operands are non-zero, then the condition becomes true.
-2 is non-zero, equals 1.
2is also non-zero, equals 1.
So the result is also 1 (1AND 1 = 1) or true represents 1.
The && operator is for logical and, not bitwise and.
The expression in your program evaluates as
printf("%d\n", (-2 != 0) && (2 != 0));
Which is 1 because boolean expressions have value 0 for false and 1 for true in C.
Conversely, if you had written -2 & 2, you program would have implementation defined behavior, depending on the representation of negative integers used for the target system. On modern systems with two's complement representation, this bitwise and expression evaluates to 2. Same value for sign-magnitude representation, but on rare systems with ones' complement representation, the value would be 0.

Logical AND operator in c spitting out 1

int a;
scanf("%i", &a);
printf("%i", a&&1);
In this program, no matter the input it spits out a 1, even when I try even numbers. The only exception is when a = 0. I might not be understanding the AND operator correctly, but for any even number shouldn't the output be 0?
Because the && operator returns a non zero value if both its operands are not zero. Maybe you mean &.
int a;
if (scanf("%i", &a) == 1)
printf("%i", a & 1);
&& is the logical AND operator.
& is the bitwise AND operator.
Operator && is the logical AND operator that returns true/false.
In C language false is 0 (zero) otherwise 1 (one) for true as C does not have boolean type.
So the result of your operator is correct and as expected.
If you insist on using bool type you can include definition for it as below
// standard way
#include <stdbool.h>
which is basically
#define bool _Bool
#define true 1
#define false 0

Explain the result of the program?

The output of below c program is,
output : 1,2,3,4 ........ 126,127,-128,-127 .... -2,-1 ?
#include <stdio.h>
#include <string.h>
int main()
{
char i=0;
for(i<=5 && i>=-1 ; ++i;i>0)
printf("%d\n",i);
printf("\n");
return 0;
}
please explain why is so ?
Here is a breakdown of your code, it's fairly sneaky:
for( i <= 5 && i >= -1 ; ++i; i > 0)
Typically a for-loop is, ( initial statement, expression, second statement ). Looking at your code before the first null statement: what you have done is an expression (in place of a statement), which does not matter at all however it's entirely useless. So removing that line (which has no effect on the result of this expression) gives us:
for( ; ++i; i > 0)
... now if you noticed you initialized i to be 0 before the for loop. What you are doing next is incrementing i and then returning its value (see here), and hence it will go from 1 ... -1 (overflowing at 127). This is because in C any non-zero value is true and 0 is false. Hence, once i becomes 0 it will stop running the loop. i can only become zero by overflowing.
Your third statement does not matter, it's irrelevant.
It is called overflow. Type "char" uses 1 byte of your RAM's capacity, so it can store only 256 values. These are [-128, 127]. When you try to get over 127, it will get back the the lowest value.
Other than that, your for loop is a little messed up. Try
for ( i = 0 ; i <= 5 ; ++i ) // This will print 0,1,2,3,4,5
printf( "%d\n" , i );
I'm guessing you're using the for loop incorrectly.
for(i<=5 && i>=-1 ; ++i;i>0)
The above code means:
Before anything, evaluate i<=5 && i>=-1 (which doesn't have any side effects so nothing happens)
On every iteration, increment i then check if it is zero. If it is non-zero, run another iteration.
At the end of every iteration, evaluate i>0 (which again, does nothing).
Therefore, your loop simplifies down to and is essentially
while (++i)
To explain your result, the system you're using is likely using implements a char as a signed two's complement integer which 'wraps' to a negative number when it is higher than 127 (since 128 in a 8 bit two's complement integer is a -128)
First of all, char occupies 1 byte and it is signed.
With the help of 8 bits (1 byte) the range of numbers that you can represent is
**-(2^(8-1)) to +((2^(8-1)) -1) [ie from -128 to +127].**
In your code you are incrementing i and also printing the same.
once i reaches 127 (in binary 0111 1111 = 127) and you again increment it becomes (1000 0000) which is -128.
And while printing you are using %d. so out will be in integer format.
That is why it is printing 1,2,3 ... -128, -127...
If you didn't understand how 1000 0000 is -128, read
What is 2's Complement Number?
Because this:
for(i<=5 && i>=-1 ; ++i;i>0)
works out as
1) Initialisation:
i<=5 && i>=-1
does nothing
2) Termination condition:
++i
increments i and will terminate when i gets to zero
3) statement executed each time round loop (normally an increment / decrement):
i > 0
does nothing.
So your code loops from i = 0 back till it's zero again

Understanding the exit condition of a 'for' loop

I had this question after reading the Stack Overflow quesion Print an int in binary representation using C.
In a user's comment, they posted this for loop, which assigns either a 1 or a 0 to the bit position in order to convert from an int decimal to char * binary.
for(; bits--; u >>= 1)
str[bits] = u & 1 ? '1' : '0';
I understand why there doesn't need to be an initialized value. This is the syntax for a for loop that I've always known:
for ( variable initialization; condition; variable update )
I don't understand how 'bit--' can be an exit condition. Please help me understand how this code works (I tested it, and it is valid).
In C, a value of zero evaluates to "false" in a Boolean context. So when bits-- evaluates to 0, in the context of the loop it evaluates to "false" and terminates the loop.
If you say, for example:
int x = 1;
if (--x)
{
printf("True!\n");
}
else
{
printf("False!\n");
}
It will output "False", because --x evaluates to 0, which is "false" in a Boolean context.
All conditions basically boil down to checking whether something is 0 or not. 0 means false, everything else means true. So that loop will break when bits is 0.
You will sometimes see while or if conditions written
if (variable) // or while(variable)
That is just shorthand for
if (variable != 0) // or while (variable != 0)
So
for (; bits--; u >>= 1)
is short for
for (; bits-- != 0; u >>= 1)
bits-- is an assignment expression of type int (since it will return the value of b, which is int). To match the for loop syntax, it gets converted to a Boolean expression, which means it is true if bits != 0.
In fact, the condition is identical to bits!=0, but by using bits--, it changes the value of bits at the same time, making the code more compact. That's all.
As others said, in C, you can use integers as a condition - 0 or false, and anything else for true. (Actually, you almost always do it - even an expression like a<b is an int.)
So, the loop will end when bits-- will be 0.
When the -- operator comes after the variable, it decreases the variable, and gets the previous value of it. For example, if you have int a=3,b; b=a--;, then b will be 3, and a will be 2.
So, the loop will exit after that bits will been decreased from 0 to -1.
That means that, if in the beginning, bits==8 (for example), the loop will iterate 8 times, when in the first, bits will be 7 (because the condition had checked), and in the last, bits will be 0. It is a nice way to loop through an array (Since in C, an array of bits variables is being indexed from 0 to bits-1).

What does the condition "if (n/10)" with integral n specify?

I am looking at the following piece of code:
void printd(int n)
{
if (n < 0) {
putchar('-');
n = -n;
}
if (n / 10)
printd(n / 10);
putchar(n % 10 + '0');
}
I understand the first if statement fine, but the second one has me confused on a couple of points.
By itself, since "n" is an integer, I understand that n/10 will shift the decimal point to the left once - effectively removing the last digit of the number; however, I am having a little trouble understanding how this can be a condition by itself without the result being equal to something. Why isn't the condition if ((n/10) >= 0) or something?
Also, why is the '0' passed into the putchar() call?
Can someone tell me how it would read if you were to read it aloud in English?
Thanks!
The n / 10 will evaluate to false if the result is 0, true otherwise. Essentially it's checking if n > 10 && n < -10 (the -10 doesn't come into play here due to the n = -n code)
The + '0' is for character offset, as characters '0'-'9' are not represented by numbers 0-9, but rather at an offset (48-57 with ascii).
Can someone tell me how it would read if you were to read it aloud in English?
If you're talking about the conditional, then I would say "if integer n divided by 10 is not zero"
n/10 will not shift the decimal number since n is an integer. The division will produce the result like this: if n = 25, then n/10 would be 2 (without any decimal points), similarly if n = 9, then n/10 would be 0 in which case if condition would not be satisfied.
Regarding the +'0', since n%10 produces an integer result and in putchar you are printing a char , you need to convert the integer to a char. This is done by adding the ascii value of 0 to the integer.
In C, there is no separate boolean type; an expression like a > b evaluates to zero if false, non-zero if true. Sometimes you can take advantage of this when testing for zero or non-zero in an int.
As for the '0', that just performs character arithmetic so that the right character is printed. The zero character has an ASCII encoding value which isn't zero, so the n value is used as an offset from that encoding to get the right numeric digit printed out.

Resources