Explain the output of the given code - c

In the below code, variable i has been declared globally as well as locally in the for loop . Due to high precedence of local variable, i will be initialized with the value 10 . But in the first occurrence of the loop, due to i++in the for loop, value of i will become 11, so should it not exit the loop after the first instance only?
#include<stdio.h>
int main(){
int i;
for(i=0;i<5;i++){
int i=10;
printf(" %d",i);
i++;
}
return 0;
}
P.S: The answer is 10 10 10 10 10

Precedence is not just about initialization. The variable i inside the loop body is a different variable from the one outside. It "shadows" the outer i, making it inaccessible in the loop body.
The loop control statement is outside the loop body. Its i is the outer i, and nothing done to the inner i has any effect on it, so it starts at 0 and counts up to 5. At each loop iteration, the inner i is re-initialized to 10, and that's the one that gets printed.

The reason it always prints is because the inner i shadows the outer i. For the same reason the i++; inside the loop increments the inner i, not the i that's used as the for loop counter.
But the i that controls the loop gets incremented after the scope of the inner i is over and has no relation to i++; done inside the loop. It's completely independent of the inner i and thus the loop runs 5 times.
GCC provides an option to warn about such shadowing: -Wshadow.

Yet another answer because there is one aspect missing so far. If you change your code slightly:
#include<stdio.h>
int main(){
int i;
for(i=0;i<5;i++){
static int i=10;
printf(" %d",i);
i++;
}
return 0;
}
You will get a more "expected" result:
10 11 12 13 14
A variable inside a block stops to exist after the block (read: pair of curly braces) is left (and it is left here after every step to execute the control statements of for) ... so with your original code, you get a new inner i each time. Declaring the inner i static still doesn't change the scope (it is only visible inside the loop body), but makes the variable survive and still be available when the same block is entered again.

Yes the answer is correct.
As loop iterates 5 times and for every iteration i inside loop is set to 10 and outer one is overshadowed by inner one. After i=10 its value is printed therefore 5 times 10 is output.

Related

error: use of undeclared identifier 'finalTotal'

When I compile this simple code the output is the above error.
So how to declare finalTotal outside while loop?
while (total<endn)
{
int finalTotal = (total + total/3 - total/4);
}
printf("no of years is %i\n", finalTotal)
NOTE:total and endn are part of the total code but not necessary for the question.
You can simply move the declaration of finalTotal as an int to before the loop.
int finalTotal = 0; // declare and initialize to 0 in case while loop does not run
while (total<endn)
{
finalTotal = (total + total/3 - total/4);
}
printf("no of years is %i\n", finalTotal)
This does look like an infinite loop though, as neither total nor endn seems to change.
You need to read up on scope. Variables can only be accessed within their scope. Since you declare int finalTotal inside of the while loop, only other statements inside of the while loop can access it.
Instead you need to declare your variable in the outer scope, so that the following printf can access it.
For example:
int finalTotal; // Declared outside of the while loop.
// You may want to consider initializing it
// with some value in case the while-loop
// never executes. (Such as -1 or something
// to signal an invalid number of years).
while (total<endn) // NOTE: This may infinite loop. Perhaps a typo?
{
// This scope has access to `finalTotal` since it was declared
// by an outer scope.
finalTotal = (total + total/3 - total/4);
}
// Now `finalTotal` can be accessed here, since it's within the same
// level of scope and not stuck inside the scope of the while-loop
// curly braces.
printf("no of years is %i\n", finalTotal)
As mentioned by others, another problem is that the while loop may never terminate since total and endn are not changing inside of the while loop. So it will potentially iterate forever.
Perhaps this was intended to be while (finalTotal < endn).

For loop with ; in C [duplicate]

