Unexpected Output involving array values with post and pre-increment - c

Shouldn't the output of following program be -
2 3 20
instead it is showing
3 2 15
Can anyone explain the reason behind this?
#include<stdio.h>
main()
{
int a[5] = {5,1,15,20,25};
int i,j,m;
i = ++a[1];
j = a[1]++;
m = a[i++];
printf("%d %d %d",i,j,m);
}

3 2 15
is the correct output.
i is 3, because i became 2 in i = ++a[1]; for pre-increment and then it got post-incremented in m = a[i++];
j is 2, because j = a[1]++;, no changes afterwards.
m is 15 because m = a[i++]; i is being post-incremented, the old value of i (which is 2) is used in indexing and the post-increment on i is sequenced after the evaluation of the = statement.
Having said that, the recommended signature of main() is int main(int argc, char *argv[]) or at least, int main(void).

At this point, values of variables are:
a = {5,1,15,20,25};
i = uninitialized
j = uninitialized
m = uninitialized
Now,
i = ++a[1];
Gets the value of a[i] which is 1, increments it and it becomes 2, and then, it is stored in i.
At this point, values of variables are:
a = {5,2,15,20,25};
i = 2
j = uninitialized
m = uninitialized
Next,
j = a[1]++;
Gets the value in a[1] which is 2 (since it was incremented in the previous statement), stores this value in j and then, increments the value stored in a[1].
At this point, values of variables are:
a = {5,3,15,20,25};
i = 2
j = 2
m = uninitialized
Then,
m = a[i++];
Gets the value in a[i](a[2] since i is currently 2) which is 15 and this value is stored in m. Then, i is incremented.
At this point, values of variables are:
a = {5,3,15,20,25};
i = 3
j = 2
m = 15

3 2 15 is correct
#include<stdio.h>
main()
{
int a[5] = {5,1,15,20,25};
int i,j,m;
i = ++a[1];
j = a[1]++;
m = a[i++];
printf("%d %d %d",i,j,m);
}
Now lets go line by line assume i , j , m equals 0 {better to initialize}
from line 3 , i = ++a[1];
i = 2 as (++ pre increment , change then use , and a[1] = 1 so , i = 2)
from line 4, j = a[1]++;
j = 2 as (++ here is post increment , use then change , a[1] becomes 3 but j is equals to 2)
from line 5, m = a[i++];
i = 2 by line 3 , here ++ post increment then i will increment to 3 but a[2] will be used .
Hence i = 3 , j = 2 , m = 15
Hope you got it ..........

Related

Understanding the math of loops in C

