Very basic question (I am a total noob in C...)
I have a piece of code written:
if(!_a[_item[i]] || _b[_item[i]])
Does this mean the next line should be run if:
item[i] is not present in a or in b
or does it mean it should be run if:
item[i] is not present in a or is present in b?
Thanks
It means item[i] is not present in a or is present in b
So, we can always look at the operator precedence tables, but I usually have some trouble following that. So let's write some code:
#include <stdbool.h>
#include <stdio.h>
int main() {
printf("%d\n", (!true || true)); // Outputs 1 (true)
}
So, let's see which of the two variants makes sense:
If we have ((!true) || true) then this makes sense.
If we have (!(true || true)) then this does not make sense.
So, we can pretty clearly say that these two expressions are the same:
(!_a[_item[i]] || _b[_item[i]])
((!_a[_item[i]]) || _b[_item[i]])
And thus, we know that the next line will run if _item[i] is not present in a or it is present in b.
Although an answer has been selected for this question, I'm going to chime in anyway.
The code
if(!_a[_item[i]] || _b[_item[i]])
Does not determine the (non) presence of _item[i] in _a or _b. What it does is say:
The numerical value of the element _item[i] of array _a is zero or the numerical value of
the element _item[i] of array _b is non-zero
Whether that maps to the concept of presence is an architectural decision that is irrelevant to how the if statement is processed.
! has higher precedence than ||. The first term is negated, the second one isn't. It's equivalent to ( (!(_a[_item[i]])) || _b[_item[i]] )
Check the operator precedence (e.g. on Wikipedia), you'll find that ! is evaluated before the || and thus the expression is parsed like this:
if((!_a[_item[i]]) || _b[_item[i]])
btw. if you see (!A || B) this is known as implies in logic: A implies B == !A || B
Related
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).
I read Xen source code and saw something like this:
#define is_domain_direct_mapped(d) ((void)(d), 0)
is_domain_direct_mapped is then used in a if statement as follows (d is a pointer to a struct variable):
if( is_domain_direct_mapped(d) ) {...}
So after compiler replaces is_domain_direct_mapped with its definition, we have something like:
if( ((void)(d), 0) ) {...}
The above if statement is very weird to me. This is the first time I see this kind of statement. How is it supposed to work?
It’s meant to always produce 0 but also evaluate d, in case it’s something with side-effects like p++.
As for why you would want to always produce 0: the implementation is different on ARM.
#define is_domain_direct_mapped(d) ((d) == hardware_domain && dom0_11_mapping)
Notice how d is evaluated exactly once here too.
Some discussion from when this was first introduced as confirmation – Re: [Xen-devel] [PATCH v3 1/3] xen/x86: introduce is_domain_direct_mapped(d) as (0) on x86:
When I've implemented this defined in common/memory.c, Jan told me to
use [1]:
#define is_domain_is_direct_mapped(d) ((void)(d), 0)
I suspect you want the same things here.
referencing Re: [v4] xen/arm: Allow balooning working with 1:1 memory mapping:
And you'll want to make sure (even if unlikely to be needed in
practice) that you evaluate the macro argument exactly once in both
flavors, i.e. in the case here
#define is_domain_direct_mapped(d) ((void)(d), 0)
This is the comma operator.
The left member (in your case d) is evaluated for its side effects and then discarded. The right member (0) gives the result.
#include<stdio.h>
main()
{
int big,x=3,y=2,z=1,q=4;
big=( x>y ? (x<z ? 20:10 && y>x ? 50:10 ) : (y>z ? 40:10 || x<q ? 30:10));
printf("big =%d",big);
return 0;
}
&& is a relational operator so it should return a true or false value i.e 0 or 1, but in this case its not. Please explain whats the logic behind its output?
Output: big =10
It's all about operator precedence (and a distressing lack of parentheses).
The output I get when I run your program is nbig =10 (with no newline; you should add a \n to your format string).
The value assigned to big isn't the result of an && or || operator. Let's reduce that over-complicated expression, one step at a time. (I've confirmed at each step that the result is unchanged.)
big=(x>y?(x<z?20:10 && y>x?50:10) : (y>z?40:10 || x<q?30:10));
We know that x>y is true, so we can drop the test and the third operand of the corresponding ?: operator:
big=(x<z?20:10 && y>x?50:10);
Let's remove the extraneous outer parentheses, add some new around the third operand of the outer ?: operator, and change the spacing a bit:
big = x<z ? 20 : (10 && y>x?50:10);
We know that x<z is false, so we can drop that and the second operand of the outer ?::
big = (10 && y>x?50:10);
Obviously 10 is true, so:
big = (y > x ? 50 : 10);
And y > x is false, so the result is 10 -- which is what I get when I run your program.
You probably assumed that this:
a ? b : c && d ? e : f
is equivalent to:
(a ? b : c) && (d ? e : f)
but in fact it's equivalent to:
a ? b : ((c && d) ? e : f)
because the && operator binds more tightly than the ?: operator.
In any case, if this is real code, you should definitely add enough parentheses so that a reasonably knowledgeable reader can understand the code without having to consult an operator precedence table. Mixing &&, ||, and ?: can be particularly confusing. Breaking down the expression into subexpressions, and assigning each one to a temporary variable (so it has a meaningful name) can also be helpful.
The above applies if you're trying to write a complex expression. If you're trying to understand something that someone else has written, you pretty much have to parse it yourself. Try doing what I did: incrementally simplify the expression (by removing parts or adding parentheses) in ways that don't change the meaning, confirming at each step that you get the same result. And if it's production code (rather than a quiz, which this appears to be), consider complaining bitterly encouraging the author to write clearer code.
Let's make your expression a bit more explicit by adding parethesis to show the precedence:
((x>y) ?
((x<z) ?
20 : ((10 && (y>x)) ? 50 : 10)
) : (
(y>z)?40:((10 || (x<q))?30:10)
)
)
x is greater than y, so let's consider
((x<z) ?
20 : ((10 && (y>x)) ? 50 : 10)
)
and x is not less than z, so
((10 && (y>x)) ? 50 : 10)
y is not greater than x, so
10
You can see that the results are not actually of your logical operators. Because of the complexity involved, you should almost certainly express such an evaluation using if statements to break up the logic in a clean way.
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."