C - While loops once extra after checking condition? - c

I am trying to figure out the following code:
#include <stdio.h>
#define TEN 10
int main(void)
{
int n = 0;
while (n++ < TEN)
printf("%5d", n);
return 0;
}
This prints 1 through 10. Isn't it supposed to print 1 to 9 only, since n++ will make it 10, and the condition while (10 < TEN) would fail hence should exit before printing?
When I change it to while (++n < TEN) I get 1 to 9, which makes sense because the addition is made before the check.
My so far understanding is that the n++ will add after the condition has been checked, hence it will print 10 (since ++n checks before, and n++ check after). Is that correct?
Thanks!

With n++ (postfix increment operator), the value of n gets incremented after the while statement, therefore the while condition n++ < TEN is first verified, and only after the value of n is updated.
When the last iteration of your while instruction while (n++ < TEN) is executed, n is still 9 (and gets incremented by 1 right after) that's why it prints 10 as the last value:
1 2 3 4 5 6 7 8 9 10

Related

Function call in for loop and static variable

#include <stdio.h>
int main() {
int r() {
static int num = 7;
return num--;
}
for(r(); r(); r())
printf("%d",r());
return 0;
}
The output is 52. How i m getting the output is out of my knowledge this question what i had learned about static went totally wrong.
First time you run r() it will return 7, next time 6 and so on.
The for loop will stop when r() value is 0.
The code flow is:
r() // 7 [1st expression in the for loop]
if (!r()) stop for loop; // 6, so goes into for loop [2nd expression in the for loop]
print (r()) // 5
r() // 4 [3rd expression in the for loop]
if (!r()) stop for loop // 3, continues again
print (r()) // 2
r() // 1 [3rd expression in the for loop]
if (!r()) stop for loop // 0 so exits the for loop
It first prints 5, then 2 (without newlines), hence the output is 52.
#include <stdio.h>
int r(){
static int num = 7;
return num--;
}
int main()
{
for(r();r();r())
printf("%d",r());
return 0;
}
the static var is like a global var (I mean not in the stack) but only visible for the function r
the result is 52 because it prints 5 then 2
the initial value of num is 7
the for call a first time r (init part of the for), so num is decremented to be 6 and r returns 7 for nothing,
the test is performed and num is again decremented to be 5 and because 6 is return and is not 0 the for continue,
now the print is done with again a call decrementing num to 4 with the result 5 being printed
r called (modif part of the for) decrementing num to 2 and returning 3 for nothing
again the test decrementing num to 2 and returning 3 != 0 the loop continue
again the print is done with again a call decrementing num to 1 with the result 2 being printed
r called (modif part of the for) decrementing num to 0 and returning 1 for nothing
the test is performed and num is again decremented to be -1 and because 0 is return by r the loop stops

Misunderstanding in basic for loop (C)

I have been going through some exercises from a recommended book I found on this website. I came across this following basic piece of code, which I could not fully understand.
#include <stdio.h>
int main(void)
{
int i;
for (i = 10; i >= 1; i /= 2)
printf("%d ", i++);
return 0;
}
This is my reasoning behind this program fragment:
Variable i is initialised to 10.
i is tested to see if greater or equal to 1, (which is always the case).
The third expression reads: i = i / 2, thus i is divided by 2 and its value stored in i.
In the printf statement i is incremented after each printf statement.
I simply cannot understand why the output of this program is:
1 1 1 1 1 1 1 1 ...
I get that the condition statement is always true, however shouldn't the first values be:
5 3 2 1 1 1 1 1?
Basically I cannot seem to understand why the value of i is straight away being stored as 1. Any corrections regarding my reasoning and/or insight on the matter will be appreciated. Please do excuse the basic nature of this question.
As #abelenky pointed out, the correct output is 10 5 3 2 1 1 1 .... The only mistake you made in your reasoning is that the statement i /= 2 gets evaluated after the body of the for loop, before testing the condition again. Another way to write the same loop would therefore be
for(i = 10; i >= 1; i = (i + 1) / 2)
printf ("%d ", i);
If you are running on Windows, try paging the output through more: myprog | more. This should allow you to see the beginning of the output of this infinite loop. On a linux machine, you could acheive the same result using more or less: myprog | less. Thanks to #EugeneSh for making the suggestion that this could be the issue.
Another way that I have found to view the initial output for programs like this is to hit Ctrl+C immediately after starting the program with Enter. This is not a "standard" method and may require very quick reflexes to get any results for a quick loop like yours.
A final suggestion is to limit the output you produce from the program directly:
int i, count;
for(i = 10, count = 0; i >= 1 && count < 100; i /= 2, count++)
printf("%d ", i++);
This will add a counter that will stop your output after 100 numbers have been printed and allow you to see the first numbers.
On the second line, you have 'i++'.
Thus at each iteration of the loop, it will also increment i by 1.
So supposing i = 1 when you start the loop. First it will be divided by 2 (i /= 2). Since i is an integer, it will become 0. Then, on the second line, you have 'i++', thus incrementing i.
So by the end of the loop iteration, i will be back to being equal to 1 (thus making this loop infinite).

