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
Related
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.
the following two programs are supposed to produce all three digit combinations of 1, 2, 3 (with repetition). They are identical in every way, other that where the loop counters are being initialized
#include <stdio.h>
int main(void)
{
short i, j, k;
i = j = k = 1;
for (; i <= 3; i++) {
for (; j <= 3; j++) {
for (; k <= 3; k++)
fprintf(stdout, "%hi %hi %hi\n", i, j, k);
}
}
return 0;
}
...This one where the counters for the three loops are being initialized outside them doesn't produce the desired output. It prints.
1 1 1
1 1 2
1 1 3
The second one...
#include <stdio.h>
int main(void)
{
short i, j, k;
for (i = 1; i <= 3; i++) {
for (j = 1; j <= 3; j++) {
for (k = 1; k <= 3; k++)
fprintf(stdout, "%hi %hi %hi\n", i, j, k);
}
}
return 0;
}
...where the counters are being initialized within each loop, produces the desired output
1 1 1
1 1 2
1 1 3
1 2 1
1 2 2
1 2 3
1 3 1
1 3 2
1 3 3
2 1 1
2 1 2
2 1 3
2 2 1
2 2 2
2 2 3
2 3 1
2 3 2
2 3 3
3 1 1
3 1 2
3 1 3
3 2 1
3 2 2
3 2 3
3 3 1
3 3 2
3 3 3
Read in a book that a for loop can be written in several forms--all of which are identical--and that the counter can be initialized, incremented, tested either inside or outside the for statement. Then why the different behavior here?
Because you don't initialize the variables i, j, k inside the loop but define them in the outer scope, their values remain saved.
In particular k remains 4, after the first loop finishes to run, then the condition k<=3 is always false and the print statement is never reached.
To write the code in the equivalent way to your book meant is that way:
#include <stdio.h>
int main(void)
{
short i, j, k;
i = 1;
for (; i <= 3; i++) {
j = 1;
for (; j <= 3; j++) {
k = 1;
for (; k <= 3; k++)
fprintf(stdout, "%hi %hi %hi\n", i, j, k);
}
}
return 0;
}
In the second one, the variables j and k are reinitialised to 1 each time the for loop is encountered.
In the first one, they are always just left with the value that they had - which means that the second time round (when i == 2 or 3), j is left at 4 from the first time round, which immediately fails the j <= 3 condition.
it's not about how you initialize the for loop, but the fact that each time that you start the for loop you don't initialize it.
for (; i <= 3; i++) {
for (; j <= 3; j++) {
for (; k <= 3; k++)
so for the first time it's fine since the values are correct, but after the 2nd and 3rd for loop finished their iterations and the first for loop reached the 2nd index the other for loops are not being initialized so their values remain 4 and the condition isn't being met, so the loops stop there.
you still need to use the initialization inside the nested for loops regardless to fix the issue.
If you initialize your variables just once, outside the for loops, then their values will never get re-initialized in the nested loops (something you need in order to generate every combination starting with 1xx, 2xx and 3xx).
In the case of the outside initialization:
After you've generated all the 11x combinations, your k variable will have the value 4, regardless of what the enclosing loops do.
So when either j or i increments to 2 and 3, your k will already be 4, hence the innermost for loop will not execute anymore.
Needless to say, the second variant of your code, re-initializes k and j every time i increments, which will then make your code reach the printf every time like you intended.
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.
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 ..........
I am confused by the following code:
#include <stdio.h>
int main()
{
int a[] = {5, 15, 1, 20, 25};
int i, j, m;
i = ++a[1]; /*statement 1*/
j = a[1]++; /*statement 2*/
m = a[i++]; /*statement 3*/
printf("\n%d\n%d\n%d\n", i, j, m);
return 0;
}
Statements 1, 2, 3 are a bit confusing for me; I don't not get the way these are producing the output for me. Can anyone shed some light on this please?
i=++a[1]; /*statement 1*/ // increments the value of a[1] and assigns to i
j=a[1]++; /*statement 2*/ // assign the value of a[i] and then increments the value of a[i] to j
m=a[i++]; /*statement 3*/ // assign a[i] to m, and increment i
i=++a[1]; // a[1] is 15 here so i =16, and a[1] =16
j=a[1]++; // a[1] is 16 so j =16 and a[1] =17
m=a[i++]; // i is 16 here but index 16 does not exists here, so program fails
i = ++a[1]; /*statement 1*/
Hear a[1] will be 15. and Pre Increment operator will increase a[1] with 1 S0 i will be 16
j = a[1]++; /*statement 2*/
Post increment operator will also increment the value of a[1] by 1. so j will be 16.
m = a[i++]; /*statement 3*/
Here, it is i++, so post increment oprator will increase i by 1..earlier i was computed 16 . now i will now be 17.
So a[17] has no value. so m will be junk value
In case of doubt, what you can do is use gdb:
Compile your code setting debug flag (-g for gcc) gcc -g -o so stackoverflow.c
run gdb gdb ./so
identify lines to break list in gdb
set breakpoints break 6 (first break is line 6)
Step forward step
Display values print i or print a[1] for instance.
But beware, if you call print ++a[1] in gdb you may change your program behaviour!
The First Statement
i = ++a[1] ---> Increments the value of a[1] (i.e) i value will be 16
Second Statement
j = a[1]++ ---> Assign the value of a[1] to j and then incremented(i.e) j would be 16.
Third Statement
m = a[i++] --> Assigning value of a[i] to m and i is incremented.