What is the meaning of '==' in C? - c

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."

Related

Can someone explain how this works? [duplicate]

I saw this code:
if (cond) {
perror("an error occurred"), exit(1);
}
Why would you do that? Why not just:
if (cond) {
perror("an error occurred");
exit(1);
}
In your example it serves no reason at all. It is on occasion useful when written as
if(cond)
perror("an error occured"), exit(1) ;
-- then you don't need curly braces. But it's an invitation to disaster.
The comma operator is to put two or more expressions in a position where the reference only allows one. In your case, there is no need to use it; in other cases, such as in a while loop, it may be useful:
while (a = b, c < d)
...
where the actual "evaluation" of the while loop is governed solely on the last expression.
Legitimate cases of the comma operator are rare, but they do exist. One example is when you want to have something happen inside of a conditional evaluation. For instance:
std::wstring example;
auto it = example.begin();
while (it = std::find(it, example.end(), L'\\'), it != example.end())
{
// Do something to each backslash in `example`
}
It can also be used in places where you can only place a single expression, but want two things to happen. For instance, the following loop increments x and decrements y in the for loop's third component:
int x = 0;
int y = some_number;
for(; x < y; ++x, --y)
{
// Do something which uses a converging x and y
}
Don't go looking for uses of it, but if it is appropriate, don't be afraid to use it, and don't be thrown for a loop if you see someone else using it. If you have two things which have no reason not to be separate statements, make them separate statements instead of using the comma operator.
The main use of the comma operator is obfuscation; it permits doing two
things where the reader only expects one. One of the most frequent
uses—adding side effects to a condition, falls under this
category. There are a few cases which might be considered valid,
however:
The one which was used to present it in K&R: incrementing two
variables in a for loop. In modern code, this might occur in a
function like std::transform, or std::copy, where an output iterator
is incremented symultaneously with the input iterator. (More often, of
course, these functions will contain a while loop, with the
incrementations in separate statements at the end of the loop. In such
cases, there's no point in using a comma rather than two statements.)
Another case which comes to mind is data validation of input parameters
in an initializer list:
MyClass::MyClass( T const& param )
: member( (validate( param ), param) )
{
}
(This assumes that validate( param ) will throw an exception if
something is wrong.) This use isn't particularly attractive, especially
as it needs the extra parentheses, but there aren't many alternatives.
Finally, I've sometimes seen the convention:
ScopedLock( myMutex ), protectedFunction();
, which avoids having to invent a name for the ScopedLock. To tell
the truth, I don't like it, but I have seen it used, and the alternative
of adding extra braces to ensure that the ScopedLock is immediately
destructed isn't very pretty either.
This can be better understood by taking some examples:
First:
Consider an expression:
x = ++j;
But for time being, if we need to assign a temporarily debug value, then we can write.
x = DEBUG_VALUE, ++j;
Second:
Comma , operators are frequently used in for() -loop e.g.:
for(i = 0, j = 10; i < N; j--, i++)
// ^ ^ here we can't use ;
Third:
One more example(actually one may find doing this interesting):
if (x = 16 / 4), if remainder is zero then print x = x - 1;
if (x = 16 / 5), if remainder is zero then print x = x + 1;
It can also be done in a single step;
if(x = n / d, n % d) // == x = n / d; if(n % d)
printf("Remainder not zero, x + 1 = %d", (x + 1));
else
printf("Remainder is zero, x - 1 = %d", (x - 1));
PS: It may also be interesting to know that sometimes it is disastrous to use , operator. For example in the question Strtok usage, code not working, by mistake, OP forgot to write name of the function and instead of writing tokens = strtok(NULL, ",'");, he wrote tokens = (NULL, ",'"); and he was not getting compilation error --but its a valid expression that tokens = ",'"; caused an infinite loop in his program.
The comma operator allows grouping expression where one is expected.
For example it can be useful in some case :
// In a loop
while ( a--, a < d ) ...
But in you case there is no reason to use it. It will be confusing... that's it...
In your case, it is just to avoid curly braces :
if(cond)
perror("an error occurred"), exit(1);
// =>
if (cond)
{
perror("an error occurred");
exit(1);
}
A link to a comma operator documentation.
There appear to be few practical uses of operator,().
Bjarne Stroustrup, The Design and Evolution of C++
Most of the oft usage of comma can be found out in the wikipedia article Comma_operator#Uses.
One interesting usage I have found out when using the boost::assign, where it had judiciously overloaded the operator to make it behave as a comma separated list of values which can be pushed to the end of a vector object
#include <boost/assign/std/vector.hpp> // for 'operator+=()'
using namespace std;
using namespace boost::assign; // bring 'operator+=()' into scope
{
vector<int> values;
values += 1,2,3,4,5,6,7,8,9; // insert values at the end of the container
}
Unfortunately, the above usage which was popular for prototyping would now look archaic once compilers start supporting Uniform Initialization
So that leaves us back to
There appear to be few practical uses of operator,().
Bjarne Stroustrup, The Design and Evolution of C++
In your case, the comma operator is useless since it could have been used to avoid curly braces, but it's not the case since the writer has already put them. Therefore it's useless and may be confusing.
It could be useful for the itinerary operator if you want to execute two or more instructions when the condition is true or false. but keep in mind that the return value will be the most right expression due to the comma operator left to right evalutaion rule (I mean inside the parentheses)
For instance:
a<b?(x=5,b=6,d=i):exit(1);
The boost::assign overloads the comma operator heavily to achieve this kind of syntax:
vector<int> v;
v += 1,2,3,4,5,6,7,8,9;

Should you use '>=' instead of '==' to be extra safe when coding with other types than float?

When working with floating-points one should use
a <= 0.0
instead of
a == 0.0
to make sure that you get the desired behaviour, as there is the problem with round-off errors when using floating-point variables.
But when using other variable types like int could it be useful to do the same? Like you have a for loop iterating over an int variable (like an index) and when it gets to a number it should do something. Should you then set the comparison to be >= instead of == when it should result in the same output? Like could there ever be a case where the == is not evaluated in the following case:
for (int i = 0; i < 10; i++)
{
if (i == 5)
{
break;
}
}
And that it would be "safer" to do the following instead:
for (int i = 0; i < 10; i++)
{
if (i >= 5)
{
break;
}
}
If there is no difference between the two when it comes to coding "safe" is there any performance or readability difference or other thing that can make one choose between the ways to code?
Tried to google this but couldn't find anything stating either way. But that might have to do with the problem with searching for operators.
Am I too paranoid for asking this?
The premise of the question is wrong; blindly using a <= 0.0 instead of a == 0.0 is not a valid practice with floating point. See How dangerous is it to compare floating point values? for a treatment of the topic.
With that said, there are some cases where use of inequality relational operators are "more hardened" than use of the equality operator, and vice versa. In general, I would recommend against it since it's likely to give you a false sense of safety; for example, in the example in your question with i==5 vs i>=5, the compiler is likely to be able to prove they're the same, and optimize either to the other if needed. This means it will not necessarily do anything to protect you against stack overflows or neutrinos or any other cause by which the value of i might become something other than 0..5 outside of the defined semantics of the language.
There are also some cases where use of equality is defined by inequality is not, particularly involving pointers. If pos and end are both pointers, pos==end is well-defined as long as they are both valid. But if they are both null, while pos==end is well-defined and true, pos>=end is undefined behavior. Likewise if they both point into different arrays (in particular if end points to a sentinel not part of your array), pos==end will always be false, but pos>=end is undefined behavior.
I also find it misleading to write if (i>=5) when you know i>5 is logically impossible - it makes the reader stop to think about whether it's possible, and if not, why you wrote it that way instead of if (i==5).
The answer is, it depends. If you have a loop like this:
for (int i = 0; i < 10; i++)
{
if (i == 5)
{
break;
}
}
Then there is no danger in i skipping 5.
On the other hand, if you have something like this:
volatile int i;
void interrupt(void)
{
i++;
}
void foo(void)
{
for (i = 0; i < 10; i++)
{
if (i == 5)
{
break;
}
}
}
Then i may change outside the normal flow of the program (e.g. because of an interrupt). In this case >= would be prudent.
Like could there ever be a case where the == is not evaluated
No, using == is safe. Integers represent all values within the range of the integer type used accurately. There are no surprises.
Should you then set the comparison to be >= instead of ==
As the result is the same, you can do both but I would find >= confusing. So for readability I prefer ==
is there any performance . . . that can make one choose between the ways to code
You can't tell by looking at the C code. It depends on the system (CPU) used. In general I would however doubt that you would experience any major difference.

Some confusion with regards to parenthesis in C

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.

Why this loop stops?

From this answer, I saw this:
unsigned long
hash(unsigned char *str)
{
unsigned long hash = 5381;
int c;
while (c = *str++)
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
return hash;
}
The problem is that I don't see how the while stops from executing. Generally an assignment isn't resulted in true? I mean if(a = 5) will be true.
Also the compiler gave me this warning:
warning: suggest parentheses around assignment used as truth value [-Wparentheses]
Can anyone step me trough on what exactly goes on with the loop? I would strongly suggests that an example would be the best approach here.
Also where should the parentheses go to make this more clear?
The value of an assignment is the value that gets assigned. For example, this code:
int a;
printf("%d\n", a=5);
… will print out 5.
So, this loop runs until c is assigned something false.
And in C, 0 is false, and strings are null-terminated, so at the end of the string, the NUL character, 0, will end the loop.
The warning is because if (a = 5) is a typo for if (a == 5) more often than it's intentional code. Putting extra parentheses around an assignment, like if ((a == 5)), is an idiomatic way to say "I meant to use the value of this assignment". With some compilers, you may get a different, stronger warning in the case where the value is constant, as in my example, than in examples like yours, but the issue is the same: if you meant to test the value of an assignment, and you don't want to disable the warning globally, the way to convince GCC to leave you along is with extra parentheses: while ((c = *str++)).
See this question for more details. You may also want to search the GCC mailing lists for threads like this one discussing the warning.

Feel kind of confused by the book "Programming in C" (Stephen Kochan)

I've been teaching myself in C programming with the book recommended by a friend who is great in C. The book title is "Programming in C" by Stephen Kochan.
I have a background in Java, and I feel a little bit crazy with the way the codes were written in Stephen's book. For example, the following code, in which I commented my confusion. Maybe I'm missing something important here, so I'm looking to hear some inputs about the correct way of coding in C.
#include <stdio.h>
void test(int *int_pointer)
{
*int_pointer = 100;
}
int main(void)
{
void test(int *int_pointer); // why call the test() function here without any real argument? what's the point?
int i = 50, *p = &i;
printf("Before the call to test i = %i\n", i);
test(p);
printf("After the call to test i = %i\n", i);
int t;
for (t = 0; t < 5; ++t) // I'm more used to "t++" in a loop like this. As I know ++t is different than t++ in some cases. Writting ++t in a loop just drives me crazy
{
if (4 == t) // isn't it normal to write "t == 4" ?? this is driving me crazy again!
printf("skip the number %i\n", t);
else
printf("the value of t is now %i\n", t);
}
return 0;
}
// why call the test() function here without any real argument? what's the point?
It is not a call, it is function declaration. Completely unnecessary at this location, since the function is defined few lines before. In real world such declarations are not used often.
// I'm more used to "t++" in a loop like this. As I know ++t is different than t++ in some cases. Writting ++t in a loop just drives me crazy
In this case they are equivalent, but if you think of going to C++ it is better to switch completely to ++t form, since there in some cases (e.g. with iterators) it makes difference.
// isn't it normal to write "t == 4" ?? this is driving me crazy again!
Some people tend to use 4 == t to avoid a problem when t = 4 is used instead of t == 4 (both are valid in C as if condition). Since all normal compilers signal a warning for t = 4 anyway, 4 == t is rather unnecessary.
Please read about pointers then you will understand that a pointer to an int has been passed as an argument here...
void test(int *int_pointer);
You can see the difference between ++t and t++ nicely explained in this link . It doesn't make a difference in this code. Result will be the same.
if(4 == t) is same as if(t == 4) . Just different styles in writing. 4 == t is mostly used to avoid typing = instead of ==. Compiler will complain if you write 4 = t but wont complain if you write t = 4
why call the test() function here without any real argument? what's the point?
Here test is declared as function (with void return type) which expects an argument of the type a pointer to int.
I'm more used to "t++" in a loop like this. As I know ++t is different than t++ in some cases. Writting ++t in a loop just drives me crazy
Note that, when incrementing or decrementing a variable in a statement by itself (t++; or ++t), the pre-increment and post-increment have same effect.
The difference can be seen when these expression appears in a large or complex expressions ( int x = t++ and int x = ++t have different results for the same value of t).
isn't it normal to write "t == 4" ?? this is driving me crazy again!
4 == t is much safer than t == 4, although both have same meaning. In case of t == 4, if user type accidentally t = 4 then compiler would not going to throw any error and you may get erroneous result. While in case of 4 == t, if user accidentally type 4 = t then compiler would through you a warning like:
lvalue is required as left operand of assignment operator.
void test(int *int_pointer); is a function prototype. It's not required in this particular instance since the function is defined above main() but you would need it (though not necessarily in the function body) if test was defined later in the file. (Some folk rely on implicit declaration but let's not get into that here.)
++t will never be slower than t++ since, conceptually, the latter has to store and return the previous value. (Most compilers will optimise the copy out, although I prefer not to rely on that: I always use ++t but plenty of experienced programmers don't.)
4 == t is often used in place of t == 4 in case you accidentally omit one of the =. It's easily done but once you've spent a day or two hunting down a bug caused by a single = in place of == you won't ever do it again! 4 = t will generate a compile error but t = 4 is actually an expression of value 4 which will compare true and assigns the value of 4 to t: a particularly dangerous side-effect. Personally though I find 4 == t obfuscating.

Resources