I am confused about how Unary Operators work in C for Ones Complement, Logical Negation and preincrementing.
Ones complement works against 0 like this:
int main()
{
int a;
a = ~0; // Ones complement
printf("%d",a); // prints as -1.
}
And logical negation works against 0 like this:
int main()
{
int a;
a = !0; // Logical negation
printf("%d",a); // prints as 1.
}
But Preincrement against 0 generates a compiler error:
int main()
{
int a;
a = ++0; //pre incrementing 0. error: non-lvalue in increment
printf("%d",a);
}
Why don't all three work considering they are all Unary Operators?
The increment (++
) and decrement (--
) operators modify the thing that follows them. You can't modify a literal or a constant. In contrast, the !
and ~
operators merely operate on a value, they don't then assign the result anywhere.
Loosely speaking, ++n
means n = n + 1; n
. That is, "take the value of n
, add one to it, write that value back to n
, and return the new value as the value of the expression." So ++0
would mean 0 = 0 + 1; 0
: "take the value of 0
, add one to it, write that back to 0
, and return the new value as the result of the expression." Literals and constants cannot be left-hand values (you can't assign to them).
In contrast, ~n
means "take the value of n
and apply a bitwise NOT operation to it, return the result as the result of the expression". n
is unchanged, ~
doesn't write back the updated value to its operand.
So for example:
int n = 0;
int a;
a = ~n;
printf("a = %d, n = %d\n", a, n); // "a = -1, n = 0" -- `n` is unchanged
vs.
int n = 0;
int a;
a = ++n;
printf("a = %d, n = %d\n", a, n); // "a = 1, n = 1" -- `n` is changed
Increment (++
) and decrement (--
) are just different in that way than for !
or ~
(or, I think, any other unary operator — at least, I can't immediately think of any others that modify their operand).