This question already has answers here:
For Loops and stopping conditions
(4 answers)
Closed 2 years ago.
While studying for my exam I saw a question which is as shown below can someone please explain to me that does the ';' means at the end of the for loop and can I also put it in a while loop? And what is the difference between the Compile-time error and the Compilation error?
#include <stdio.h>
int main(){
int value;
for ( value = 1; value <= 15; value+=3);{
printf("%d", value);
}
return 0;
}
This is probably a mistake; it is syntactically correct, but actually would be read by the compiler like this:
for (value = 1; value <= 15; value+=3);
// Unrelated block!
{
printf("%d", value);
}
This means that the loop will execute, then run four more times, but not actually do anything, then the block will execute once.
Where the loop and the block following it are completely separate and unrelated.
The semicolon ; terminates the definition of the loop body. In this case there are no statements in the body of the loop, hence the only affect of the loop is to modify the value of the counter variable, value.
The statement following the semicolon has it's own scope thanks to the curly braces, but it has no real affect in this case.
The printed result will be the value of value after the (empty) loop has executed, i.e. 16.
You could not do the same with a while loop because the variable would need to be incremented within the body of the loop and the value tested at each iteration to decide whether to continue looping.
Of course, you could avoid any loop by initialising value to 16.

Scope of variables in "for" loop

What I have known so far is, multiple declarations inside a block produce an error message and also uninitialized local variable gives garbage value on printing.
But coming across an example of for loop in C has shaken my concept on the scope of variables.
Below is the code for the same:
#include<stdio.h>
int main()
{
int i;
for(int i = 5; i > 0 ; i--){
int i;
printf("%d ", i);
}
}
The above code produces the output
0 0 0 0 0
I have two questions
A for loop is considered as one block then how two different memories are allocated for two declarations of same variable i? And if the first line of for loop and its body are considered as two blocks, then how to identify different block?
Inside the body of the loop, the variable i is uninitialized, then how is it taking the value as 0, as it should be having garbage value?
Please, explain this.
The scope of a variable declared in the first part of the for loop is all three parts of the for plus the loop body. In your case the body of the loop is a compound statement, and you declare another variable named i in that block, so it masks the i declared in the for.
So in your piece of code there are three relevant scopes:
The body of the main function
The three parts of the for loop.
The body of the for loop.
And each of them is "internal" to the other, so a variable declared at one of these scopes masks a variable of the same name in a higher scope.
To further illustrate this, if we modify your code as follows:
int main()
{
int i = 9;
printf("outer i: %d\n", i);
for(int i = 5;i>0;printf("middle i:%d\n", i),i--){
int i = 7;
printf("inner i: %d\n",i);
}
printf("outer i: %d\n", i);
}
The output is:
outer i: 9
inner i: 7
middle i:5
inner i: 7
middle i:4
inner i: 7
middle i:3
inner i: 7
middle i:2
inner i: 7
middle i:1
outer i: 9
As for why your code is printing 0 inside of the loop, an uninitialized variable may have any value, including 0. So just because it's printing 0 doesn't mean it's not garbage.
A block is anything in curly braces. A block doesn't have to follow a for do, while, if, etc. Literally any set of statements can be enclosed in their own block scope using curly braces.
The i in the for loop is not in the loop body scope since it is outside the curly braces. The i in the block is indeed uninitialized and contains garbage. Garbage usually just means "whatever was there before". As often as not, that value will be zero. That doesn't make it any less garbage.

Output of a simple for loop?

