How does this C program print a value 1 or 0? - c

This is is the simple program that I was writing in C
#include <stdio.h>
int main(void){
int i, j, k;
i = 2; j = 3;
k = i * j == 6;
printf("%d", k);
}
so I know what this program is actually doing two values for the variable's are given here it does the calculation and then check;s the calculated value to the given condition.
Now here is what I am not getting When the program get executed it return's the value 1 when the given condition is satisfied and 0 if not, and i know that 1 stand's for true and o stand's for false but what i was thinking how doe's it do that i mean there is nothing in the program that tell' it to print 0 or 1 for the condition. Is it default in some C compilers to return that values or am i missing some point.

There is nothing in the program that tells it to print 0 or 1 for the condition.
Yes there is, you print k and you assigned the result of the comparison to k. These are all equivalent (given that i = 2 and j = 3):
k = i * j == 6;
k = (i * j == 6);
k = (6 == 6);
k = 1;
Then you print it:
printf("%d", k); // Prints 1

As you said it yourself, logical expressions in C evaluate either to 0 (false) or to 1 (true). That's exactly what "tells it" to put either 0 or 1 into your k variable, depending on whether the condition is satisfied.
Now, you seem to be talking about what your program "returns". I'm not sure what you mean by "returns" here. The program exit code perhaps? Your main function does not contain any return statements, which means that in C89/90 its return value will be unpredictable, while in C99 it will be guaranteed to return 0. I suspect that you are using a C89/90 compiler that simply returns "garbage" from main, which purely accidentally happens to match the final value of k.

In C, there is no true or false, just 1 and 0, or more precisely 0 and not 0.

Related

++i and i++ in while loop in C

I am using a program to detect the boundary of each data type, which is like this:
#include <stdio.h>
#include <stdlib.h>
int main()
{
/*first while loop using a++ dosesn't give us a right answer*/
int a = 0;
while (a++ > 0);
printf("int max first = %d\n", a-1);
/*second while loop using ++a performs well*/
int b = 0;
while (++b > 0);
printf("int max second = %d\n", b-1);
system("pause");
return 0;
}
After I compile this propram and excute it, it returns:
int max first = 0
int max second = 2147483647
So I try to debug it, and I find out that in the first part, after a++ becomes 1, then it just stop autoincrement and jump the while loop,while in second part it runs well, why is this happening?
The pre-increment operator (e.g. ++b) is done first, and the value of the expression is the incremented value.
That is
int b = 0;
while (++b > 0) ...
will increment b first and then check its value using the larger-than comparison. Since in the very first iteration ++b will make b equal to 1 the condition will be 1 > 0 which is true.
Now the post-increment operator does the increment after the old value is used.
So for example a++ will return the old value of a and then do the increment.
So with
int a = 0;
while (a++ > 0) ...
the very first iteration a++ will return 0 which means you have the condition 0 > 0 which is false and the loop will never even iterate once. But the value of a will still be incremented, so afterwards it will be equal to 1 (when the loop have already ended).
This behavior of the pre- and post-operators should be part of any decent book, tutorial or class.
after a++ becomes 1, then it just stop autoincrement and jump the
while loop
This happens because of the post and pre increment operators and the ; in while loop working together.
a will be incremented by 1 after the condition a++ > 0 is evaluated. Thus, the condition fails. The ; at the end of the while statement results in an empty loop and the next print statement will be executed even if the condition on which the while loop is based returns true.
This is exactly what happens in the second while loop - the pre increment operator will increment b before the condition is checked inside while (++b > 0);. The empty while loop keeps on adding one to the value of b until there is an overflow.
At this point, strictly speaking, you have invoked undefined behaviour because the operation has resulted in overflowing a signed integer.
Let me rewrite the main function you wrote - so that it becomes easier to understand.
int main()
{
/*first while loop*/
int a = 0;
while (a > 0){ a = a + 1; }
printf("int max first = %d\n", a-1);
/*second while loop*/
int b = 0;
b = b + 1;
while (b > 0){ b = b + 1; }
printf("int max second = %d\n", b-1);
system("pause");
return 0;
}
Some observations regarding what happened here:
Because at the beginning of the first while loop - the value of a is 0 - which is not greater than 0; the loop gets skipped at the beginning. As a result, the first printf outputs 0.
At the beginning of the second while loop, before evaluating the loop control condition; the loop control variable b gets incremented by 1, resulting the value of b becoming 1; which is greater than 0. For this reason, the second loop is executed.
While executing the second loop, the value of b keeps incrementing by 1 until the value of b overflows. At this point, the program encounters undefined behaviour - and exits the while loop if the program doesn't crash or keeps executing the loop indefinitely (in which case, at some stage the OS will terminate the program; or ask the user to terminate it - as the program will become non-responsive).
You mentioned that you wanted to measure the limit of int values; I hope this reference and this reference will help you in some way.

