I am really confused that when this like 1 == scanf("%lg", &entry) is swapped to scanf("%lg", &entry) == 1 makes no difference. My lab book says the former, while I feel latter is comprehensible.
1 == scanf("%lg", &entry) means 1 MUST be equal to scanf("%lg", &entry)Can anyone explain this? I understand the latter, that the evaluation of scanf("%lg", &entry) must equal 1
I tried passing lots of different values and it makes no difference.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
double entry = 0.0;
double total = 0.0;
int number_of_entries = 0;
while (scanf("%lg", &entry) == 1 ) {
total += entry;
number_of_entries++;
}
/* print the average of all the entries */
printf("%f\n", total / number_of_entries);
return EXIT_SUCCESS;
}
Generally speaking, you should not be surprised by (1 == scanf(...)) behaving the same as (scanf(...) == 1), since equality is symmetric. However, this is so because one of the operands is idempotent (in particular, the literal constant 1). scanf() is the only expression with a side effect, so there is no possibility of a different interpretation of the code when the arguments of == are reversed.
However, the evaluation order of the arguments to == is unspecified. So, if on side of == has a side effect that can affect the other side, then the evaluation order will impact the result of the == operation, and reversing the arguments could cause a different behavior. Such a program will thus have undefined behavior.
As a silly example, consider:
a = 0;
if (scanf("%d", &a) == a) {
...
}
The snippet has undefined behavior, because it is unspecified whether the a on the right hand side of == will be the old value it was initialized to in the statement above, or the new value that the scanf() call may have supplied. Changing the order of the arguments may cause the program to behave differently, but the behavior is still undefined.
scanf("%lg", &entry) == 1
is the same as
1 == scanf("%lg", &entry)
However, I once had a friend who preferred the
1 == scanf("%lg", &entry)
because it caught the potential typo
1 = scanf("%lg", &entry)
whereas
scanf("%lg", &entry) = 1
would go through the compiler ok.
They are the same. And it's not limited to scanf. Usage like
if (5 == x)
is called Yoda Conditions. It's a method to prevent forgetting to use double = to compare equality. If one mistakenly write:
if (5 = x)
Then the compiler will report the error. On the other hand
if (x = 5)
is valid C (it will assign x with the value of 1, and return the value 5, i.e, true) so the compiler may not warn your about it.
It's just a coding-style, many modern compilers will warn you if you write if (x = 5). If that is true in your case, I suggest not using Yoda Conditions since it's bad for readability.
Related
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.
Please bear with me, I am trying to learn C as my first programming language and am only 15 minutes in.
Why must parenthesis be used here:
while ((number1 = number2))
...when they do not need to be used here?
while (number1 <= number2)
Thanks in advance.
In:
while (number1 = number2)
number2 is being assigned to number1.
This is optically very similar to comparing number1 and number2, i.e.:
while (number1 == number2)
So a warning is produced in the former case. In order to suppress that warning you need to place the parentheses around the assignment, i.e.:
while ((number1 = number2))
It is a very common mistake to write
if ( a = b ) // assign b to a, branch if result is non-zero
when you meant to write
if ( a == b ) // *compare* b to a, branch if equal
leading to all kinds of mayhem.
It's such a common mistake that most compilers will issue a warning if they see an assignment in a conditional like that. To tell the compiler, "no, I really know what I'm doing", you surround the assignment in an additional set of parentheses:
if ( ( a = b ) )
This basically means, "yes, I intend to assign b to a and branch on the result, shut up."
If I could time travel back to Bell Labs in 1970, this is one of several decisions I'd slap Ritchie over. An entire class of bugs would never have existed if the assignment operator had been := or something equally dissimilar to comparison.
Who said there is a must? You can omit it too.
while (number1 = number2)
yes this would generate compiler warning because you are assigning and checking the assigned value without parentheses. But this is legal and bad practice.
So the reason they did this is to avoid the warning about which the compiler complained. (You shouldn't skip warning to follow a bad practice - rather allow compiler warnings and try to solve them diligently).
Though as you are beginner - aware of the statement, here the while statement is basically
while(number2)
Point: The most common to use would be to while(number1 == number2).
Also does the same thing as the previous one. Who said in the second one you can't? You can.
while ((number1 <= number2))
This is a matter of opinion. Many programmers will still wrap a comparison in parentheses for clarity. That's to make them more legible. For instance:
while(i == 0) //comparison
while(i = 0) //assignment (and therefore, infinite loop)
but more commonly, because chains of conditions can become very hard to read, and getting into the habit of parenthesizing your comparisons makes complex comparisons easier to understand:
//whiskey tango foxtrot
while(i == 0 || j == i && k == 5 || f == "pancakes")
//oh, now it's clear that we're not checking "i && k". Easier to read!
while((i == 0) || (j == i) && (k == 5) || (f == "pancakes"))
//now I've guaranteed i and j both have the value "0" by using parentheses,
//or we get false; but everything is still clearly separated.
while(((i == 0) || (j == i)) && (k == 5) || (f == "pancakes"))
First off, the first example is extremely bad practice. It's not comparing number1 and number2, it's setting the value of number1 to the value of number2. See https://freedom-to-tinker.com/2013/10/09/the-linux-backdoor-attempt-of-2003/ for some more information.
That said, both forms are allowed; you can always add extra parenthesis. In the case you have above, there is no difference.
That said, odds are good that you're simplifying from an example where multiple conditions are chained together, like
while ((number1 == number2) || (number3 == number4))
As you can see, it makes it a bit easier to see what the code is doing. Technically it's not really necessary here, either (though it's generally considered to be good practice), but it can be necessary for more complicated expressions because different expectations about operator precedence can result in your code doing things you might not expect. To take an example from that page, for something like
e = a < d ? a++ : a = d;
It can take a few moments even for an expect to figure out what is going on, and someone less familiar with C will probably need much longer. On the other hand, if you add parenthesis:
e = ( ((a < d) ? (a++) : a) = d );
Things become much easier to read.
First I have to say that i'm completely new to programming and this is my first program. I've watched a 5 hour tutorial before I started this and now I've run into my first problem I can't solve myself. So I hope someone here can help me!
I've written the following code
void printMainMenu();
void printTourMenu();
void assignment1();
void assignment2();
void assignment3();
void assignment4();
void assignment5();
void assignment6();
int main()
{
int userInput;
printMainMenu();
printf("\n\n");
scanf("%d", &userInput);
if(userInput == 4||6)
{
printTourMenu();
}
if (userInput == 1)
{
assignment1();
}
if(userInput == 2)
{
assignment2();
}
if(userInput ==3)
{
assignment3();
}
if(userInput ==5)
{
assignment5();
}
return 0;
all the functions are just pure printf so I just want the user to be able to print 6 different things depending on what they click on, but instead of making two if-statements to do the very same thing depending on the input, I just try and make an if-statement that works with multiple inputs.
the problem is in the if(userInput == 4||6) which i've tried with both
4, 6 and 4||6 where it keeps printing the printTourMenu no matter what I input and then the function i'm actually calling. With 4&&6 it prints printTourMenu only when I input 4 but not when I input 6
so what am I doing wrong? I hope someone will help this beginning programmer :D
Actually, the answer was simple and provided ASAP by Steve Summit:
if (userInput == 4||6)
doesn't do the expected. The correct would be:
if (userInput == 4 || userInput == 6)
IMHO, you should now ask:
So, if if (userInput == 4||6) is wrong – why didn't the compiler complain? (I assume it didn't although I didn't try.)
There are two reasons for this and IMHO you should know these reasons (as you did not yet learn them from your C book).
There are no special boolean types in C. Instead, every integer ≠ 0 is counted as TRUE but 0 is counted as FALSE. Hence, logic operators compute integers, comparison operators as well.
Thus, userInput == 4 || 6 is just a valid arithmetic expression and it has a precise result.
To understand how userInput == 4 || 6 is evaluated you need to know about C operator associativity and precedence also. Both terms can be found by google very easy (because they probably are searched quite often (at least periodically by me)).
I recommend the reference table of cppreference.com: C Operator Precedence.
Studying this table, we see:
operators == and || are both evaluated from left to right.
operator == has lower precedence as operator ||, i.e. == binds stronger, i.e. == is computed first.
Hence, it's starting with two cases:
userInput contains value 4: ⇒ userInput == 4: 1
userInput contains anything else: ⇒ userInput == 4: 0
These first results are applied to the second operator || 6:
1 || 6: 1 (Remember, logic-or operator just checks whether at least one argument is not 0.)
0 || 6: 1
It shows that anything || 6 results in 1.
That's why it was printing the tour menu regardless what you input.
Don't forget: as well as in school math, it is allowed to use parentheses () to override associativity and precedence. So, if you are in doubt just put parentheses around. Normally, they don't have any impact on run-time performance (at least, not as long as you don't change the order of operator evaluation due to this).
Why won't this work, I'm very new to programming but I can't seem to figure out why this wont work correctly.
#include <stdio.h>
#include <math.h>
int main(){
int num1;
printf("Enter 1, 2, 3.");
scanf("%d", &num1);
if(num1 = 1)
printf("You entered one");
else if(num1 = 2)
printf("You entered two");
else if(num1 = 3)
printf("You entered three");
else
printf("Invalid");
}
In C it is valid to use assignment (int x = 5) within a conditional (if statement).
For example:
int x = 0;
if (x = 5)
{
}
This will evaluate to true (it returns 5 to the "if" and all non zero terms are true by convention) if the assignment could be done and the value != 0. Which, in this case, it can be done and returns 5.
You were likely looking for this:
int x = 0;
if (x == 5)
{
}
This will evaluate to false (0).
Remember: You use a single equal sign "=" to mean "assignment". Use a double equal sign "==" to mean "comparison".
Replace all the = with == and you should be fine (because = is used for assignment, while == is used to test for equality, which seems to be what you want to do)
In C, as in other many programming languages, the = operator means "assignment". When you do a = 3, that means "assign a with 3", which of course it's something that succeeds and returns true, that's why your program will always enter the first branch.
What you have to do is use the "equality testing" operator, ==, so that a == 3 returns true if and only if the value held by variable a is 3.
Your code having one mistake you have taken = instead of ==, in C = operator means assignment operator while== operator is used for comparision.
To clear about your doubts regarding operators read this link
http://www.tutorialspoint.com/cprogramming/c_operators.htm
And because you started with int main() just for compiler reasons put return 0; at the end of your program to be more correct.
It doesn't work because you need to change the = sign to ==. You use the equal sign sometimes when you declare a int or char. == is meaning equal to and you want to use that when your not declaring ints and chars.While != means not equal.You should also put a return 0; at the end of your program.
What is the meaning of == and how does it differ from =?
How do I know which one to use?
== is a test for equality. = is an assignment.
Any good C book should cover this (fairly early on in the book I would imagine).
For example:
int i = 3; // sets i to 3.
if (i == 3) printf("i is 3\n"); // prints it.
Just watch out for the heinous:
if (i = 4) { }
which is valid C and frequently catches people out. This actually assigns 4 to the variable i and uses that as the truth value in the if statement. This leads a lot of people to use the uglier but safer:
if (4 == i) {}
which, if you accidentally use = instead of ==, is a compile-time error rather than something that will bite you on the backside while your program is running :-)
The logical-or operator is two vertical bar characters, one after the other, not a single character. Here it is lined up with a logical-and, and a variable called b4:
||
&&
b4
No magic there.
a == b is a test if a and b are equal.
a = b is called an assignment, which means to set the variable a to having the same value as b.
(You type | with Shift-\ in the US keyboard layout.)
== tests equality
= assigns a value
neither are related to ||
I might add that in Finnish and Swedish keyboards. Pipe symbol; |; of OR is AltGr (the right alt) and < key. IF you are using Mac on the other hand it is Alt-7 key.
Gave me a lot of sweat when I first started typing on these keyboards.
Now that you know the difference between '==' and '=", let me put you some words of caution. Although '==' is used as a standard test of equality between comparable variables and '=' used as an internally type-casted assignment, the following programming error is quiet common.
In the below example and similar codes, '=' is know as "Always true" conditional operator.
#include<stdio.h>
int main()
{
int i = 10, j = 20;
if ( i = j )
printf("Equal\n");
else
printf("NOT Equal\n");
return 0;
}
So, the word of caution is "Never use '=' in if statements, unless you have something evil in your mind."