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.
Related
The following program was cited as going into an infinite loop:
#include<stdio.h>
int main()
{
int n;
for(n = 7; n!=0; n--)
printf("n = %d", n--);
getchar();
return 0;
}
On analyzing, I do find that at one point the value of n does become 0 and right then, the loop should terminate.
Won't it happen such that when it enters the loop for the first time, the value is 7, then it becomes 6, and since that there are 2 post-decrements per iteration?
But, why does that not happen?
Each loop iteration actually decreases n by two, and the comparison n != 0 always sees an odd value for i and hence never terminates.
In particular, just before the iteration in question, n is first decremented to 1 by n-- in the loop header (since this must occur after the end of the previous iteration, just before evaluation of the condition n!=0).
Then, printf("n = %d", n--); is evaluated, printing n = 1, while postdecrementing n to zero. After the end of the loop body, n is decremented again by n-- in the loop header, making it -1, just before the condition n!=0 is evaluated to determine whether the loop should continue.
As a result, n!=0 is true every time it is evaluated (in particular, it is not evaluated at the instant that n is zero, since the n-- in the loop header must first complete)
It's because of the second decrement in the print here:
for(n = 7; n!=0; n--)
printf("n = %d", n--);
That makes the sequence of checks against n go 7, 5, 3, 1, -1, ... There are an even number of values for an int so this will form a cycle upon underflow that leaves out the even numbers, including 0.
Remember that the for loop condition is evaluated just before each loop iteration, and after the decrement in the loop itself. It isn't tested while the loop is running.
try doing this
#include<stdio.h>
int main()
{
int n;
for(n = 7; n>=0; n--)
printf("n = %d", **--n**);
getchar();
return 0;
}
What will be the output of the program?
#include<stdio.h>
void main()
{
int i = 0;
while(i < 10)
{
i++;
printf("%d\n",i);
}
}
Will the output start from 0 or from 1 as I my professor taught me that the value of the variable is incremented only at the end of the loop while using i++ unlike in ++i?
The side effect of incrementing using either the prefix ++ or the postfix ++ occurs before the statement i++; completes. The fact that the statement is in a loop doesn't change that.
Your professor is correct. The first time printf is called in the loop, i will have the value 1 because the previous statement incremented the value.
Had you instead had the following code:
while(i < 10)
{
printf("%d\n",i++);
}
Then 0 would be printed on the first iteration. In this case, the value of i is incremented, but the postfix ++ operator means that the old value of i is passed to the printf call.
will start from 1 since the line i++ ends before you enter the next line which prints, the ++i compared to i++ is different when you increment it while doing something else in the same line/command.
for example: if you use
printf("%d",i++);
it would print 0 before incrementing i but if you put it like this:
printf("%d",++i);
it will first increment i (from 0 to 1) and then print i(which is 1 the first time it's printed).
Your code will print 1 as first value.
i++ increments the value at the end of the statement, and vice versa ++i increments the value before the statement. This is usually used when assigning variables:
i = 5;
int a = ++i; // a=6, i=6
i = 5;
int b = i++; // b=5, i=6
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;
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.
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.