• We’re currently investigating an issue related to the forum theme and styling that is impacting page layout and visual formatting. The problem has been identified, and we are actively working on a resolution. There is no impact to user data or functionality, this is strictly a front-end display issue. We’ll post an update once the fix has been deployed. Thanks for your patience while we get this sorted.

C++ :Pointers, I need an explanation.

JumBie

Golden Member
Can someone explain this block of code to me in simple terms, lol. It has me quite confused.


Code:
// more pointers 
#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;
}
cout << numbers[n] << ", ";   return 0; 
}
 
Last edited by a moderator:
Code:
// more pointers 
 #include <iostream>  
using namespace std;   
int main ()  
{   
int numbers[5];  
int * p;         
p = numbers;     

*p = 10;        //numbers[0] is 10 (thought it had to be declared as number[0]=10 )

p++;  *p = 20;  //numbers[1] is 20 (add 1 to p now numbers[1] value is 20 )

p = &numbers[2];  *p = 30; //numbers[2] is 30(no idea why it references the address) 

p = numbers + 3;  *p = 40; //numbers[3] is 40(did not know you could address numbers[3] by adding 3 to array numbers   )

p = numbers;  *(p+4) = 50; //numbers[4] is 50(no idea how *(p+4) works   )

for (int n=0; n<5; n++)     
cout << numbers[n] << ", ";    

return 0; 

} cout << numbers[n] << ", ";   return 0;  }

Use code tags, it will help preserve your formatting. I can't edit every post for you 🙂.

http://forums.anandtech.com/showthread.php?t=2069847

Markbnj
Programming mod
 
Last edited by a moderator:
> p = &numbers[2]; *p = 30; //numbers[2] is 30(no idea why it references the address)

Some questions to think about:

What is the difference between: &numbers, &numbers[0], &numbers[1] ?

What is the difference between &numbers[1] and numbers[1] ?

For the second question, imagine that "int numbers[5]" created the storage for the array at location 1000. that means the memory at location 1000 would look something like 1000 = [ 10 ] [ 20 ] [ 30 ] [ 40 ] [ 50 ]
 
> p = &numbers[2]; *p = 30; //numbers[2] is 30(no idea why it references the address)

Some questions to think about:

What is the difference between: &numbers, &numbers[0], &numbers[1] ?

What is the difference between &numbers[1] and numbers[1] ?

For the second question, imagine that "int numbers[5]" created the storage for the array at location 1000. that means the memory at location 1000 would look something like 1000 = [ 10 ] [ 20 ] [ 30 ] [ 40 ] [ 50 ]

So I guess this is all just showing ways in which to write the code when It could all be written like.

Soo....

Code:
p=numbers; *p=10;
means...
numbers[0]=10 ?

p++ ; *p=20 
means numbers[1]=20

p=&numbers[2];
references the address...but I'm assuming based on your logic that the address 
is the same as the location so its addressing the location where numbers[2] is 
and giving it the value 20.

p=numbers +3
I never knew you could reference a section(int) in an array by adding 3. Is 
this equivalent to numbers=numbers[0]+3?

p=numbers; *(p+4);
uhh... numbers=numbers; <-that ends the line but we already know they equal each 
other isnt this useless. Then it references (p+4) or numbers+4? Once again is 
this number[0]+4? Which then becomes numbers[4], I did not know you could 
do this.
 
Last edited:
You're doing well.

Notice the similarity between p = (numbers + 3) and (p + 4) ?

In both cases the compiler knows that you are starting with pointer to an integer array and adding to it. So it does the * sizeof (int) for you. That is if p = memory location 1000 and you say p + 3, it actually means 1012 not 1003.

p=numbers; *(p+4);
uhh... numbers=numbers;

Are you sure? Why would p still be equal to numbers after executing the other lines of code? Try adding some cout << &p statements.
 
The value of the pointer + 4 times the size in bytes of int?

*p+(4x4)?

Correct.

Code:
 so of this is your number array.  And P pointed to numbers[0], 
  
 *p
 [B][int][/B][int][int][int][int]
  
  
 where does it now point to after 
 *p = *p + ( 4 * sizeof(int) ) ?
 [hint] you are physically moving where *p points to.
  
  ?      ?     ?     ?     ?
 [B][int][/B][int][int][int][int]
 
You're doing well.

Notice the similarity between p = (numbers + 3) and (p + 4) ?

In both cases the compiler knows that you are starting with pointer to an integer array and adding to it. So it does the * sizeof (int) for you. That is if p = memory location 1000 and you say p + 3, it actually means 1012 not 1003.



Are you sure? Why would p still be equal to numbers after executing the other lines of code? Try adding some cout << &p statements.

Code:
int numbers[5];
int * p;
p = numbers;
*p = 10;
cout << &p<<"\n";
p++;  *p = 20;
cout << &p<<"\n";
p = &numbers[2];  *p = 30;
cout << &p<<"\n";
p = numbers + 3;  *p = 40;
cout << &p<<"\n";
p = numbers;  *(p+4) = 50;
cout << &p<<"\n";

The output:
0x22ff18
0x22ff18
0x22ff18
0x22ff18
0x22ff18

...not exactly sure why this is so complicated for me. I'm just having trouble understanding how you can reference a particular section of an array by these methods of use.
 
Correct.

Code:
 so of this is your number array.  And P pointed to numbers[0], 
  
 *p
 [B][int][/B][int][int][int][int]
  
  
 where does it now point to after 
 *p = *p + ( 4 * sizeof(int) ) ?
 [hint] you are physically moving where *p points to.
  
  ?      ?     ?     ?     ?
 [B][int][/B][int][int][int][int]
