I'm sure that at this point you've figured out that the "*" (asterisk) character has something to do with pointers. There are a couple different contexts in which this character can appear. That means, this character can have different meanings depending on where it's placed in your code.
Here is one context:
This is an integer:
int i = 123;
This is an int-pointer (a pointer that can point to integers):
int* ptr;
The only semantic difference between these two lines of code is the "*" character, which signifies that this variable is a pointer (there is one other difference - the fact that we initialized the integer, but didn't initialize the pointer, but that's not so important right now).
The "*" doesn't have to sit right next to the type either. It can be separated by whitespace. For example, all three of the following lines of code are identical:
int* ptr;
int *ptr;
int * ptr;
Whichever you use is personal preference.
Our pointer "ptr" isn't actually pointing to anything yet. Just like how
int
s store integers, pointers store addresses to things.
More specifically, an int-pointer stores an address to an int. A double-pointer stores an address to a double. A string pointer stores an address to a string, etc.
Let's initialize "ptr" by giving it an address to point to. Let's give it the address of our integer "i". That would look like this:
1 2 3
|
int i = 123;
int* ptr = &i;
| |
I've just introduced a new character, the ampersand (&). Just like the asterisk (*), the ampersand has different meanings in different contexts. In this context it means "address-of". If you think about it, it makes sense if you read the code like you would if it were written in plain English: Integer pointer "ptr" equals
address of "i".
You can experiment with this, just to get more familiar with addresses. You don't even need pointers for this. Try running the following code:
1 2 3 4 5 6 7 8 9 10 11 12
|
#include <iostream>
int main() {
int i = 123;
std::cout << "Address of \"i\":" << std::endl;
std::cout << &i << std::endl;
std::cin.get();
return 0;
}
| |
This will print the address of "i". The address of "i" will most likely change every time you run this program. The address of "i" is just the actual memory location in which the integer "i" happened to be allocated. Most of the time (when dealing with pointers), we're not actually even interested in the actual locations of where things are stored. We, as programmers, don't need to know where our variables are stored as long as we have a "handle" by which to access them, which is basically what a pointer is - don't let that confuse you.
Back to the earlier example, take a look at this:
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
|
#include <iostream>
int main() {
int i = 123;
int* ptr = &i;
std::cout << "Value of \"i\":" << std::endl;
std::cout << i << std::endl << std::endl;
std::cout << "Address of \"i\":" << std::endl;
std::cout << &i << std::endl << std::endl;
std::cout << "Value of \"ptr\":" << std::endl;
std::cout << ptr << std::endl << std::endl;
std::cout << "Address of \"ptr\":" << std::endl;
std::cout << &ptr << std::endl << std::endl;
std::cout << "Value of integer pointed-to by \"ptr\":" << std::endl;
std::cout << *ptr << std::endl;
std::cin.get();
return 0;
}
| |
This code prints the following:
1.) The value of "i" (123)
2.) The address of "i", whatever it happens to be.
3.) The value of "ptr". Notice, that this is the same as the address of "i", because i's address is being stored as the pointer's value.
4.) Just for fun, we're printing the pointers value, which is actually something you can do. "ptr" is technically also just another variable, so you're free to print it's actual address.
5.) Finally, the value of the integer that "ptr" happens to be pointing to, which in our case is the value of "i", which is 123.
Notice, line 22 makes use of another meaning of the asterisk (*) character. On this line, it means "value-of", which in plain English would be read as "value-of ptr" or "value pointed by ptr".