

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer

This question already has an answer here:


int main ()
  int foo(X * p); // forward declaration
  bar(x * y);  // function call




share|improve this question

marked as duplicate by gnat, MichaelT, Snowman, durron597, Bart van Ingen Schenau Jun 13 '15 at 17:07


It is just a matter of legacy and habits. Remember that C is a very old programming language. Look into Rust or Go for something newer! – Basile Starynkevitch Jun 8 '15 at 12:44
Anyone past the earliest beginner stage would write int ans = (**a) * 3; which isn't confusing at all. Don't complain about the language when it is entirely in your hands to write clear code. – gnasher729 Jun 8 '15 at 13:12
I think @MichaelT might have found it: Why does C use the asterisk for pointers? – Snowman Jun 8 '15 at 14:14
To be honest, I really can't tell if the example is ugly because of the * notation or because of not using enough/consistent whitespace between operators overall. If you don't like int ans = **a * 5 then you can always say, int x = **a; int ans = x * 5; – Brandin Jun 9 '15 at 12:46
up vote 16 down vote accepted


The lexical parsers differentiate between them based on the context.



share|improve this answer

I do not know for sure, but I would be willing to bet that the answer is probably because the inventors of C ran out (or nearly ran out) of characters.

The original intention was that the language should use symbols for operators, and also that the language must be expressable within the so-called "lower" ASCII table, which consists of ASCII values 0 through 127.

The first 31 values are unprintable control characters, so we are left with this:




Remove the space, and all characters needed for identifiers, (which are all letters, all numbers, and the underscore,) and and we are left with this:


Remove parentheses, braces, and brackets, as well as the backtick (`), which is not sufficiently dissimilar from the single quote, and we are left with this:


Remove punctuation which is critical for the syntax of the language, ("#',.:;?) and we are left with this:


Remove the ampersand (&), which stands for "taking the address of" something, and which must therefore be distinctly different from anything that has to do with pointers, as well as comparisons, (<=>), exclamation (!), plus (+), and minus (-), which are valid operations to perform on pointers, and we are left with this:


I am not sure why the dollar sign and the at-sign were not considered; perhaps they were thought of as being a bit too bulky to make frequent use of in code. So, take them out, and we are left with these:


As you can see, all of the above characters are used as operators for various arithmetic and logical operations in C, which means that they had to reuse one of them as the character for declaring and dereferencing pointers.

They chose the asterisk (*), which is a decent choice because it somewhat bears the notion of a "point", and because multiplication is not one of the operations which are valid to perform on pointers.

They could have also chosen the caret (^), (which stands for exclusive-OR,) but I do not think that it is such a huge deal, and clearly, their options were very limited.

share|improve this answer
Pascal uses ^ for pointers. Kernighan had a few gripes with that language and may have wanted to do things differently. – MichaelT Jun 8 '15 at 13:40
Many older languages (such as BASIC) used the $ in variable declarations. Too, it's usually only available on US keyboards, although I don't know if this consideration would have been important to the original designers. – Clockwork-Muse Jun 8 '15 at 13:44
You might also tweak your set of characters given the response from Ken Thompson to the query (noting that C got it from B): "b was designed to be run with a teletype model 33 teletype. (5 bit baud-o code) so the use of symbols was restricted." - you can see its character set in Wikimedia. – MichaelT Jun 8 '15 at 14:09
If I could change 5 things in C I would change pointer from "*" to "^", attribution from "=" to ":=", equal from "==" to "=", "||" to "or" and "&&" to "and". – Mandrill Jun 8 '15 at 14:23
@Mandrill although what you just said probably qualifies as blasphemy, I would tend to agree with you. We will probably burn in hell for this. – Mike Nakis Jun 8 '15 at 14:55


if-statement: "if" expression statement |
              "if" expression statement "else" statement

leads to the dangling else problem, where

if a if b c else d

can be parsed as either of



The other, more difficult problem is

typedef-name: identifier



share|improve this answer


typedef int MahInt;
MahInt * p; // declaration or multiplication?

It is not possible to parse C without symbol tables.


int x, y;
x ??!??! y;

which is really

x || y
share|improve this answer

The typedef was a relatively late addition to the C language.



int foo() {



For example:

int x, y;
int foo() {
         typedef int x;
                  so this is a declaration */
               so it's an expression statement again */


share|improve this answer




share|improve this answer