what should be the output for below program?

void foo(int n, int sum)
{
int k = 0, j = 0;
if (n == 0) return;
k = n % 10;
j = n / 10;
sum = sum + k;
foo (j, sum);
printf ("%d,", k);
}
int main ()
{
int a = 2048, sum = 0;
foo (a, sum);
printf ("%d\n", sum);
getchar();
}
For me this should be 4,0,2,8,0
However, when i execute it, it gives me 2,0,4,8,0
As the code stands, the argument sum to foo is not really relevant since it is passed by value so the last statement in the main function printf ("%d\n", sum) will print 0 regardless of what happens inside foo. That's the last 0 you see in the output the program generates.
Now, the function foo itself accepts an argument n, performs integer division by 10, and recursively calls itself until n is zero. This in effect means that it will print the decimal digits of the input number which is what you see in the output...
It is called as recursive call to the function.
And internally Recursion run as a stack LAST IN FIRST OUT kind
Now in your case it is first printing the output of last call to foo function
Steps in which your program is executing are like this and result will go in stack
1 - 1 st call to foo value of k = 8
2 - 2 nd call to foo value of k = 4
3 - 3 rd call to foo value of k = 0
4 - 4 th call to foo value of k = 2
And as told earlier it will work like stack so the output of the program will be
2 0 4 8 and if you want 4,0,2,8,0 this as a output you need to write the logic accordingly :)
Yes, the output you are getting is absolutely right.
In main(),foo() is called with a=2048 and sum=0.
In foo() we have n=2048, then the if condition calculates values for k,i.e.,(n%10) and j,i.e.,(n/10) till n becomes equal to 0.
Now since there is a recursive call to foo() with j and sum as parameters, the value of k in each iteration gets pushed to a stack and is popped out when n==0 condition is satisfied.
So, if you trace out the program you get values of k=8,4,0,2 which is pushed to stack in the same sequence and thus while popping the elements we have 2,0,4,8.

Variable assignment in conditional statement

I have a code:
while (i = j) {
/* not important */
}
For how long will this while loop work? Is it till the moment when the value of variable j is equal to zero?
For while loop properties, quoting C11, chapter §6.8.5/p4, (emphasis mine)
An iteration statement causes a statement called the loop body to be executed repeatedly
until the controlling expression compares equal to 0. [...]
and considering the assignment inside the loop condition, quoting §6.5.16/p3
[...] An
assignment expression has the value of the left operand after the assignment,111) but is not
an lvalue. [...]
So, every time the loop condition is executed, first the current value of j will be assigned to i and then, the value of i will be taken as the controlling expression value.
In other words, the loop will continue until j becomes 0.
That said, iff you are sure about the assignment part as the loop condition statement, put it into double parenthesis like
while ((i = j)){
Less confusion for the compiler and the next developer/maintainer.
For how long will this while loop work? Is it till the moment when the value of variable j is equal to zero?
A while loop would would work till it's the condition or expression evaluates to be false (i.e, 0).
In your code, YES while loop works till the moment when the value of variable j is equal to 0.
Note : The assignment operator in C returns the value of the variable that was assigned i.e, the value of the expression i = j os equal to j.
In while(i = j) , first i is assigned with value of jand then the expression is evaluated whether true or false.
Why not try a simple program :) :
#include <stdio.h>
int main(void)
{
int i = 0,j =10;
while (i = j)
{
printf("in loop when j = %d\n",j);
j--;
}
printf("exited loop when j = %d",j);
}
output :
in loop when j = 10
in loop when j = 9
in loop when j = 8
in loop when j = 7
in loop when j = 6
in loop when j = 5
in loop when j = 4
in loop when j = 3
in loop when j = 2
in loop when j = 1
exited loop when j = 0
An assignment operation always returns the result of the assignment, so the loop will continue until j == 0, this behavior exists so you can chain many assignment operations together like so:
a = b = c;