I have these three codes, which do work, but they're not printing what I expected them to print. I don't think I properly understand the math/precedence here and was wondering if someone could help me comprehend.
CODE A
int a;
int b = 1;
for (a = 1; a < b + 4; b++, a = b * 2)
printf("%i\n", a);
I expected it to print out 4, 5. but it's 3, 9. I understand that's correct -- but why?
CODE B.
int a = 5;
int b = 0;
while (a > 3)
{
b += a;
--a;
}
printf("%i, %i\n", a, b);
Admittedly I struggled figuring out the math. It prints out 3, 9 --- but I don't get why.
CODE C.
int a;
int b;
for (a = 7, b = 2; b < a; a++)
b += a - 2;
printf("%d, %d\n", b, a);
This prints out 13, 9 but I got 11, 7.
Let's step through the first loop:
for (a = 1; a < b + 4; b++, a = b * 2)
printf("%i\n", a);
First, we execute the initialization statement, which gives us a=1 and b=1 (b was set earlier in the code).
We execute the test expression (a < b + 4, which is 1 < 1 + 4), which is true, so we continue
We execute the loop body. We haven't performed any operations on a yet, so a is still equal to 1 so our output is:
1
Now execute the update expression, b++, a = b * 2. This
increments b (giving us b=2), and then sets a = b * 2, so a = 4.
We execute the test expression, and 4 < 2 + 4, so we continue.
We execute the loop body, which gives us as output:
4
We execute the update expression. We increment b, giving us
b=3, and then set a = b * 2, giving us a = 6.
We execute the test expression, and 6 < 3 + 4, so we continue.
We execute the loop body, giving us as output:
6
We execute the update expression. We increment b, giving us
b=4, and then set a = b * 2, giving us a = 8.
We execute the test expression. 8 < 4 + 4 is false, so we exit
the loop.
You can walk through a similar process for the other loops.
What might be part of the source of confusion is that a for loop in c will execute until the first semicolon found in the source code if there is not a surrounding pair { ... } to delineate several lines of code. For code A, the stuff after the second semicolon in the for loop is executed on every iteration and the printf statement is executed on every iteration too. In the last code snippet, code C. The printf is only executed after all the iterations of the for loop have completed. The same is true of the while loop in code snippet B, the printf executes after the while terminates. The while loop use of {...} delimiting characters makes this more obvious to the reader while the for loops do not.
Of course you still need to work through the calculations themselves too-which are also fairly tricky.
A for loop consists of the following structure:
for ( init; condition; increment ) {
statement(s);
}
As for how this actually executes, it is exactly equivalent to the following:
init;
while(condition) {
statement(s);
increment;
}
So, if we have the following code (CODE A):
int a;
int b = 1;
for (a = 1; a < b + 4; b++, a = b * 2)
printf("%i\n", a);
That means:
init: a = 1
condition: a < b + 4
increment: b++, a = b * 2
statement(s): printf("%i\n", a);
We can translate that into a while loop by substituting:
int a;
int b=1;
a = 1;
while(a < b + 4) {
printf("%i\n", a);
b++, a = b * 2;
}
Now, we can trace the execution step by step to see what's happening.
First loop:
1. b=1
2. a=1
3. a < b + 4
1 < 1 + 4
1 < 5
true
4. Output: 1
5. b++
b = b + 1
= 1 + 1
= 2
6. a = b*2
= 2*2
= 4
Second loop:
1. a < b + 4
4 < 2 + 4
4 < 6
true
2. Output: 4
3. b++
b = b + 1
= 2 + 1
= 3
4. a = b*2
= 3*2
= 6
Third loop:
1. a < b + 4
6 < 3 + 4
6 < 7
true
2. Output: 6
3. b++
b = b + 1
= 3 + 1
= 4
4. a = b*2
= 4*2
= 8
Fourth loop:
1. a < b + 4
8 < 4 + 4
8 < 8
false
2. End
Looking at Code A:
int a;
int b = 1;
for (a = 1; a < b + 4; b++, a = b * 2)
printf("%i\n", a);
b is set to 1;
a is set to 1;
a (1) is less than b + 4 (5), so the loop executes the printf(), printing 1;
b is incremented to 2; a is set to 4 (b * 2);
a (4) is less than b + 4 (6), so the loop executes the printf(), printing 4;
b is incremented to 3; a is set to 6 (b * 2);
a (6) is less than b + 4 (7), so the loop executes the printf(), printing 6;
b is incremented to 4; a is set to 8 (b * 2);
a (8) is not less than b + 4 (8 too), so the loop terminates.
You can apply a similar technique to the other cases.
Looking at Code B:
int a = 5;
int b = 0;
while (a > 3)
{
b += a;
--a;
}
printf("%i, %i\n", a, b);
a is set to 5;
b is set to 0;
a (5) is greater than 3 so the loop body executes;
b (0) has a (5) added to it, so it becomes 5;
a is decremented, so it becomes 4;
a (4) is greater than 3 so the loop body executes;
b (5) has a (4) added to it, so it becomes 9;
a is decremented, so it becomes 3;
a (3) is not greater than 3 so the loop terminates;
The printf() statement prints a then b, so the result is 3, 9.
Looking at Code C:
int a;
int b;
for (a = 7, b = 2; b < a; a++)
b += a - 2;
printf("%d, %d\n", b, a);
a is set to 7;
b is set to 2;
b (2) is less than a (7), so the loop executes the assignment operator;
a - 2 is 5 so b is set to 7 (2 + 5);
a is incremented to 8;
b (7) is less than a (8), so the loop executes the assignment operator;
a - 2 is 6, so b is set to 13 (7 + 6);
a is incremented to 9;
b (13) is not less than a (9), so the loop terminates;
The printf() statement prints b then a, so the result is 13, 9.

Wrong value being printed by printf

