The following is a piece of code that shows an output stating whether a number, entered by a user, is a prime number or not.
#include <stdio.h>
#include <stdlib.h>
int a,b;
int main(void) {
printf("Enter number: ");
fflush(stdout);
scanf("%d",&a);
for (b = 2; b < a; b++)
{
if (a % b == 0)
break;
}
if (b<a)
{
printf ("%d is divisible by %d\n", a, b);
}
else
{
printf ("%d is prime \n", a);
}
return 0;
}
The piece of code, written above, is not mine and it identifies a prime number successfully everytime (i.e the printf statement of the else clause gets printed).
My understanding of the if statement is that an else clause in an if-else statement belongs to the nearest if statement which doesn't already have an else clause. And so, having said that, I believe the else clause, in the above piece of code, belongs to the nearest if statement.
My question is this: If the user enters a prime number like 31 or 37 or any other prime number, how does the printf statement of the else clause get printed?
The condition if (b<a) (of the second if statement) will always be true considering that b will only be incremented to (a-1). And so if the user enters the number 31, the variable b will only be incremented to 30. Shouldn't it be the case that the printf statement of the second if statement gets printed, regardless of whether the number entered by the user is prime or not, considering that the condition if (b<a) will always be true?
How does the above piece of code print all the prime numbers correctly, and therefore, work alright? (when, according to my limited understanding of the way the if statement works, it shouldn't)
The condition if (b<a) (of the second if statement) will always be true considering that b will only be incremented to (a-1).
That is not the case. If no divisor is found, the for loop continues until the condition b<a is false. This happens when b == a, not b == a-1. The loop body isn't run when the loop condition is false, but the increment has happened nevertheless.
This loop
for (b = 2; b < a; b++)
{
if (a % b == 0)
break;
}
can be interrupted in two cases. The first one is when a is divisible by b
if (a % b == 0)
break;
But for prime numbers this condition is always will be equal to false.
So the other case when the loop will be interrupted is when b after increment
for (b = 2; b < a; b++)
^^^
will became equal to a. In this case the condition
for (b = 2; b < a; b++)
^^^^^
will be equal to false and the control will be passed to the if-else statement.
If so then b is equal to a and a is a prime number.
First, you are correct, the whitespace between
if (b<a)
{
...
}
and
else
{
...
}
doesn't matter. The else indeed belongs to the if.
Second, it's not true that the if (b<a) is always true. As long as a % b == 0 never returned true, the loop continues until b==a, which fails the condition. They could have also written if (b!=a).
Related
This question already has answers here:
For vs. while in C programming?
(19 answers)
Closed 5 months ago.
This is a approach for Weather a number is prime or not
QUESTION:
int main()
{
int i, num, b;
printf("ENTER A NUMBER : \n");
scanf("%d", &num);
for (i = 2; i <= num - 1; i++)
{
if (num % i == 0)
break;
}
if (i == num)
printf("PRIME");
else
printf("NOT A PRIME");
return 0;
}
How will the value of i will be incremented if loop is completed..The condition for stopping is num-1 then how in next statement value of i will be == num
Ex: if i enter 5 loop will run till 4 and value of i will be 4 then how will it will be == num..
Hope question is understood.
The body of the for loop is executed as long as the test condition is true. That means, when the loop stops executing because of the test condition (rather than because of the break), the test condition is false.
Therefore, when the loop ends this way, i <= num - 1 is false. Since num is 5, that means i <= 4 is false, which occurs when i has become 5.
I got your point , Let's analyze it together
First let's be clear about prime numbers
A prime number is a number that is only divisible by itself and one
so , if we iterate from 2 till the number - 1 we are including all the numbers in range 2 & number-1 and in case any of those numbers are divisible by our variable
then it's not a prime and we break the loop before it reaches number-1
I see you're confused in the stopping condition
the stopping condition is number!
the loop is valid till number -1
then it increments
so i will be equal to the number and the condition of the loop is not satisfied
in this case we can say that we reached all numbers between 2 and number -1 and found nothing divisible by our variable
hence it's prime
else if the counter i didn't reach the number itself this means that the loop went into a break
and a break means we found a divisible integer
so it's not prime
Hope this helped!
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.
void main()
{
int a, b, r;
//Finf GCD by Eucledian algorithm
scanf("%d %d", &a, &b);
for( ; b == 0; (a = b), (b = r)){
r = a % b;
printf("GCD is %d", a);
}
printf("GCD is %d", a);
}
Somehow this doesn't work.
I assign a to b and b to r, but this doesn't seem to change the value of a or b.
This for(;b==0;(a=b),(b=r)) sets up the for-loop like this
do nothing to init anything
as long as b equals 0 do the loop body
between loop body executions first copy value of b to a,
then copy value of r to b
Note that the loop will never execute if b starts off non-zero.
Otherwise the loop will stop executing as soon as b becomes non-zero, from being updated with value of r.
(This is somewhat compiling an answer from comments, in order to get this out of the list of unanswered questions. Credits to dddJewelsbbb. I offer to delete this if they make an answer and ask me to.)
Find the corrected working code below, which changes the loop condition:
#include <stdio.h>
void main ()
{
int a, b, r;
//Finf GCD by Eucledian algorithm
scanf ("%d %d", &a, &b);
for (; r > 0; a = b, b = r)
{
r = a % b;
}
printf ("GCD is %d", a);
}
Test by giving inputs: 16, 12
16
12
GCD is 4
Code explanation:
The code is the direct implementation of Euclid's algorithm to find GCD. Here the divisor (one of the number) is used to obtain a remainder (after dividing the second number as dividend). Next, the remainder becomes the divisor and the earlier divisor becomes the dividend and this process continues till remainder is zero.
There is plenty of scope in the code to make it more elegant and handle corner cases. I corrected the exact same code as minimum as possible to spot the exact error (which was in the for loop condition).
#import <stdio.h>
int main(void) {
int sum,i;
sum = 0;
for(i=0;i<10;i++) {
if(i%2)
continue;
sum+=i;
}
printf("\n%d",sum);
return 0;
}
How does if(i%2) works in the above code?
In computing, the modulo operation finds the remainder after division of one number by another (sometimes called modulus).% is the modulus operator.
So i%2 returns the remainder left after i is divided by 2.
Therefore if i is odd i%2=1(TRUE)
else it is 0(FALSE).(even condition)
Therefore if i is even i is added to sum else the loop continues.
if condition knows only TRUE or FALSE.
If your modulo operation make a true condition then it will execute continue. Otherwise it will do sum.
**True condition = any number without zero(0)
Here, the % used is called the modulo operator. It checks the remainder of a division.
Regarding the if statement, the C11 standard says, from chapter §6.8.4.1
Syntax : if ( expression ) statement
and
... the first sub-statement is executed if the expression compares unequal to 0.
So, for a statement like if(i%2), the result
is TRUE, when the i value is not a multiple of 2, i.e., produces a non-zero remainder, so continue; is encountered.
is FALSE, when i is perfectly divisible by 2. so, continue; is skipped and
sum+=i; is executed.
That said, there is no #import <stdio.h> in C, it should be #include <stdio.h>
Finaly,
How does if(i%2) works in the above code?
It is used to add all the even numbers up to 9. The result, 20, is then printed out.
The condition in the if statement
if ( i % 2 )
is equivalent to
if ( i % 2 != 0 )
This condition is equal to true if i is an odd number.
So the program finds the sum of even numbers in the range [0, 10 )
According to the C Standard (6.8.4.1 The if statement)
2 In both forms, the first substatement is executed if the
expression compares unequal to 0.
Here "the first substatement" means the if statement (if else is present then it is the second substatement).
It is better to rewrite the loop without the break statement. For example
for ( i = 0; i < 10; i++ )
{
if ( i % 2 == 0 ) sum += i;
}
It is the same as
for ( i = 0; i < 10; i += 2 )
{
sum += i;
}
Few days ago I've a weird idea came into my mind that manipulate if(); statement in a weird way.Let's go on to a simple code.
The Code :
if(printf("blahblah\n");{
}
My Idea :
1.)To me I think this code will always evaluated to be true(my assumption) since the test condition is substituted with a function call.
So today I'm doing an exercise provided by a book(just to help me refresh what i learn few days ago).This is the code.
The Code :
#include <stdio.h>
int main(void) // This program would add up the value enter by user , for e.g with the
{ //input of 20 , it will print out the sum of 1+2+3+4+5.....20.
int count , sum , size;
count = 0;
sum = 0;
printf("Enter a value to find the sum of it from 1 : ");
scanf("%d" , &size);
while (count++ < size)
sum = sum + count;
printf("sum = %d\n" , sum);
return 0;
}
By using my idea on the first code , I modified the second code into this.
#include <stdio.h>
int main(void)
{
int count , sum , size;
count = 0;
sum = 0;
printf("Enter a value to find the sum of it from 1 : ");
while (scanf("%d" , &size) && count++ < size )
sum = sum + count;
printf("sum = %d\n" , sum);
return 0;
}
The Question :
1.)Based on the assumption made by me in the first code , the scanf() function suppose to be always evaluated to true.That's why the second test condition count++ < size is the one that determine whether the statement in while statement will be executed or not.
2.)But when I run the program , I input 30 but it doesn't work , the program just stop there without doing anything after i hit enter.
3.)I try to switch the to test condition with the `count++ < size as left operand while the input function as right operand.
4.)After doing so , the result i get is different.When i try to run the program , the program execute the second printf() function statement , and print out sum = 0.
Your help is much appreciated , do correct me for mistakes.I'm willing to learn from it.
To me I think this code will always evaluated to be true(my assumption) since the test condition is substituted with a function call.
This is incorrect. The function (in this case, printf) returns a value (in this case, an int). When you use it as the condition in the if statement, the function is called and the value it returns becomes the condition: if it returns zero it evaluates to false; if it returns nonzero it evaluates to true.
There is no difference between
if (printf("Hello, World!")) { }
and
int i;
i = printf("Hello, World!");
if (i) { }
(aside, of course, from the additional variable in the second example.)
In your modified second example, scanf is called each time the loop condition is checked. You could rewrite the loop like this:
while (1)
{
int result_of_scanf;
result_of_scanf = scanf("%d", &size);
if (result_of_scanf == 0)
break;
if (count++ >= size)
break;
sum += count;
}
scanf doesn't just get called once; it gets called for each iteration of the loop. scanf returns the number of elements that it read successfully, so in this case it will return either 1 (if you input a valid integer within the range of int) or 0 (if you give any other input).
The program appears to be stuck but actually it is expecting you to input numbers. That is you will have to enter numbers till the count is equal to the input number.