4

Why is the * used to declare pointers?

It remove indirection, but doesn't remove any when you declare a pointer like int *a = &b, shouldn't it remove the indirection of &b?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Paralax01
  • 63
  • 4
  • 1
    That character `*` has a pretty different meaning in an expression versus a declaration. In an expression it's a dereference operator. In a declaration it's more like a this-is-a-pointer modifier. – Steve Summit Nov 01 '21 at 20:22
  • 2
    In a declaration, it's not an operator at all. – HolyBlackCat Nov 01 '21 at 20:23
  • 2
    Have you thought about why there is no removal of indirection in `42 * 4`? – eerorika Nov 01 '21 at 20:35
  • 1
    You're close, but you're not quite at the intended way to read C declarations: `int *a;` => `int`, `*a` => The expression `*a` produces `int`. Declarations in C were designed to model use like this. – chris Nov 01 '21 at 20:36

4 Answers4

5

Many symbols in C and C++ are overloaded. That is, their meanings depend on the context where they are used. For example, the symbol & can denote the address-of operator and the binary bitwise AND operator.

The symbol * used in a declaration denotes a pointer:

int b = 10;
int *a = &b,

but used in expressions, when applied to a variable of a pointer type, denotes the dereference operator, for example:

printf( "%d\n", *a );

It also can denote the multiplication operator, for example you can write:

printf( "%d\n", b ** a );

that is the same as

printf( "%d\n", b * *a );

Similarly, the pair of square braces can be used in a declaration of an array, like:

int a[10];

and as the subscript operator:

a[5] = 5;
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
2

Any time you have a pointer declaration with initialization like this:

type *x = expr;

it is equivalent to the separate initialization followed by assignment:

type *x;
x = expr;

It is not equivalent to

type *x;
*x = expr;      /* WRONG */
Steve Summit
  • 45,437
  • 7
  • 70
  • 103
2

It's part of the declaration, so it's not a dereference operator at all. Yet it still means the same thing.

int *a

can be read as

The value pointed by a is an int.

just like

printf("%d\n", *a);

can be read as

Print the value pointed by a.

See this answer to Correct way of declaring pointer variables in C/C++ for a bit on background on this.

ikegami
  • 367,544
  • 15
  • 269
  • 518
  • 1
    It actually “is” a dereference operator. Not in the sense that a dereference operation is performed, but in that it still holds its dereference meaning. As K&R explain, a declarator presents a picture of how an identifier will be used. `int *a` says `*a` will be used as an `int`, meaning that when the dereference operator is applied to `a`, the result has type `int`. So the `*` in `int *a` is the dereference operator, but just used for its meaning, not to perform its computation. – Eric Postpischil Nov 01 '21 at 20:55
  • It actually isn't a dereference operator. You can't place an expression on the left of `=` in a declaration. But it does *act as* a dereference, yes, which is what my answer already says. – ikegami Nov 01 '21 at 20:59
1

Back when C was invented, a somewhat interesting choice was made. Variables would be declared in a kind of echo of how they would be used.

So

int a;

means "you can get an int out of a. Then,

int *a;

means you can get an int out of *a.

And,

int a[3];

means you can get an int out of a[index]; here, the size is put in where the index would be.

This can be chained to complex cases

int *a[3];

vs

int (*a)[3];

now if you don't know how C parsing works, this is opaque; but at least you only have to learn it once!

This is why some people think int* a is bad form, because the * is really attached to a not the int.

Initialization of the named variable is a different thing.

(some declaration) = (some expression)

the symbols in the declaration never act as expressions. They are the same symbols, just different meaning.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524