I have this piece of C code
#include <stdio.h>
int main(){
int i , j , m , A[5]={0,1,15,25,20};
i = ++A[1];
printf("%d:\n",i);
j = A[1]++;
printf("%d:\n",j);
m = A[i++];
printf("%d:\n",m);
printf("%d %d %d",i,j,m);
return 0;
}
and It's output is
2:
2:
15:
3 2 15
Shouldn't the printf print the values as 2 , 2, 15 but why is it printing 3 , 2, 15
P.S : I really didn't abuse this code , someone else did (my professor perhaps) and I'm just learning C .
The line
m = A[i++];
will increment the variable i in-place after it gets the cooresponding value from the array A.
i is incremented as a part of below statement
m = A[i++];
Lets see what we got here..
int i , j , m , A[5]={0,1,15,25,20};
i = ++A[1]; // takes the value of A[1], increment it by 1 and assign it to i. now i = 2, A[1] = 2
printf("%d:\n",i);
j = A[1]++; // takes the value of A[1](which is 2), assign it to j and increment the value of A[1] by 1. now j = 2, A[1] = 3
printf("%d:\n",j);
//remember the value of i? its 2
m = A[i++]; // takes the value of A[2](which is 15), assign it to m and increment the value of i by 1. now m = 15, i = 3
printf("%d:\n",m);
printf("%d %d %d",i,j,m); // Hola! we solve the mystery of bermuda triangle :)
return 0;
m = A[i++];
this code assign A[2] which is 15 to the variable m ,and then +1 to the current value of i to become 3.

What is the process behind this output?

The value of i is 2 when I comment out statements 2 and 3, but when I don't, i becomes 3. Why is that?
#include <stdio.h>
int main()
{
int a[5]={5,1,15,20,25};
int i,j,k=1,m;
i=++a[1]; //Statement 1
j=a[1]++; //Statement 2
m=a[i++]; //Statement 3
printf("%d %d %d",i,j,m);
return 0;
}
In Statement 3, your code is incrementing the value of i:
m = a[i++];
This is easier to notice is you break it up as the following two lines:
m = a[i];
i++;
Note: The order is important! Since this is post-increment (i++, not ++i), the value of i is used first, and then incremented.
m=a[i++] causes i to be incremented by one. It is the i++ part that increments i.
after statement 1: i = a[1] + 1 which means you are adding 1 to a[1] then storing that value in i
i = 2 ; a[1] = 2'
after statement 2: j = a[1]++ which means you are adding 1 to a[1] i.e 2 + 1
j = 2; a[1] = 3;
after statement 3: m = a[i + 1] which means you are adding 1 to the index value
i already equals 2 so you do m = a[2+1] which is 15 but since you have i++ that operation still preforms the add to i making i =4
m = 15; i = 4; thus a[i] = 20

For loop confusion in C

