Bug in the code - c

This code is always printing
fine Rs. 1
Despite number of days entered is > 30. What is the reason?
#include<stdio.h>
int main(void)
{
int days;
printf("enter no. of days");
scanf("%d",&days);
if (days<=5){printf("fine 50 paise");}
else if (5<days<=10){printf("fine Rs. 1");}
else if (10<days<30){printf("fine Rs.5");}
else printf(" memebership cancelled");
}

change
if (5<days<=10)
to
if (5<days && days <= 10)
same for other(s).
Otherwise, in your code, the condition check behaves like
if ( (5 < days) <=10)
so, whatever value you enter for days [6 and above, keeping the first if in mind], the result of the < operation will always produce either 0 or 1, both being <= 10, thus making the condition TRUE, printing fine Rs. 1.
Related Reading: C operator precedence.
Note: It's a good practice to add a return statement before the closing } of main()

C parses statements (such as if(5<days<=10)) in pieces, rather than trying to interpret them holistically. What this means is that the compiler reads if(5<days<=10) as if((5<days)<=10). Note that this means that the result of 5<days is compared to 10, not the variable days. To expand, the result of any comparison operator (<, >, ==, etc) is an integer representing whether it is true or false (this is called a boolean value, a value which is either true or false), 1 or 0 respectively. So, assuming 5<days is true, the next comparison is 1<=10 (or 0<=10 if days is smaller than 5), which of course is always true.
To fix this, use the comparison operator && (and). if(5 < days && days <= 10) is parsed as ((5 < days) && (days <= 10)), so you are correctly first comparing the days variable to 5 and 10, then taking the truth value of each of those statements and seeing if 5 < days and days <= 10 is true.
One last point - 0 is always false, any non-zero is always true, so if(0) will always be false and if(5) will always be true.

It's due to the second if condition, i don't know if it is allowed to use condition the way you used in you code as:
if (5<days<=10)
edit it to
if(days > 5 && days <= 10)
and it will work, also edit the third condition accordingly.

if (5<days<=10)
is not of the right syntax
it should be
if(5<days && days<=10)
change it and your problem should be solved. :)

Related

Conditional expression in ternary operator in C

Code
#include <stdio.h>
int main() {
int i;
for (i=1; i<=10; i++) {
(i % 2) ? printf("%d is odd\n", i) : printf("%d is even\n", i);
}
}
Result
1 is odd
2 is even
3 is odd
4 is even
5 is odd
6 is even
7 is odd
8 is even
9 is odd
10 is even
In the above C program, why it still works fine even though the conditional expression only states i%2 and not i%2!=0 ?
In C, integers can be used in a Boolean context, and zero represents false while non-zero represents true.
That's why your code works. The expression num % 2 will be 0 (the single false value) for an even number and 1 (one of the many possible true values) for an odd number.
The following expressions would all work for detecting an odd number:
num % 2
(num % 2) != 0
((num % 2) != 0) != 0
... and so on, ad untilyougetboredum (like 'ad infinitum' but with limits).
Having said that, I don't really consider it a good idea to do it this way, code should express intent as much as possible and the intent here should be to choose the path of execution based on a comparison. That means, if you're looking for an odd number, you should use something like (num % 2) == 1.
You also don't need a separate printf call in each of those code paths:
printf("%d is %s\n", num, ((num % 2) == 1) ? "odd" : "even");
You'll notice I've also used num instead of i. This is simply a style thing of mine, related to the afore-mentioned intent. If the variable is only used as an index, I'm happy to use the i-type variables(a) but, the second it gains a semantic property (like a number being checked for oddity), I tend to use more descriptive names.
I have no issue with people using simple variable names, I just prefer more descriptive ones in my own code.
(a) Actually, I'd probably use idx in that case but that's being too CDO(b), even for me :-)
(b) OCD but in the right order :-)
C doesn't have a dedicated boolean type. It uses int value as boolean. That is 0 is considered false and any non zero value is treated as true.
Try printing some conditions
printf("%d",5==5);
printf("%d",1>3);
This will output
1 and 0.
C always uses 1 to denote true. But any other non-zero value would work as well when using in conditions.
if(6+1)
printf("TRUE");
Will print TRUE.
This is also the reason we can use this form of while loop:
int i= 10;
while(i--){
printf("%d",i);
}
Will print 9876543210. Notice it stops when i becomes 0, which is false.
Now back to the question, i%2 would always result in either 0 or 1. In case of 1(true) the first statement is run while in case of 0 (false) the second statement is run.