Value after the while loop with post-increment

Please explain me why the last printf gives value 11?
I really don't understand why it happened.
When a = 10 the condition is not fulfilled so why this value has changed to 11?
Incrementation goes as soon as the condition is checked?
Code:
int main(void) {
int a = 0;
while(a++ < 10){
printf("%d ", a);
}
printf("\n%d ", a);
return 0;
}
Output:
1 2 3 4 5 6 7 8 9 10
11
Let's look at a++ < 10 when a is equal to 10.
The first thing that will happen is 10 < 10 will be evaluated (to false), and then a will be incremented to 11. Then your printf statement outside the while loop executes.
When the ++ comes on the right hand side of the variable, it's the last thing evaluated on the line.
Try changing a++ < 10 to ++a < 10, rerunning your code, and comparing the results.
The post increment operator increments the value of the variable before it after the execution of the statement.
Let's take an example,
int k = 5 ;
printf("%d\n", k++ );
printf("%d", k );
will output
5
6
because in the first printf(), the output is shown and only after that, the value is incremented.
So, lets look at your code
while(a++ < 10)
it checks a < 10 and then after that, it increments a.
Lets move to a few iterations in your loop.
When a is 9, the while loop checks 9 < 10 and then increments a to 10, so you will get output for that iteration as 10, and similarly, for the next iteration, it will check 10 < 10 but the while loop does not execute, but the value of a is incremented to 11 and thus, in your next printf() , you get output as 11.
Let's look at a simpler piece of code to show what a++ does.
int a = 0;
int b = a++;
printf("%d %d\n", a, b);
I think that you'd expect this to output 1 1. In reality, it will output 1 0!
This is because of what a++ does. It increments the value of a, but the value of the expression a++ is the initial pre-incremented value of a.
If we wanted to write that initial code at the top of my answer as multiple statements, it would actually be translated to:
int a = 0;
int b = a;
a = a + 1;
printf("%d %d\n", a, b);
The other increment that we have access to is pre-increment. The difference there is that the value of the expression ++a is the value of a after it was incremented.
Because it's post-increment. The compiler will first evaluate a<10 and THEN increment a by 1.

Pointers: why the output is 6?

The output of the program below is 6. I am not able to figure out why. When I trace it out by hand, I am getting 5.
#include<stdio.h>
#include<conio.h>
main()
{
int i,count=0;
char *p1="abcdefghij";
char *p2="alcmenfoip";
for(i=0;i<=strlen(p1);i++) {
if(*p1++ == *p2++)
count+=5;
else
count-=3;
}
printf("count=%d",count);
}
if(*p1++ == *p2++) is reading both p1 and p2 character by character. When the characters are the same, it will increase count by 5, else it will decrement it by 3. But, there is another thing that you didn't pay attention to: strlen(p1) will always be different in each iteration, because p1 will change. So, in each iteration, you also need to check its value.
p1 p2 count i strlen (before entering into the loop body)
a a 5 0 10
b l 2 1 9
c c 7 2 8
d m 4 3 7
e e 9 4 6
f n 6 5 5 <- No more - this is the last one
The trick here is, strlen(p1) changes every iteration. So loop condition goes
0 <= 10 +5
1 <= 9 -3
2 <= 8 +5
3 <= 7 -3
4 <= 6 +5
5 <= 5 -3
So equal characters are a, c, e, shown as +5 above. Total is 6.
Your program stops when i>strlen(p1) because you are changing p1 each time you do *p1++.
When it computes the condition strlen returns the size from the las char.
If you store the value in a variable at the beginning (before your loop) it should work.
Anyway, try to avoid pointer arithmetic...

