Verifying that My Understanding of Pointers Is Correct

Hello,

This is just a little summary of pointers that I wrote, I would appreciate it if you could verify that it is correct and maybe add a little more if there's something else you think I should add.

[u]Pointers[/u]

When initialising, an asterisk means that it is a pointer. The data type (‘int’, ‘byte’ etc.) means that it will point to that data type. For example, this just initialises a pointer called ptr which points to an int, but doesn't actually point to any address yet.

int *ptr;

Saying

int *ptr = 50;

means that you initialise a pointer to point to address no. 50. You would usually give the address of a variable here (using ‘&’) It is the same as saying:

int *ptr;
ptr = 50;

When running, * means value stored at the address which it points to (the real info you want). So in this case, the value at the address is set to 50. Recognise the different uses of the asterisk when initialising the pointer and when using while the rest of the program is running.

*ptr = 50;

Just using ptr (no asterisk) will give you the address, that it is pointing to, not the value stored there.

Saying

int x = 10;
int *ptr = &x;

Means that ptr now points to x. *ptr would now return 10 (the same as just saying x) and ptr would return the memory address of x (the same as saying &x).

And, if I'm right with all this, what's the point of using pointers (pun not intended)? Why not just use the variable itself and its address if you need to (x and &x instead of *ptr and ptr)?

Thanks.

For example, this just initialises a pointer called ptr which points to an int, but doesn't actually point to any address yet.

Code:

int *ptr;

That defines a pointer but does not initialise it.

int *ptr = 50;

Should be written int *ptr = (int*)50;

what's the point of using pointers

What's the point of writing an address on a letter? Why don't I just take it to the house and push it through the letterbox?

Simple exampleSerial.println ("Hello world"); Here, the "println" function is given the address of the string (which could be megabytes long on a machine with more memory), but the string stays where it is, and only the address is given.

euge64:
And, if I’m right with all this, what’s the point of using pointers (pun not intended)? Why not just use the variable itself and its address if you need to (x and &x instead of *ptr and ptr)?

Well, say you need to pass a 1000-byte structure to a function. Which is easier? Pass down a 2-byte pointer, or copy all 1000 bytes? And if you do pass a copy, what if the function wants to change something? Then you have to copy 1000 bytes back.

x and &x instead of *ptr and ptr

Passing by reference is a more modern way of passing a pointer. It's the same concept though.

Also the [] makes a variable a pointer

So for instance;

int arrayVar[3]={100,200,300};
int* intPointer;
intPointer=arrayVar;

//you can now assume that intPointer and arrayVar
//are completely interchangeable
//therefore you can now say
Serial.println(intPointer[0]);
Serial.println(intPointer[1]);
Serial.println(intPointer[2]);

//or You can even say
Serial.println(*arrayVar);
Serial.println(*(arrayVar+1));
Serial.println(*(arrayVar+2)); 

//even though you'd expect
Serial.println(arrayVar[0]);
Serial.println(arrayVar[1]);
Serial.println(arrayVar[2]);
//spookily, you can also say
Serial.println( 0[intPointer]);
Serial.println( 1[intPointer]);
Serial.println( 2[intPointer]);

Thanks for your reply. I was only guessing with the int *ptr = 50 because I haven't seen anyone do that.

Simple example

Serial.println ("Hello world");

Here, the "println" function is given the address of the string (which could be megabytes long on a machine with more memory), but the string stays where it is, and only the address is given.

Sorry, I can't see how it gives it the address of the string, nor how pointers are involved. Do I need some kind of knowledge on the workings of print()?

What's the point of writing an address on a letter? Why don't I just take it to the house and push it through the letterbox?

Why don't you? It's not as if there's some kind of convenience factor for the Arduino in "posting" it rather than going to the address itself, is there? And wouldn't it need to go to the address anyway to get its value?

Well, say you need to pass a 1000-byte structure to a function. Which is easier? Pass down a 2-byte pointer, or copy all 1000 bytes? And if you do pass a copy, what if the function wants to change something? Then you have to copy 1000 bytes back.

So in using x, the integer itself, it copies all the data to another place in memory? That seems a bit counter-intuitive — why didn't Dennis Ritchie just make it so that it would pass the address instead? Anyway, it makes sense to use a pointer in that case.

Serial.println(intPointer[0]);
Serial.println(intPointer[1]);
Serial.println(intPointer[2]);

