Understanding pointers and address references in C

So here is an exercise and the gives solution below:

Assume that the following declarations have been made:

char c = ‘A’;
char *p = &c;
char **p2 = &p;
void *v = &p2;

Examine each of the following expressions. If the expression is illegal, write ILLEGAL. If the expression is legal, write its type (ie. int, void *, etc.)

 &p2 : char***
 *p2: char*
 &v: char****
 p2 + 1: char**
 v[0]: Illegal

Can you explain how we got such types? I understand that v[0] is illegal because v points to the address, and we cannot use bracket notation to access it as we do with array. But all other make me a bit confused, especially 1-3.

I would be happy for the help!

Upvotes: 0

Views: 109

Answers (2)

John Bode
John Bode

Reputation: 123448

For any lvalue expression e of type T, the expression &e has type T *, and the value of the expression is the location of e. Similarly, for any expression p of type T *, the expression *p has type T and the value of the expression is the value of whatever p points to.

The expression c has type char, so the expression &c has type char *, and the value of the expression is the location of c. This value is assigned to the variable p, which also has type char *

Since p has type char *, the expression &p has type char ** and the value is the location of p. This is assigned to the variable p2, which also has type char **.

There's a mistake in the answer key; the type of &v is void **, not char ****.

v[0] is illegal because v has type void *, and you are not allowed to dereference a void pointer.

Upvotes: 3

Khanh Nguyen
Khanh Nguyen

Reputation: 11134

Start with the basic variables

c: char
p: char* (because p = &c)
p2: char** (because p2 = &p)
v: char*** (because v = &p2)

Now, & adds one level of indirection, and * dereferences, which subtracts one level of indirection.

&p2: char*** (because p2 is char**)
*p2: char* (because p2 is char**)
&v: char**** (because v is char***)
p2 + 1: char** (same type as p2)

Note that you can (and some people do) write char *p as char* p which can more easily translated into "variable p of type char*", same for char** p, etc. But char *p has somehow become the convention. I personally had a hard time converting when I joined a company that follows the char *p convention.

Upvotes: 0

Related Questions