Incoming wall of text explanation:
Pointers are weird. I hated them when I first started learning them. But they allow us to do so many more things that would be next to impossible without them.
Try this out for size:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
#include <string>
#include <iostream>
struct myStruct
{
std::string structString;
};
int main()
{
myStruct *structPointer;
structPointer = new myStruct[5];
for (auto i = 0; i < 5; i++)
{
std::cin >> structPointer[i].structString;
}
for (auto i = 0; i < 5; i++)
{
std::cout << structPointer[i].structString << std::endl;
}
delete[] structPointer;
}
|
I guess it isn't too bad for you to learn to get used to using character arrays. We all had to learn how to use them at some point.
Pointers are weird. What a pointer is is something that stores the memory address of something else. So, "structPointer" is holding the memory address of a "myStruct" in memory. If you just do
std::cout << structPointer;
, you'll get the memory address of the thing. If you want to get the value, you can do this:
std::cout << *structPointer.myString;
The * deferences the pointer and you can actually access the values stored in the struct in memory.
The way arrays are handled is really cool.
You can do this:
int arr[5];
, and it will create an array of 5 integers. But how does it actually get "arr[3]"? When created, arrays are stored in a contiguous block in memory. "arr[0]" is the very first integer in the array, right? So, if you wanted "arr[1]", you just need the integer right after "arr[0]". In other words, you can step over in memory and grab it. It will take your index, and step over in memory to grab the thing your're asking for. It knows how much space your thing takes, so it can determine very quickly how far to step over.
When you do:
activity_pointer = new activityInfo [max];
, you are creating an array of activityInfo structures in a contiguous block in memory. You can index through them like you would if you just created an array with a fixed size. The only big difference that you need to be worried about is that it is created on the HEAP, not the STACK. Thus, you must delete it when you are done (you do not need to tell C++ how many you are deleting).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
|
int main()
{
int *integerPointer; //Pointer to an integer, but we can use this to dynamically create an array
int integerArraySize = 0;
std::cout << "Enter the number of integers in the dynamic array: ";
std::cin >> integerArraySize;
if (integerArraySize < 0 || integerArraySize > 20) //Let's keep it small for now
{
std::cerr << "Stop trying to break things." << std::endl;
std::cerr << "An error, you get." << std::endl;
exit(-3);
}
integerPointer = new int[integerArraySize]; //We just created a new array, in a contiguous block in memory. We can index through this just like a regular array!
for (auto i = 0; i < integerArraySize; i++)
{
integerPointer[i] = pow(i, 2);
}
for (auto i = 0; i < integerArraySize; i++)
{
std::cout << "We are looking at index: " << i << std::endl;
std::cout << "\tThe address of integerPointer[" << i << "]" << " is: " << &integerPointer[i] << std::endl;
std::cout << "\tThe value at integerPointer[" << i << "]" << " is: " << integerPointer[i] << std::endl;
}
delete[] integerPointer; //Make sure you delete
return 0;
}
|
For my machine, an "int" moves by 4 from address to address, but other data types will have different distances between them. For example, changing this to use "long long int" changes the distance between the addresses to be 0x08. Oh, addresses are in hex, by the way. So, don't be freaked out if you see letters in the memory addresses.
Pointers can get much more complex, but I'll let you sit on this for now. It's better to take pointers a little at a time so as to not get overwhelmed.