Why is my loop not going infinite

#include <stdio.h>
#include <cs50.h>
int main(void)
{
int n;
printf("Please give me an integer greater than zero!\n");
n=GetInt();
if(n<0)
{
printf("You are giving me a bad value!\n");
return 1;
}
for(int i=n-1;i<n;n--)
printf("%d\n",n);
return 0;
}
I would like to know why the loop is not going to infinity if the user enters in a number for n. Lets say that the user puts in 40 for n; wouldn't i always be n-1, so 39 and n being 40, then i becomes 38 when n becomes 39 and so on — so wouldn't that make an infinite loop?
for(int i=n-1;i<n;n--)
Lets draw a (really short) table for n = 40:
i | n
-----+-----
39 | 40 i < n ? true
39 | 39 i < n ? false
Thus, we'll exit the loop after the 1st iteration.
Clarification:
I guess you're confused because you think that i is updated in each iteration, but that's the point - it doesn't, its value is fixed and only n is changing.
This loop only runs once. Consider:
for(int i=n-1;i<n;n--)
With n == 40, on the first iteration, i = 39.
The condition i < n is true (39 < 40 == true), so we go in to the loop for the first time.
At the end of the first loop, n gets decremented to 39
The condition i < n is false (39 < 39 == false), so we don't get a second time through the loop.
Now, what happens if we make n increase instead of decrease? Will that run forever?
for(int i=n-1;i<n;n++)
The answer is "maybe, but probably not":
Eventually, n will reach the largest value that can be stored in an integer, INT_MAX (defined in limits.h, and on my system it is 2,147,483,647).
Making an integer larger than INT_MAX causes integer overflow.
The result of integer overflow on a signed integer is undefined, which means the result could be anything (and indeed, your program could crash).
On most systems, however, the value will probably wrap around to INT_MIN, or -2,147,483,648.
If this happens, i < n will be false, and your loop will terminate.
But, since integer overflow on signed integers is undefined behaviour, you can't be sure that this will happen. It is better to write your program to avoid this situation.
If you really want it to run forever - just write:
while(1) { ... }
or
for(;;) { ... }
These two loops have the advantage that they are common ways to write an infinite loop, and so they are easy for other programmers to read.
The reason is that i is never decremented, so it does only 1 loop:
i=39 n=40
i=39 n=39 -> stop
In order to decrement also i you should write:
for(int i = n-1;i<n;n--,i--)
i is only ever set once at the start of the loop. For example if the user enters 10 then i is 9 for the 1st iteration. By the 2nd iteration n is decremented by 1 and i is still 9.
n will underflow somewhen because int is signed and has a value range of -2147483648 to 2147483647 for example (x86).
Somewhen n will get more positive than i.
Edit:
The loop has at most 1 iteration.
Edit 2:
The loop would have no iterations if n would have the value -2147483648 for example because -2147483648 - 1 will make the value positive (two complement integer arithmetic). But this could never the case because the pre condition is that n may not be negative.
Your for loop:
for(int i=n-1;i<n;n--) {
printf("%d\n",n);
}
Translates into the following while loop:
{
int i = n - 1;
while (i < n) {
printf(%d\n", n);
n--;
}
}
The first clause of the for statement performs initialization. It is not repeated at each iteration, but only once. Thus, i never changes value, and so the loop ends after a single iteration.
This happens because you are decrementing n. At the second iteration i < n is false, you are exiting from the loop.
What will happen is:
//Example n = 100
for (int i = 100 - 1; 99 < 100; 100--)
//We now have 99 < 99 on the next loop
//After that you will have 99 < 98 etc.. it will only run once
To make the loop you want use:
for(int i = n-1; i > n ; n--)
To make an endless loop use:
for(;;) //or while(true)
your condition is wrong in the for loop..in your loop i is not changing only n is changing
try this
for(i=n-1;i<n;i--)
{
printf("%d\n",i);
}
you written perfect for loop...
for(int i=n-1;i
#include<stdio.h>
#include<conio.h>
int main()
{
int i;
for(i=0;;)
{
printf("%d",i);
}
return 0;
}
or you can do anything else....
to put in infinite simply make ;; in the other two condition in loop.

Resources