*p points to numbers[16]?
 
*p points to numbers[16]?

There is no element in numbers at spot 16. That would be out of the bounds of the array. Here's a clue that might help: when you increment the pointer (p++), you aren't literally incrementing the memory address by 1 or anything like that. You are moving to the next "spot" in memory (so the next integer in your array, in this example).
 
Code:
The output:
0x22ff18
0x22ff18
0x22ff18
0x22ff18
0x22ff18

...not exactly sure why this is so complicated for me. I'm just having trouble understanding how you can reference a particular section of an array by these methods of use.[/QUOTE]

D'oh, sorry, that should be cout p, not &p.  Since p is a [b]pointer to[/b] integers, the value of p is where it is pointing.  The address of p is where p itself is located, the chunk of memory to hold its value.
 
There is no element in numbers at spot 16. That would be out of the bounds of the array. Here's a clue that might help: when you increment the pointer (p++), you aren't literally incrementing the memory address by 1 or anything like that. You are moving to the next "spot" in memory (so the next integer in your array, in this example).

this is a good point and is why it's important that he know that his ints are usually 32 bits large on a PC.
I believe this can be changed with a compiler "flag" that tells the compiler to make all ints 64 bits, if you want, in which case the next spot would not be 32 bits off, but 64.
I believe this depends on the compiler implementation.
http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en010300
E.g. in pic16s and pic18s, (microchip) an int is 16bits large, and you have to use "long i" if you want 32 bits and "long long i" if you want a 64 bit large integer.
 
Last edited:
related:
Code:
int * p;
// because of *, 'p' is a chunk of memory the size of the architecture "word" size, which will be used to store the location of the int.
words-- http://en.wikipedia.org/wiki/Word_(computer_architecture)
so in a 32bit windows installation the word length is 32bits, which means the pointer length is 32 bits by default as well.
in a 64bit installation the word length is, I believe, 64bits. This extra overhead is one of the reasons why 32 bit code run in a 64 bit installation is about 5-10% slower than on a 32bit windows installation (games for example). Having to carry around that extra data slows the processor down a bit as far as "useful work done" is concerned. Though, the tradeoff for using more than 4GB of RAM is either worth it, or mandatory now, depending on how much memory you need.
 
Last edited:
once you get good with pointer arithmetic you're basically smart enough for anything.
it's annoying at first but now it's my favorite

Haha, haven't heard that before, but I think I agree. OP, don't feel bad, C/C++ pointer arithmetic is about as bad as it gets, or at least until you try to tackle pointers to functions that return pointers.
 
so of this is your number array. And P pointed to numbers[0],

*p
[int][int][int][int][int]


where does it now point to after
*p = *p + ( 4 * sizeof(int) ) ?
[hint] you are physically moving where *p points to.

? ? ? ? ?
[int][int][int][int][int]

"*p = *p + (4 * sizeof(int))" dereferences p and adds 16 (assuming 4 byte int) to its value. If p points to the first element of numbers, the statement is the equivalent of "numbers[0] += 16."

If you're intending to perform pointer arithmetic, the statement should be "p = p + (4 * sizeof(int))." However, that sets p to numbers[16], well past the end of the 5-element array.

Do you understand that adding a value to a pointer already accounts for the "sizeof(Type)" calculation? i.e. If you want to have it point to the fifth element of numbers, you simply write "p = p + 4."
 
This cleared up a lot of the confusion when it comes to pointers and arrays.
Code:
#include<iostream>
using namespace std;
int main ()     
{         
int num[5];         
int * ptr_p;          

ptr_p = num;    //ptr_p points at first element         
*ptr_p = 1;        //Store the value 1          

ptr_p++;        //Increase to second element         
*ptr_p = 2;        //Store the value 2          

ptr_p = &num[2];    //Get addres of third element         
*ptr_p = 3;        //Store the value 3          

ptr_p = num + 3;    //Goto element 4         
*ptr_p = 4;        //Store the value 4          

ptr_p = num;    //Point at first element         
*(ptr_p+4) = 5;    //First goto element 5 and then store 5          

//Now print value of each element         

   for (int i=0; i<5; i++)             
cout << num[i] << '\n';         
return 0;     
}
also these examples

Code:
char num[10]; 
char *ptr_toarray = &num[0];

//In this example we declare an array with ten elements. 
Then we say that the pointer *ptr_toarray must point at 
the first element of the array 


//Now we could do the following (note the round brackets)
char num[10]; char 

*ptr_toarray = &num[0]; 
*(ptr_toarray + 2);

//This is the same as num[2]. Or we can do this:

char num[10]; 
char *ptr_toarray = &num[0]; 
ptr_toarray++;

//So now the pointer is pointing at the second element: 
num[1]. (We also could write: ptr_toarray=ptr_toarray+1;)
 
Do you understand that adding a value to a pointer already accounts for the "sizeof(Type)" calculation? i.e. If you want to have it point to the fifth element of numbers, you simply write "p = p + 4."


Yes... that was a mistake... there should have been no *.

p = p + 4 * (sizeof(int));


Back in 1998-2002 (Visual Studio 4, Visual Studio 6) when I last truly used C++ (prior to all the .net stuff), this was not the case, so no I did not recognize it had changed.
 
Last edited:
IMO, instead of trying to figure out how that code works, learn the fundamentals and theory first then apply that to the code and it'll be much easier to understand.
 
One thing to point out, in C++ arrays are really just fancy notation for pointers. (There is more to it than that, yes, they make guarantees that allow for compiler optimizations).

So when you say "numbers[1]" you are really saying *(numbers + 1) (which, btw, will compile).

Hope this helps a little.
 
Back
Top