C Integer range must meet 3 different conditions

If I wanted to limit the range of values to be assigned to an integer to three different conditions. eg; Must be between 9 and 95 and also be divisible by 5 would this be the correct way to accomplish this?
I've been told that i can have multiple conditions as long as they are separated by && but I am having little success with my code.
if (input >= 5 && input <= 95 && input %5)
Your code seems fine to me, except for this line.
if (input >= 5 && input <= 95 && input %5)
The expression input % 5 returns the remainder of input/5. You want input to be divisible by 5, which happens when input % 5 returns a remainder of 0. Since C interprets 0 as false, and pretty much all other integers as true, this expression will do exactly the opposite of what you want it to do. Try using
if (input >= 5 && input <= 95 && (input % 5 == 0))
That should do what you want it to do.
There are a number of issues with your code as it stands. First, the outright bugs:
The expression input % 5 will give you the remainder when divided by five. This means you will get zero if it is a multiple, non-zero otherwise. Unfortunately, zero is treated as false so this will only be true if input is not a multiple. The correct expression is (input % 5) == 0.
If you enter something that cannot be interpreted as an integer, the scanf will fail and input will be left at whatever value it was beforehand. This should be caught and acted upon, by checking the return value - this gives you the number of items successfully scanned so should be one.
Your code seems to return the value if okay but return nothing if it's invalid.
Next, while not bugs, these things are my personal preferences which can make code easier to read and maintain:
I prefer to explicitly separate sub-expressions so I never have to worry about precedence rules (provided it doesn't make the expression unreadable in the process). To that end, I would make the full if statement if ((input >= 5) && (input <= 95) && ((input % 5 == 0)).
I'm not a big fan of the if (condition) transferControl else ... construct since the else is totally superfluous.
I also prefer error catching to be done in a localised fashion at the start, catching problems early. Only after all checks are passed do you do the success portion.
A function (assuming it is a function, which seems likely) should generally do one thing, such as check if the value is valid. Writing issues to standard output is probably best left to the caller so that the function is truly re-usable. It would be better to have a function do the check and return some value to indicate whether or not there was a failure, along with the value if valid.
It's usually better to use puts("something") rather than printf("something\n"). The printf call is best left to where you actually need to do argument formatting.
Taking that all into account, the code that I would posit would be along the lines of:
#include <stdbool.h>
bool InputValidRangeAndMultiple(
unsigned *pValue,
unsigned minVal,
unsigned maxVal,
unsigned multVal
) {
unsigned input;
// If no unsigned int available, error.
if (scanf("%u", pValue) != 1) return false;
// If value invalid in any way (range or multiple), error.
if ((*pValue < minVal) || (*pValue > maxVal)) return false;
if ((*pValue % multVal) != 0) return false;
// Value is now deemed okay.
return true;
}
Calling that function can be done thus, with the prompts and errors handled outside the "input and check" function:
#include <stdio.h>
unsigned value;
puts("Enter Value.\nValue must be divisible by 5 and within 5 and 95...");
if (! InputValidRangeAndMultiple(&value, 5u, 95u, 5u)) {
puts("Invalid input...");
returnOrDoSomethingIntelligent();
}
// The 'value' variable is now valid.

zero is greater than or equal to zero evaluates to false

i = 0;
if(0 <= i <= 0)
this returns false.
I don't understand this at all. Watch window I also tried making the statement read (0 <= i && i <= 0) when I test them individually 0 <= i returns false while i <= 0 returns true. they both should be true. I'm not sure if this is a precision thing but I wouldn't think so since I'm hard coding the values in. Please help me understand this fundamental problem.
If it helps I am trying to evaluate if a point is on a line by getting the intersection point and then checking if it's between the x and y start point and end point. this becomes a problem when I am trying to check when x or y is on its axis then you run into the problem of checking if 0 is between or equal to 0 and 0. Which it is so it would fall on the line.
Chaining of relational operators is not possible (to produce a valid result as per the expectation), you need to write separate instruction to verify each condition.
Due to the absence of explicit parenthesis and LTR association, a statement like
if(0 <= i <= 0)
is evaluated as
if( (0 <= i) <= 0)
which boils down to
if ( 1 <= 0)
which produces a 0, (FALSE).
That said, the claim pertaining to
I also tried making the statement read (0 <= i && i <= 0) when I test them individually 0 <= i returns false while i <= 0 returns true. they both should be true
is not correct, they both are true. See for yourself

I am facing difficulty to understand this program [duplicate]

This question already has answers here:
How is i==(20||10) evaluated?
(2 answers)
Closed 7 years ago.
#include <stdio.h>
int main(void)
{
int i=10;
if(i==20 || 30)
printf("True");
else
printf("False");
return 0;
}
//Gives output:True
//Please tell me how this if loop is getting evaluated
There is no loop here..
Just one condition check, which has the following condition.
if(i==20 || 30)
First, you should know, any non-zero value is taken as True in a condition check.
So, first i is checked with the value 20, if thats true then True is printed, else it checks the next condition as there is an OR inbetween. SInce the next condition is non-zero which is always true, therefore it goes inside and prints True.
NOTE: This program will always print True, as the next condition is always true, and there is an OR in between which needs only one of the conditions to be true.
I have a feeling you want to check "if i is 20 or 30". The syntax for that is "if ( i is 20 ) or (i is 30)". The translation of that logic into code is:
if ( i == 20 || i == 30 )
When you use
if ( i == 20 || 30 )
it is translated as:
if ( (i == 20) || 30 )
regardless of what (i == 20) evaluates to, the conditional expression will always evaluate to "true" since 30 is a non-zero value.
Your if statement as two conditions
First is (i==20) and second is 30
The second conditions is 30 which is always true.
For "OR" operation any one true is enough to execute the if statements
So the statements under if are executecd
In your code:
i==20 give result false because i=10
i==20 || 30 equals to false || 30 give results true because 30 (or non-zero values) equal to true in condition check.
It should be:
if((i==20) || (i==30))
The expression if(i==20 || 30) is turning out to be true(non zero) hence you are seeing the output as true. The expression will be evaluated according to the precedence at which the operators get evaluated. == has higher precedence than || hence i==20 will be evaluated first and the result becomes as follows
if( true || 30 )
Now the operator is || the Left operand will be checked first which is true and control enters if block and prints true. This is called short circuit evaluation. If we have logical || operator, first the Left operand will be evaluated. If the left operand is true compiler wont evaluate right operand.

Output of this C program i can't understand

I am revising C again and was making some test programs. At one program I was checking a condition which was translating ino this condition.
#include <stdio.h>
int main()
{
if(0 <= 3000.000000 <= 2000.00){ //this is the condition
printf("3000 is less than 2000, whoa.. \n");
}
return 0;
}
The output is always this print string. I can't understand why.
P.S
I am testing the middle value, i.e 3000.000000 here, but it can be some variable.
The condition is parsed like this:
if((0 <= 3000.000000) <= 2000.00){
The first part, (0 <= 3000.000000), is true, and evaluates to 1 in the comparison with 2000.00. And 1 <= 2000.00 is true.
If you're trying to test whether a value a lies between two values b and c or is equal to either, then you need an expression along the lines of
(a >= b) && (a <= c)
You're getting caught by the fact that in C, booleans are integers: either 0 or 1.
So that line is interpreted left-to-right: First 0 <= 3000, which is true so it ends up as 1. Then that value is fed into the next half, (1) <= 2000, which is obviously true.
It will prints the string in printf.
Because the condition is static.
The 0 is always less than 30000.000000. For the next condition the output of the first condition returns 1. it checks using the 1.
The second condition checking is 1 <= 2000.00. This condition is also true.
So, only this prints the string.
the first condition evaluates to 1 as output and further 1<2000 is checked which is also true.So,the string is printed.

Resources