Addresses and pointers
Every variable lives somewhere in memory, and that location has an address. The unary & operator gives you a variable's address: &score. A pointer is a variable whose value is an address. int* p = &score; declares p as "pointer to int" and stores the address of score in it.
Following a pointer to the thing it points at is called dereferencing, and uses unary *: *p is score. Reading *p reads score; assigning *p = 95 changes score. The same symbols mean different things in different places, which is the main source of confusion:
| You write | Where | Meaning |
|---|---|---|
int* p | in a declaration | p is a pointer to int |
&x | in an expression | the address of x |
*p | in an expression | the object p points at |
int& r | in a declaration | r is a reference (another name) for an int, covered below |
#include <iostream>
int main() {
int score = 90;
int* p = &score; // p holds the address of score
std::cout << "score = " << score << '\n';
std::cout << "*p = " << *p << '\n'; // follow the pointer
*p = 95; // writes into score
std::cout << "score = " << score << '\n';
int bonus = 5;
p = &bonus; // a pointer can be re-aimed
*p += 1;
std::cout << "bonus = " << bonus << ", score still " << score << '\n';
std::cout << std::boolalpha << (p == &bonus) << '\n'; // compare addresses
std::cout << "a pointer takes " << sizeof(p) << " bytes\n";
}score = 90
*p = 90
score = 95
bonus = 6, score still 95
true
a pointer takes 8 bytesAdd int** pp = &p; (a pointer to a pointer) and change bonus through **pp. Draw the three boxes on paper first.
std::cout << p prints the address itself, something like 0x16fdff2ac. It changes on every run (the operating system randomises where the stack and heap live), so it is useless in a verified example and rarely useful in a real program. Print *p to see the value, and compare pointers with == when you need to know whether two point at the same object.cannot initialize a variable of type 'int *' with an lvalue of type 'int'
int main() {
int score = 90;
int* p = score;
return *p;
}main.cpp:3:10: error: cannot initialize a variable of type 'int *' with an lvalue of type 'int'
3 | int* p = score;
| ^ ~~~~~A pointer holds an address, and score is an int value, not an address. C++ never converts a plain integer into a pointer silently: that would let 90 be treated as memory location 90.
Take the address with &.
int main() {
int score = 90;
int* p = &score;
return *p == 90 ? 0 : 1;
}