user1845593 user1845593 - 1 month ago 6x
C Question

Understand pointers in C

I'm reviewing my C skills, and I'm struggling to understand some bits.
Here's my understanding of C and pointers.

Every time I declare a variable, C stores the value in memory.

int num = 12; // The 12 is stored somewhere in memory, let's say has address 0x54

To get the memory address of variable "num" we do:

printf("%p", &num); // this returns the 0x54

if I want to create a pointer, that points to the same value of "num", I do:

int *ptr = # // create a pointer and point him to 0x54

If I check both address:

printf("%p\n", &num); // prints 0x54
printf("%p\n", ptr); // prints 0x54
printf("%p\n", &ptr); // prints 0x94 is the address of the pointer itself

After the above...
I don't understand the output of my program.
I'm reading this book, and the author says that we can treat pointers as arrays and vice versa (except in some cases [if I understood correctly]).

int ages[] = { 23, 43, 12, 89, 2 };

printf("1-%d\n", ages[0]);
printf("1-%d\n", ages[1]);

printf("2-%p\n", &ages[0]);
printf("2-%p\n", ages);
printf("2-%p\n", &ages);

printf("3-%d\n", *(&ages[1]));
printf("4-%p\n", *(&ages));
printf("5-%p\n", &ages[1]);
printf("6-%p\n", &ages+1);
printf("7-%d\n", *(*(&ages)+1));
printf("8-%ld\n", sizeof(1));

Output with questions in comments:

1-23 // value of position 0, OK
1-43 // value of position 1, OK
2-0x7fff1fd500f0 // adress of the beginning of array, OK
2-0x7fff1fd500f0 // same as above, OK
2-0x7fff1fd500f0 // because ages is not a pointer, same as above, OK
3-43 // get address of ages, advance 4 bytes and then give me the value that is in that address, OK
4-0x7fff1fd500f0 // give me the address of ages, and then give the value that is in that address. The address I have in the print number 2, why doesn't return the value and show me the address? **NOT OK**
5-0x7fff1fd500f4 // give me the address of the position 1 of the array, the address that contains the number 43, OK
6-0x7fff1fd50104 // why I don't get the same number of the print 5? How I jump from f0 to 104? **NOT OK**
7-43 // why I need pointer of pointer, **NOT OK**
8-4 // this was just trying to understand print 6, OK

Can someone explain me prints 4, 6 and 7, and let me know if I'm thinking correctly on the other prints.


Your confusions all boil down to two things: how operator precedence works and what &ages means.

Let's look at the latter first. Obviously &ages is a pointer. But what is it a pointer to? It's not a pointer to int. Instead, it's a pointer to the type int[5].

So let's look at this:

printf("4-%p\n", *(&ages));

If you have a pointer to int[5], and you use * on it, you get what it points to: int[5]. This then decays to a pointer when being passed to printf. Specifically, a pointer to the first element of the array.


printf("5-%p\n", &ages[1]);

Is a matter of operator precedence. Using explicit parenthesis, this is &(ages[1]); [] has higher precedence than &. Well, we know that ages[1] is the second int in the array. Using & on it will return a pointer to the second element in the array.

In a similar way:

printf("6-%p\n", &ages+1);

Operator precedence tells us that this is really (&ages) + 1. And remember, what is &ages? That's right, a pointer to int[5].

When we perform pointer arithmetic, we add the size of the object being pointed to to the address. That object is int[5], whose size is 20. Or in hex, 0x14. Therefore, you get an address 0x14 bytes from the start of the array.

As for:

printf("7-%d\n", *(*(&ages)+1));

Operator precedence tells us that this expression is really *((*(&ages)) + 1). So you get a pointer to int[5], turn it back into an int[5], then add 1 to it. That requires decaying the int[5] into an int*, then using pointer arithmetic. Then you access the value at that address.