ballardcw
ballardcw

Reputation: 1

Arrays and pointers arithmetic confusion

#include <iostream>
using namespace std;

int main ()
{
  int numbers[5];
  int * p;
  p = numbers;  *p = 10;
  p++;  *p = 20;
  p = &numbers[2];  *p = 30;
  p = numbers + 3;  *p = 40;
  p = numbers;  *(p+4) = 50;
  for (int n=0; n<5; n++)
    cout << numbers[n] << ", ";
  return 0;
}

Fairly new coder here. This is an example taken from the pointers page on cplusplus.com. They talk about dereferencing, the address of operator, and then they talk about the relationship between arrays and pointers. I noticed if I simply printed out a declared array it spits out the address of the array. I'm really trying to understand exactly what some of these lines of code are doing and am having a hard time.

Everything makes sense up until *p=10. I read this as, "the value being pointed to by pointer p is equal to 10" but an array isn't just one value. In this case it's 5... So, whats the deal? Will the compiler just assume we are talking about the first element of the array?

Even more confusing for me is p++;. p right now is the address of the array. How do you do p=p+1 when p is an address?

I understand p= &numbers[2];. As well as the following *p = 30;.

p = numbers + 3; confuses me. Why are we able to take an address and just add 3 to it? And, what does that even mean?

Everything within the for loop makes sense. It's just printing out the array correct?

Thanks for your help in advance!

Upvotes: 0

Views: 878

Answers (5)

Azeem
Azeem

Reputation: 14687

Let's break it down:

int numbers[5];
int * p;

Assigning the array variable to a pointer means that the pointer will be pointing to the first element:

p = numbers;      // p points to the 1st element
*p = 10;          // 1st element will be 10

p++;              // go to next location i.e. 2nd element
*p = 20;          // 2nd element will be 20

You can do pointer arithmetic and it works according to the type. Incrementing an int pointer on a 32-bit machine will do a jump of 4 bytes in memory. On a 64-bit machine, that will be 8 bytes. Keep in mind that you cannot do this with a void pointer.

p = &numbers[2];   // assign the address of 3rd element
*p = 30;           // 3rd element will be 30

p = numbers + 3;   // numbers + 3 means the address of 4th element
*p = 40;           // 4th element will be 40

p = numbers;       // p points to the 1st element
*(p + 4) = 50;     // p + 4 means the address of 5th element
                   // dereference 5th location and assign 50
                   // 5th element will be 50

Upvotes: 1

Saikat Das
Saikat Das

Reputation: 322

As Pointed out this due to pointer arithmetic. So both array numbers and pointer p are int, so after assigning numbers's base address to pointer p and the *p=10 does numbers[0]=10

Now when you do p++ the address of p is incremented but not to the next numeric value as in normal arithmetic operation of ++ but to the address of the next index of numbers.

Let's assume a int is 4byte of memory and numbers's initial address is 1000. So p++ makes address it to be incremented to 1004 which is numbers[1] Basically it points to the next int variable position in memory. So when *p = 20 is encountered the value 20 will be assigned to the next adjacent memory i.e. 1004 or numbers[1]=20.

After that the p directly assigned address of 3rd index numbers[2] i.e 1008 (next int var in memory). Now p is pointing to the 3rd index of numbers so *p=30 is again numbers[2]=30

p = numbers + 3; *p = 40; does similar thing that is assigns base address of numbers incremented by 3 indexes (1000 + 3*sizeof(int) =1012 ==> 1000 + 3*4 =1012) to p and assigns 40 to that. so it becomes equivalent to numbers[3]=40.

Then p = numbers; *(p+4) = 50; is assigning 1000 to p and the adding 4 to the address of p by using the () and assigns 50 to the value by using *() which is value of the address(1000+ 4*4 = 1016) inside the braces.

Upvotes: 2

DWilches
DWilches

Reputation: 23065

Using a pointer like this in C++: p = numbers makes p point to the first element of the array. So when you do p++ you are making p point to the second element.

Now, doing *p = 10 assigns 10 to whatever p is pointing to, as in your case p is pointing to the first element of the array, then *p = 10 is the same as numbers[0] = 10.

In case you see this later: *(p + i) = 20, this is pointer arithmetic and is the same as p[i] = 20. That's why p[0] = 10 is equivalent to *(p + 0) = 10 and equivalent to *p = 10.

And about your question: How do you do p=p+1 when p is an address?: as arrays in C++ are stored sequentially in memory, if the element p is pointing at memory address 6400010 then p++ points at 6400014 assuming each element pointed by p occupies 4 bytes. If you wonder why p++ is 6400014 instead of 6400011, the reason is a little magic C++ does: when increasing a pointer, it doesn't increase by 1 byte but by 1 element so if you are pointing to integers, each one occupying 4 bytes, then p will be increased by 4 instead of 1.

Upvotes: 1

Tanuj Yadav
Tanuj Yadav

Reputation: 1277

1> p=numbers;
pointer p now points to the start of the array, i.e first element.

2> *p=10;
first element now becomes 10, as p is pointing to the first element.

3> p++;
this moves the pointer to the next element of the array, i.e second element
So, again *p=20; will make second element=20

4> p = &numbers[2];
this statement means that p now points to 3rd element of the array.
So, *p = 30; will make 3rd element=30

5> p = numbers + 3;
Wen we do p=numbers+1; it points to second element, so p=numbers+3; will now point to 4th element of array. *p = 40; make the fourth element=40

6> p = numbers;
Again p points to first element of array
*(p+4) = 50; will now make 5th element=50

Upvotes: 0

Geoduck
Geoduck

Reputation: 8999

There are a lot of pages on the web on how pointers work. But there are a couple things to quickly point out.

int* p;

The above line mean p is a pointer to an int. Assigning something to it doesn't change what it is. It is a pointer to an int, not an array of int.

int number[5];
p = number;

This assignment takes the address where the array is stored, and assigns it to p. p now points to the beginning of that array.

p++;

p now points to the 2nd int in the array. Pointers are incremented by the size of the object they point to. So the actual address may increase by 4 or 8, but it goes to the next address of an int.

*p = 30;

This is an assignment, not a comparison. It doesn't say that what p points to is 30, it copies 30 into the address pointed to by p. Saying "equals" is generally confusing in programming terms, so use either "assign" or "compare" to be clear.

Upvotes: 0

Related Questions