0

assuming we have a pointer called

struct node *head

When referring to this as &head the type becomes pointer to pointer (struct node**) why is this?

programmer
  • 669
  • 3
  • 11
  • 1
    `struct node*` refers to an address of a value of type `struct node`. `struct node**` refers to an address of an address of a value of type `struct node`. `&` is the address-of operator and gives you the address of the variable in its operand. So, doing `&head` gives you the address of head which has type `struct node*` which itself is an address of some variable residing in memory with the type `struct node`. Hence, it's type is `struct node**`. – Ruks Aug 04 '21 at 15:16

4 Answers4

4

Imagine a real life laser pointer.

You can point it to cars (car *), to pigeons (pigeon *), ..., to anything (void *).

Now use a laser pointer to point to a laser pointer pointing to cars (car **).

Of course in real life you can point the same laser to a car or a pigeon, etc... but in C that's invalid: a car * cannot point to pigeons, etc.

You can turn the laser pointer off too (pointer = NULL; /* :-) */)

pmg
  • 106,608
  • 13
  • 126
  • 198
  • Using this analogy, &head gives the address of the *pointer variable*, which is of type (struct node*) right? So we are referring to the *pointer variable* how is the extra ``*``` added to make this of type ```struct node**``` because all I am seeing is us using ```&head``` to refer to the address of the ```pointer variable``` in question. – programmer Aug 04 '21 at 15:50
  • @printf, a pointer to a `struct node` has type `struct node *`. A pointer to `struct node *` has type `struct node **`, which you can also write as `(struct node *)*`. Pointers can certainly be confusing to those unfamiliar with them, but at this point I am having difficulty determining just what it is about them that you are not grasping. – John Bollinger Aug 04 '21 at 16:02
  • @JohnBollinger Please look at user TimRandall's answer and look at my comment, that is specifically what I seem to be troubled with. – programmer Aug 04 '21 at 16:04
3

Whenever you take the address of something of type T, the result is of type T*.

So if the type of head is struct Node *, the type of &head must be of type struct Node **.

all we are doing is referring to the address of the pointer, which means it's a pointer, right?

They're both pointers, but they're not pointers to the same kind of thing. head contains a pointer to a Node structure, but &head contains a pointer to the variable. "address of the pointer" is not the same as "contents of the pointer", even if the contents are a pointer.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Wait a minute, isn't &head the address of the pointer variable? how does &head contain a pointer? it contains a memory address right, not a pointer? – programmer Aug 04 '21 at 15:36
  • I thought a pointer was a variable that holds a memory address though? So can I think of a pointer as a memory address? – programmer Aug 04 '21 at 15:37
  • 1
    A pointer is a type of value, like an integer or float. You can declare variables that hold all these things. – Barmar Aug 04 '21 at 15:38
  • E.g. `malloc()` is a function that returns a pointer. You can assign it to a pointer variable. – Barmar Aug 04 '21 at 15:39
  • ah so when you say ```pointer``` you don't mean a pointer variable, you mean a memory address? – programmer Aug 04 '21 at 15:40
  • 1
    I mean a pointer value. Values exist independently of the variables that we store them in. – Barmar Aug 04 '21 at 15:41
  • so is a "pointer value" a memory address or a pointer variable, sorry this is confusing for me lol – programmer Aug 04 '21 at 15:42
  • It's an abstract concept. A pointer value is a memory address along with its associated type. – Barmar Aug 04 '21 at 15:46
  • E.g. `head` and `(void *)head` both refer to the same address, but the latter is a different type. – Barmar Aug 04 '21 at 15:47
  • Wait, could I think of it like this: let's say ```struct node *head``` has a memory address of ```0x2468``` and ```head``` is pointing to address ```0x1234```. If I do ```&head``` i get address ```0x2468``` and if I dereference this address I get the address ```0x1234``` so it becomes (struct node**) – programmer Aug 04 '21 at 16:27
  • Yes, you're getting it. – Barmar Aug 04 '21 at 16:28
  • nice thanks for the help, I appreciate it. Lastly if you don't mind could you reccomend me something to maybe solidify my knowledge on this? – programmer Aug 04 '21 at 16:31
  • 1
    Sorry, I don't know good tutorials on this stuff. – Barmar Aug 04 '21 at 16:32
2

struct node *head;

This means that head is a pointer to a node. The contents of head, then, will be the address of a node.

Now, consider this: struct node** p = &head; The expression &head evaluates to the address of head, that is, the address of an object containing the address of a node. That's why the type of p is a pointer to a pointer.

Tim Randall
  • 4,040
  • 1
  • 17
  • 39
  • I understand that but ```struct node** p``` is out of the question, in my example I just include ```&head``` with no inclusion of *another* pointer variable like you have included (```p```). Of course I understand how it would work in your context (with variable ```p```) but how would it work without the ```p``` variable? Would there be an invisible ```p``` variable allocated in memory for ```&head``` or something like that? – programmer Aug 04 '21 at 16:01
  • If you just type the expression `&head` in your code, then yes, it is of type `struct node**`. If you don't do anything with it, it will have no effect. I assigned it to `p` since that seemed to be the simplest use case. You could also have passed it to a function, assuming the function takes a parameter of type `struct node**` – Tim Randall Aug 04 '21 at 16:08
  • So yes, @printf, the result of the expression `&head` has a different type than the expression `head` does. This is a natural consequence of the effect of that operation. The `&` operator is not the only operator whose result type (always) differs from its argument type. The dereferencing operator (unary `*`) has this property too, of course, but so also do typecast operators. And most arithmetic and relational operators also have that property under some circumstances. That is not an exhaustive list. – John Bollinger Aug 04 '21 at 16:12
  • Wait, could I think of it like this: let's say ```struct node *head``` has a memory address of ```0x2468``` and ```head``` is pointing to address ```0x1234```. If I do ```&head``` i get address ```0x2468``` and if I dereference this address I get the address ```0x1234``` so it becomes (struct node**) – programmer Aug 04 '21 at 16:18
1

Assume the following declaration:

T x; // for some arbitrary type T

The expression x has type T, thus the expression &x1 yields a value of type T * (pointer to T). This is true for any type T.

Now let's replace T with a pointer type P *:

P *x; // T -> P *

The expression &x yields a value of type P ** (T * -> (P *) * == P **).

So yeah, the expression &head will yield a value of type struct node **, and its value will be different from head.

Multiple indirection shows up a lot in C. It looks weird at first, but you'll get the hang of it soon enough.


  1. The operand of the unary & operator shall be either a function designator, the result of a [] or unary * operator, or an lvalue that designates an object that is not a bit-field and is not declared with the register storage-class specifier - C 2011 Online Draft, § 6.5.3.2 Address and indirection operators.
John Bode
  • 119,563
  • 19
  • 122
  • 198
  • Thanks this was a pretty clear example, I know now after multiple hours of thinking and understand that, when we do ```&x``` there is 2 parts to it 1) the address of the *pointer variable x* which is type P* and 2) when we dereference this address we get another address of type P* so altogether if you think about it, it makes P**, that sounds about right I think – programmer Aug 04 '21 at 18:18