Hello, I am looking for some examples involving pointers, Ive been trying to get my head around them, on and off for a few months, and I believe I understand the basics of what they do. But all the examples I can find of them, are basically the same, pointing to a variable, then the variable get changed using the pointer etc. But I am looking for examples that are more real life, not too complicated, but an example that will show what they are actually used for in pieces of code.
If anyone has any examples they would be willing to show, it would be greatly appreciated.
why not write yourself a nice linked list class or tree class with them? Those are classic pointer problems that have tons of source code / how to / etc online.
Before you go too far down a rabbit hole, pointers are NOT used as much as they used to be when the language was younger. They have their merits, but there are other ways to do most of the things that could only be done with pointers back when.
If you can make a little linked list program and get that working cleanly, you will know about as much about pointers as you need to for practical coding. For kicks you may also want to use a pointer to make an array (do this first, its simple) and do a bit of messing with the synax…
int *x = new int[10]; //this is an array of integers, really, just used a pointer to get there
int * ip = x;
for(j = 0; j < 10; j++)
{
*ip++ = j; //use a pointer to move through the array
}
for(j = 0; j < 10; j++)
{
x[j]= j; //same result as above loop, direct access array style
}
or basically understand the &x (get a pointer to), *x (dereference first location of a pointer, may be the ONLY location), and x[index] (access the nth location of a pointer, as if it were an array) and understand new/delete keywords. If you can read all this syntax and do the linked list... you are in pretty good shape..
I personally avoid * syntax and pointer math if at all possible, both are avoidable. * can make math code confusing (*x*=*y or z = *x * *y, goodness) and pointer math is almost always show-off code more than practical. The second one is the same as z = x[0] * y[0];
I will try the linked list idea, although I have never worked with them before, it is good practice. However, just for just now, I am doing the array/pointer like you suggested, but I am having some issues in understanding it i believe.
What I do not understand is why &ptr does not return the same address as the array. Is the pointer stored just before the array in memory? If so, why does ptr return the same address?
Also what is the point in the address operator on the line &arr, if printing arr, just gives the memory location too?
I think I need to read more to get a better understanding of pointers, but the documentation doesnt seem to be enough to get my head around it all
Because the pointer itself is stored in memory and as such, it has its own unique memory address just like any other variable.
An array is a constant pointer to its very first element, so when you send arr to the output stream, you will get the memory address of the very first element in your array displayed. Since your variable ptr points to that memory also, when you send ptr to the output stream, the same memory address is displayed. However, the pointer itself also has its own unique memory address on the stack. So when you send &ptr to the output stream, you're sending the memory address of the pointer itself to the output stream.
I think you're overthinking pointers as do most beginners. In truth, they're very simple to grasp. Forget about everything you know about pointers and just remember this: A pointer is a variable which stores a memory address of some other variable or structure. Done. If you're coming from a C# background, then think of pointers as reference variables. They refer to other variables. Why do we need them? Because they allow us to dynamically allocate memory and send objects from one function to another without copying them.
An array is implicitly converted to a pointer to its first element in many cases. When you print arr you are actually printing the address of the first element in arr (&arr[0]). ptr also points to the first element in arr so that is why it prints the same thing for both arr and ptr.
The first element in an array is stored at the first address of the array. This means that the address of the array (&arr) and the address of the first element in the array (&arr[0]) will be the same, and that is why &arr also prints the same as arr and ptr. There is however one difference. The type of &arr is a pointer to an int array of size 3 (int(*)[3]) which is different from the other two that has type pointer to int (int*).
This is an oversimplification which is not helpful. An array is not a pointer.
I think it's helpful to understand the relationship between pointers and arrays early on. An array name is indeed a constant pointer to the first element of the array. You can use the array name as a pointer for random access to elements.
#include <iostream>
#include <type_traits>
template < typename T > void what_is( const T& x )
{
std::cout << std::boolalpha
<< "is it an array? " << std::is_array<T>::value << '\n'
<< "is it a pointer? " << std::is_pointer<T>::value << '\n'
<< "how many bytes does its object representation take? " << sizeof(x) << '\n' ;
ifconstexpr ( std::is_array<T>::value )
std::cout << "how many elements are there in this array? " << std::extent<T>::value << '\n' ;
}
int main()
{
int array[123] {} ;
std::cout << "array\n" ;
what_is(array) ; // array
// is it an array? true
// is it a pointer? false
// how many bytes does its object representation take? // 123 * sizeof(int)
// how many elements are there in this array? 100
std::cout << "\n+array\n" ;
what_is( +array ) ; // note: array to pointer decay
// is it an array? false
// is it a pointer? true
// how many bytes does its object representation take? // sizeof(pointer to object)
}
I had to learn that one recently too. Its not the same, C++ makes them look the same via a friendly syntax shortcut. However, because of the shortcut, you can treat them the same in almost all practical code, so while its technically incorrect, its practically / in code use still a very useful shortcut to know.
&ptr is the address of the address of the value you thought it would be.
its like saying
int ** p2d = &ptr;
ptr[0][0]; //this is arr[0]
Another thing I avoid is multi dimensional pointers :)
As for your program: congratulations, you have invented a reference. ptr is just a hand-rolled reference to arr. There are real world uses for this; say you are searching a container of objects looking for the maximum of some object.field. You can track the max with a pointer as a reference instead of a temporary object, saving copying a lot of information every time you find a bigger one as you iterate the container (say its not a container like an array where you could have just kept the index … though, if you think about the above for a bit, you will realize that an array index is a shortcut to a pointer as well -- arr[2] is the same as arr+2 is the same as ptr+2, though I am not sure arr can be used that way in syntax, I haven't had a need to try it). A pointer assignment only costs you an integer assignment, much cheaper than a fat class which under the hood may be doing 50+ times that amount of work.
A pointer type is expected, so array to pointer decay takes place:
There is an implicit conversion from lvalues and rvalues of array type to rvalues of pointer type: it constructs a pointer to the first element of an array. This conversion is used whenever arrays appear in context where arrays are not expected, but pointers are. https://en.cppreference.com/w/cpp/language/array#Array-to-pointer_decay
Ahhh that's nice I never knew unary '+' had a function. I guess it's still not so useful though because it can only be used in this context and for casting to int.