user1845593 - 1 year ago 99
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 = &num; // create a pointer and point him to 0x54
``````

``````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));
``````

``````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.

This:

``````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.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download