Conditional Operator Query in C

{
int i=0;
int j;
j=(i=0)?2:3;
printf("the answer is %d",j);
}
I want to know why this statement j=(i=0)?2:3; gives the answer 3 when the value define to i is zero?
In C, zero is considered as false and all non-zero numbers are considered as true. This:
j=(i=0)?2:3;
is the same as
if(i = 0)
j = 2;
else
j = 3;
Here, i = 0 assigns 0 to i and since 0 is considered as false, the else executes, assigning 3 to j.
Do note that = is the assignment operator and assigns its left and right operands. This is different from the conditional operator == which compares both its operands and returns 0 if false and 1 if true.
If you meant ==, then j=(i==0)?2:3; is the same as
if(i == 0)
j = 2;
else
j = 3;
which will assign 2 to j as i == 0 is true.
To prevent these kind of mistakes, you can use Yoda Conditions as suggested by #JackWhiteIII, i.e , reversing the condition. For example,
j=(i=0)?2:3;
can be written as
j=(0=i)?2:3;
Since 0 is a constant value and cannot be altered, the compiler is emit an error, preventing these kind of mistakes. Note that both 0 == i and i == 0 do the same thing and both are indeed valid.
i=0 is an assignment. Use i==0 for comparison.
Assignments return the new value of the variable that is being assigned to. In your case, that's 0. Evaluated as a condition, that's false.
As in the above code snippet,
{
int i=0;
int j;
j=(i=0)?2:3;
printf("the answer is %d",j);
}
you mistyped, (i==0) with (i=0) which just assigns 0 to i and checks the result, hence you're getting the output as, the answer is 3. The new code would be like,
{
int i=0;
int j;
j=(i==0)?2:3;
printf("the answer is %d",j);
}
The above corrected code snipped gives the output as,
the answer is 2.
Because you mistyped the == operator. You are setting i to the value 0 again and testing this value, which is 0, hence false.
Write this instead:
j = (i == 0) ? 2 : 3;
The result of the assignment operator (= in i=0) is the new value of the object (0). 0 is a false value, thus the 'false' branch of your condition is chosen, which is 3.

If loop execution

In the code below,
#include<stdio.h>
int main()
{
int k,sum;
for(k=7;k>=0;sum=k--)
printf("%d \n",sum);
return 0;
}
The output is:
0
7
6
5
4
3
2
1
I want to know how this loop executes and why isn't printing 0 in the last?
On first iteration sum is uninitialized. It has indeterminate value.
C11: 6.7.9 Initialization:
If an object that has automatic storage duration is not initialized explicitly, its value is
indeterminate.
Section 6.3.2.1 says that the behavior is undefined in this case.
In short, the sum variable is updated to be the same as k. After that update, k is decremented by 1 and then the loop runs
What that means is...
First loop, sum is uninitialised (hence the first 0)
the last time the loop runs, sum is set to k (1), k is decremented to 0. The loop runs. The condition is tested so the loop exits.
It all comes down the this: sum=k--. If you were to do sum=--k, k would be decremented before its value is assigned to sum.
Your program has undefined behaviour, since it is reading from an uninitialized variable in the first round of the loop (cf. C11 6.3.2.1/2).
Following code :
for(k =7; k >= 0; sum = k--)
//your code here printf("%d \n",sum);
can be expanded as:
k=7;
for(; k >= 0; ){
//your code here printf("%d \n",sum);
sum = k--;
}
In first run sum is uninitialized so your program have undefined behavior.
Try this
#include<stdio.h>
int main()
{
int k=7,sum;
for(sum=k=7;k>=0;sum=--k)
printf("%d \n",sum);
return 0;
}
The loop starts by taking the initial value of the sum which in this case is by default equal to zero as a result the first iteration displays 0 however on the second iteration init of sum takes place and it starts from 7 to onward 0
When k=1 then value of k is assigned to sum and it gets decremented to 0 . Thus sum = 1 and k = 0.
Now k=0 and as per the loop condition k>=0 is true. So it enters into loop body and prints value of sum as 1 . Now value of k is get assigned to sum and k decrements . Thus sum = 0 and k = -1 . But -1>=0 is false and loop execution stops .
Hence program is not printing 0 in the last.

Resources