1. 变量、内存、比特位(bit)与字节(byte)

在 C++ 中:

  • 1 字节(byte) = 8 比特(bit)
  • 变量必须占有实际的内存空间
  • 64 位系统下指针大小通常是 8 字节(64 bit)

常见基础类型大小(不同平台可能略有差异,但通常如下):

类型 大小(字节) 大小(比特) 说明
bool 1 8 只占 1 字节
char 1 8 字符类型
short 2 16
int 4 32 最常用整数类型
long 4 或 8 32/64 Windows 是 4,Linux 是 8
long long 8 64
float 4 32
double 8 64
T*(指针) 8 64 64 位系统固定占 8 字节
1
2
3
int x = 10;           // 占 4 字节
double d = 3.14; // 占 8 字节
int* p = &x; // p 本身占 8 字节

2. 地址(Address)是什么?

每个变量存储在内存中的某个位置,该位置有一个唯一编号:地址

1
2
int n = 10;
std::cout << &n << std::endl; // &n = 变量 n 的地址

输出类似:

1
0x7ffeeabc1020
  • 0x 表示十六进制
  • 后面是内存地址

3. 指针(Pointer):保存地址的变量

指针本身是“一个变量”,它的内容是“另一个变量的地址”。

1
2
int n = 10;
int* p = &n; // p 里保存的是 n 的地址

内存示意:

1
2
3
4
+------------+       +------------+
| n (10) | <---- | p |
+------------+ +------------+
contains: 0x地址

指针相关操作:

1
2
3
std::cout << p;   // 输出指向的地址(&n)
std::cout << &p; // 输出指针变量自身的地址
std::cout << *p; // 解引用,访问 n

三者的关系:

表达式 代表的含义
p p 存的值(n 的地址)
&p p 自己的地址
&n n 的地址
*p p 指向的内容(等于 n)

4. 引用(Reference):变量的“别名”

引用相当于给变量起一个别名,不会创建新的存储空间。

1
2
int n = 10;
int& ref = n; // ref 是 n 的别名

内存图:

1
2
3
4
5
+------------+
| n (10) |
+------------+
↑ ↑
ref n 本身

关键性质:

  • 引用必须初始化
  • 引用不能为 null
  • 引用不能重新绑定其他变量
  • 对引用取地址 == 对原变量取地址

例如:

1
std::cout << &ref << std::endl;  // 等同于 &n

5. “引用没有空间,而指针有空间”是什么意思?

引用(Reference)

  • 语法上:引用不是独立对象,没有自己的存储位置
  • 实现上:编译器可能用指针实现引用,但这对用户不可见

引用只是一个强绑定的别名:

1
2
int x = 10;
int& r = x;

&r == &x 永远为真。


指针(Pointer)

指针本身是一个变量,因此必须有存储空间。

1
int* p = &x;

内存示意:

1
2
3
4
5
p occupies 8 bytes
+------------+ +-----------+
| p | -----> | x(10) |
+------------+ +-----------+
contains &x

你可以打印指针的地址:

1
std::cout << &p << std::endl;  // 指针变量自己的地址

6. 对比总结:引用 vs 指针

对比项 引用(Reference) 指针(Pointer)
是否有自己的存储空间 ❌(语义上无) ✔(必须有)
是否可为空 ❌ 不可为空 ✔ 可以为 nullptr
是否可重新绑定 ❌ 不可 ✔ 可改变指向
获取地址 &ref == &original &p 为指针自己的地址
使用方式 像别名一样 必须解引用 *p
常用场景 函数参数、返回值 动态内存、需要可空、数组操作

7. 综合示例:分别打印地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>

int main() {
int n = 10;

int& r = n; // 引用
int* p = &n; // 指针

std::cout << "Address of n (&n): " << &n << '\n';
std::cout << "Address of r (&r): " << &r << '\n';
std::cout << "Value of p: " << p << '\n';
std::cout << "Address of p (&p): " << &p << '\n';
std::cout << "Value pointed by p (*p): " << *p << '\n';

return 0;
}

可能输出:

1
2
3
4
5
Address of n (&n): 0x7ffeefbff45c
Address of r (&r): 0x7ffeefbff45c ← 引用与 n 的地址相同
Value of p: 0x7ffeefbff45c ← p 存的就是 &n
Address of p (&p): 0x7ffeefbff450 ← p 自己的地址
Value pointed by p (*p): 10