Wouldn't that just print the memory addresses? Or are you saying that the square brackets mean that you don't need to use the asterisk before as you normally would with a normal variable (not an array)?

And then

Serial.println(arrayVar[0]);
Serial.println(arrayVar[1]);
Serial.println(arrayVar[2]);

would result in some copying of the data to a new location in memory, so it is slower and less efficient?

AWOL: //spookily, you can also say Serial.println( 0[intPointer]); Serial.println( 1[intPointer]); Serial.println( 2[intPointer]);

That is spooky. Now I'm gonna have nightmares about C!

Why don't you?

Because I don't have the time to deliver my own letters. I give them to an agent to do it for me.

AWOL:

Why don't you?

Because I don't have the time to deliver my own letters. I give them to an agent to do it for me.

No, come on, seriously, is that how it works? The Arduino/ATmega has its own "agent" to get the values at the memories? Can you explain that in terms of a "locker" analogy - various lockers in memory with numbers/addresses on them?

Thanks for your help guys.

euge64: So in using x, the integer itself, it copies all the data to another place in memory? That seems a bit counter-intuitive — why didn't Dennis Ritchie just make it so that it would pass the address instead? Anyway, it makes sense to use a pointer in that case.

Unless you use the & (reference) syntax, functions are passed arguments by value (ie. copies).

In the case of integers the difference may be minimal (except that changes the function makes do not get propagated back to the original).

In the case of simple functions (eg. to take the square root of a number) passing a copy is more efficient than passing an address (from which you then have to get the original value).

Once you get into larger structures, eg. a name-and-address record which might be thousands of bytes long, passing a 2 (or 4) byte pointer is much more efficient than copying all the data.

euge64: Serial.println(intPointer[0]); Serial.println(intPointer[1]); Serial.println(intPointer[2]);

Wouldn't that just print the memory addresses? Or are you saying that the square brackets mean that you don't need to use the asterisk before as you normally would with a normal variable (not an array)?

No it wouldn't print the memory addresses. the [] and the * format are interchangeable So it prints 100,200,300 just like any regular array;

And then

Serial.println(arrayVar[0]);
Serial.println(arrayVar[1]);
Serial.println(arrayVar[2]);

would result in some copying of the data to a new location in memory, so it is slower and less efficient?

No. It's exactly the same as the example directly above it. It will just print the stored integers of the array.

euge64: No, come on, seriously, is that how it works? The Arduino/ATmega has its own "agent" to get the values at the memories? Can you explain that in terms of a "locker" analogy - various lockers in memory with numbers/addresses on them?

It's absolutely nothing to do with Arduino/ATmega. This is basic C/C++ we are talking about.

I don't want to seem unkind, but this is basic C stuff. Read a tutorial on using pointers in C. The Arduino does not corrupt that concept.

Google "pointers in c". There are 39+ million hits. Some of them should help you.

The Arduino/ATmega has its own "agent" to get the values at the memories?

Yes, the agent is the Serial.print function. I give it the address of some data I (my program) want to deliver to the user, and the agent (the Serial function "println") presents that data to the serial port.

[quote author=Nick Gammon link=topic=270891.msg1909658#msg1909658 date=1412588984] I don't want to seem unkind, but this is basic C stuff. Read a tutorial on using pointers in C. The Arduino does not corrupt that concept. [/quote]

Ok, sorry, it's just that the ones I read didn't go into all this detail. Thanks anyway.

C++ simply could not work without pointers, but a lot of the functionality is hidden, like the omnipresent but largely unseen "this" pointer.

//you can also have ponters to pointers //for example

int **intPointyPoint=&intPointer;
Serial.println(**intPointyPoint);
Serial.println(*(*intPointyPoint+1));
Serial.println(*(*intPointyPoint+2));

And, you guessed it. This will print those same three stored values

You use pointers all over the place in C - use of arrays and passing multi-element arguments to functions as has already been mentioned. It's just that they're hiding in plain sight - until you understand pointers though, you don't notice them.

Pointers are crucial for dynamic memory allocation - take a look at malloc. n.b. don't actually use malloc or its buddies on an arduino with little RAM - that way lies fragmentation and hard to explain crashes.

Once you have malloc, pointers make it easier to build some kinds of data structures - linked lists, trees, sparse arrays etc.

Pointers have many uses, but traditionally there's a bit of a learning curve before they click for you. Just be happy you don't need that understanding on day one of your C adventures.