Schizoid Operators

The C language features a host of symbols that take on different meanings depending on how they’re used. Unless you’re careful, these operators’ multiple personalities can confuse the bejeebers out of you.

First, the reason for the confusion is simply due to the design of the computer keyboard.

Back in the 1970s, consistency between the various computer (actually terminal) keyboards wasn’t a major concern. The alphanumeric keys were present, but outside of those letters and numbers the keyboards were short on symbols. The only consistent symbols available were the common punctuation characters found on just about every typewriter keyboard.

The C language had to make due given the limited character set available. So some symbols were used multiple times. Specifically, the & and *.

The & operator can be used in two different ways. I’m not counting the doubling-up of the && operator, which could be considered a third way. The two other ways are:

& the bitwise AND operator, or the “AND mask” as I write about in my C programming books.

& the unary address operator.

The * operator has two uses as well:

* the multiplication operator.

* the unary pointer operator.

The * operator is also used to declare a pointer variable, but that’s still the same operator so it doesn’t count as a third purpose.

Both symbols have the unary mode in common, which is interesting because both of them relate to pointers in that mode: &var yields the address of variable var, and *ptr fetches the value stored at memory location ptr.

But how does the compiler know that?

No, it doesn’t guess. The compiler knows which variables are pointers and which aren’t. If you use a statement such as:

result = 17 *ptr;

If ptr is a pointer variable, then you’ll see an invalid operands error. That means you tried to concoct an equation without an operator. When ptr isn’t a pointer variable, the * works as a multiplication operator. Presto.

The moral of the story: Context is important!

Not only context, but spacing as well. Specifically for readability’s sake, use white space as much as possible. While C doesn’t rely upon white space in the code, your eyeballs do. So when the compiler is faced with something obnoxious like this:

result=17**ptr;

It then uses the order of precedence to determine which operators bind to which values or variables in the statement. Above, the * unary operator has higher precedence, so it binds to ptr first, then the * operator is used for multiplication. Of course, you could be forgiving when you write the code, and sprinkle in some white space:

result = 17 * *ptr;

Not only is that format more readable, the compiler doesn’t penalize you for making the code less cryptic. That’s always a plus as far as I’m concerned.

Leave a Reply