I'm VERY new to c programming. The output of the following program is
One Two Two One but I don't know why. Can anyone explain this to me?
#include <stdio.h>
{
int i, j, k = 100;
for(i=0;i<2;i++)
{
printf("One");
for(j=0;k;j++)
{
printf("Two");
k -=50;
}
}
return 0;
}
Outer loop:
The outer for loop executes twice. Because i starts at 0, the condition i<0 is satisfied, so it runs. After it runs i gets incremented to 1, runs again, i gets incremented to 2, then doesn't run because the condition i<2 is no longer satisfied. That is where your two outputs of "one" come from.
Inner loop:
Every time the outer loop runs it creates the inner for loop. j starts at 0 but the condition for the inner loop is just k. At first, k is set to 100. Here's where it gets messy. In order for a for loop to run, the condition must be "not false". False can be either a numerical value of 0 or just null. Since it's not either one of those the inner for loop runs, and unless the condition is manually changed by something outside the for loop, it will run forever. Luckily it is in fact being changed inside the for loop and after running twice (and outputting two twice), the value of k is now 0 and exits the loop.
Put 'em together:
To summarize, the order of execution is:
outer loop (i=0, "one" gets printed)
inner loop (j=0, k=100, "two" gets printed)
inner loop (j=1, k=50, "two" gets printed)
k=0, inner loop completes (notice the j didn't get used here)
outer loop (i=1, "one" gets printed)
k=0, inner loop does not execute even once
i=2, outer loop completes

for(++i;++i;++i) the second argument is < or <=?

In this for loop statement
#include<stdio.h>
int main()
{
static int i;
for(++i;++i;++i) {
printf("%d ",i);
if(i==4)
break;
}
return 0;
}
Variable i is at first 0. The arguments in the for-loop at 1st round are 1st ++i: i = 0 + 1 = 1 2nd ++i: i=1+1=2 So, in first loop I have this for(i=1; i<2; ++i); or for(i=1; i<=2; ++i);?EDIT I found this example online in a test about C. I run this (inside the for-loop , I have a break point so after some loops it breaks) but I was just guessing the behavior of that so I asked it here to be sure. I am learning now C so stupid questions exists for me. Its better to ask, than not.
In the second argument it is actually ++i!=0, The loop is interpreted as
for(++i;++i!=0;++i)
If you start with a positive i or 0, it will be an infinite loop and will invoke undefined behavior when i reaches INT_MAX.
If i was -Ve initially the loop may stop at a defined run.
EDIT: As you changed your question, Your code will not crash, but you can clearly understand the dry-run by replacing the second ++i with ++i!=0.
So the 1st iteration becomes:
(i=1;2!=0;++i/*this will execute later*/)
2nd iteration becomes:
i=3 //this is from the 1st iteration last part.
(/*initialization is done 1st time only*/;4!=0;++i/*again, this will execute after this iteration*/)
It will print 2 4.
Before the for loop, i will be 0. It hasn't been assigned anything yet, and static variables are guaranteed to be zero initialized before they are first used.
It will execute the first ++i in the for loop, since that expression is evaluated once at the beginning of the loop. i will be 1.
It will execute the second ++i, because that is evaluated BEFORE every loop to see if it should run an iteration of the loop. i will be 2.
It will run the loop body. This will print 2.
The if condition won't be true so it won't break.
It will execute the third ++i in the for loop statement, since it evaluates that AFTER every iteration. i will be 3.
It will execute the second ++i again, since it needs to see if it needs to run another loop. It will be nonzero, so it will run another loop. i will be 4.
It will print 4.
The if condition will be true, it will break out of the loop.
However, it is a nonsense way to do it. This is a more appropriate way to do that:
int i;
for (i = 2; i <= 4; i += 2)
printf("%d ", i);
or better yet:
printf("2 4 ");
static int i;
While the C standard guarantees that variables with static storage duration are initialized to 0, you should not abuse that. Always initialize your variables, either at the line where they are declared or in runtime. So change this to static int i=0;
The first ++i is indeed equivalent to having i=1 there. Esentially your loop does this:
for(i=1; loop_until_program_crash; i++)
If you have a break inside the loop, then the loop is likely poorly written. If you know in advance when the loop should end, then that condition should be inside the for loop condition. If you don't know in advance, then use a while loop instead.
It should be :
for(i=1; i<=2; ++i);
static int i=0;
for(++i;++i<=2;++i)
{
printf("4rth :%d\n",i);
}
see : http://ideone.com/TGLYlL

Resources