This is a question from a practice test that I do not fully understand.
For the code fragment
int i = 0, j = 0, k = 0;
for (i=-1; i<=10; ++i){
j = i; ++k;
}
I am asked to find the values of the variables after executing the code.
The answers are:
i = 11 j = 10 k = 12
I don't understand how, can someone please help?
Understanding the value of i after the loop is very simple, much simpler than the sorts of other answers here. The loop condition is i<=10 ... in order for the loop to terminate, that condition must be false. Clearly, the value of i that makes that false is 11.
The value of j at the end of the loop is the previous value of i, which is 10, and the value of k is the number of times the loop executed, which is 1 (for -1) + 1 (for 0) + 10 (for 1 thru 10) = 12.
i must be <= 10, so it is 11 to exit the loop and inside the last iteration of the loop, i = 10 = j. k is 1 after the first iteration, while i is -1. Running through the loop, you'll see:
k = 1, i = -1
k = 2, i = 0
k = 3, i = 1
k = 4, i = 2
k = 5, i = 3
k = 6, i = 4
k = 7, i = 5
k = 8, i = 6
k = 9, i = 7
k = 10, i = 8
k = 11, i = 9
k = 12, i = 10
Therefore k = 12
Here are the steps:
When the loop begins, all three variables are zero.
The loop initializer sets i to minus 1.
Loop test: i <= 10 is true, so loop is entered.
Inside the loop, j is set to i, so j is also minus 1.
k is incremented, so k becomes 1.
the iteration ends; i is incremented because of the ++i, so i becomes 0.
Loop test: since i is zero, i <= 10 is true, so the loop is entered again.
In this way, the loop continues, changing j, k, and i in that order. So when i becomes 10, j will be 9 and k 11. At that point:
The loop is entered for the last time.
j becomes 10 as well; k becomes 12
Then i gets incremented to 11. The loop condition i <= 10 is false, and the loop terminates.
So i is 11. j is 10, k is 12 when the loop terminates.
The key point is, after the first pass, every time the loop is entered, j is one less than i, and k is one greater than i. When the loop terminates, this is still the case.
for (i=-1; i<=10; ++i){
j = i; ++k;
}
Here is the loop :
i = i +1; <-------+
| |
check condition!------|--+
| | |
j = i; | |
| | |
k++;----------------+ |
| |
+<--------------------+
|
other code
at last loop
i = 10
condition == true
j = 10;
k = 12;
Then
i= i+1 means i = 11 but the condition show false! loop end.
Take three variables separate.
You can see the variable k would be incremented , the number of times the loop is executed.
The no. of time sit would be executed from -1 to 10 it would have done 12 iterations
k = 1, i = -1, j=-1
k = 2, i = 0, j=0
k = 3, i = 1, j=1
k = 4, i = 2, j=2
k = 5, i = 3, j=3
k = 6, i = 4, j=4
k = 7, i = 5, j=5
k = 8, i = 6, j=6
k = 9, i = 7, j=7
k = 10, i = 8, j=8
k = 11, i = 9, j=9
k = 12, i = 10, j=10
After This i has reached its limit, but it will first increment and then check,
hence i=11, k=12 and j to a one less than the value of i i.e j= 10

Pointer in C, don't understand how they got this result

here is code snippet
void F (int a, int *b)
{
a = 7 ;
*b = a ;
b = &a ;
*b = 4 ;
printf("%d, %d\n", a, *b) ;
}
int main()
{
int m = 3, n = 5;
F(m, &n) ;
printf("%d, %d\n", m, n) ;
return 0;
}
answer
4 4
3 7
I see how 4 4 was computed, I don't get how they got 3 7 (I do understand how 3 is computed, it is not changed since it was not passed by reference)
Thanks !
I've annotated the F function with comments to explain what's going on:
a = 7 ; // a is now 7
*b = a ; // b points to n, so n is now 7
b = &a ; // b now points to a and no longer to n
*b = 4 ; // a is now 4. n is unaffected
At the start of main, we have
m=3 n=5 // int m = 3, n = 5;
then we call F(m, &n), passing m by value, and n by pointer
such that
m = 3 n = 5
a = 3 b->n // F(m, &n);
Now, inside F(), we assign 7 to a:
m = 3 n = 5
a = 7 b->n // a = 7
then we assign a (=7) to the memory address pointed by b (->n)
m = 3 n = 7
a = 7 b->n // *b = a;
next we change b, so that now b points to a:
m = 3 n = 7
a = 7 b->a // b = &a;
and then we assign 4 to the memory address pointed by b (->a)
m = 3 n = 7
a = 4 b->a // *b = 4;
printing a (=4) and *b (->a =4)
and printing m (=3) and n (=7) outside the function
Take a close look at this line
b = &a ;
*b = 4 ;
b gets the reference of a (it's memory address). When you now access *b it points to the memory of the variable a, not to n anymore
Quite subtle indeed. :)
In F a lot of nonsense happens: whichever value is passed via a, it's discarded, and instead 7 is assigned to it. Then, the value of a (which is 7) is assigned to the variable to which b points (which is n, so it's here that n becomes 7).
At the next line, the object to which b points is changed, so that b now points to the local parameter a, and at the following line the object pointed by b (=>a) is set to 4.
Thus, now we have a that is 4, b that points to a (=>so *b==4, since *b==a), m is still 3 (it was passed by value, so it couldn't have been changed by F) and n was set to 7.
By the way, this is exactly the mess you shouldn't to at all in your applications to avoid confusing any people who have the disgrace to work on them. :)

Resources