1、初始化与绑定
指针(Pointer) 可以在声明时不初始化,稍后可以指向不同的对象。引用(Reference)必须在声明时初始化,并且一旦绑定到某个对象,就不能再绑定到其他对象。
#include <iostream> int main() { int x = 5; int y = 10; // 指针示例 int* p; // 定义一个指向 int 类型的指针 p = &x; // p 指向 x std::cout << "p points to x: " << *p << std::endl; // 输出 5 p = &y; // p 现在指向 y std::cout << "p points to y: " << *p << std::endl; // 输出 10 // 引用示例 int& r = x; // r 引用 x std::cout << "r references x: " << r << std::endl; // 输出 5 // r = &y; // 错误,r 不能重新绑定到其他变量 return 0; }
2、可空性(Nullability)
指针可以指向 nullptr
,表示不指向任何有效对象,引用 必须引用一个有效的对象,不能为 nullptr
。
#include <iostream> int main() { int x = 5; int* p = nullptr; // p 不指向任何对象 if (p == nullptr) { std::cout << "p is a null pointer and does not point to any object." << std::endl; } // 将 p 指向 x p = &x; std::cout << "p now points to x: " << *p << std::endl; // 输出 5 return 0; }
3、内存地址与大小
指针 是一个独立的变量,拥有自己的内存地址和大小,引用 没有自己的内存地址,其地址和大小与所引用的对象相同。
#include <iostream> int main() { // 指针示例 int x = 5; int* p = &x; std::cout << "Address of pointer p: " << &p << std::endl; // 输出 p 的地址 std::cout << "Size of pointer p: " << sizeof(p) << " bytes" << std::endl; // 输出指针的大小 // 引用示例 int& r = x; std::cout << "Address of reference r: " << &r << std::endl; // 输出 x 的地址 std::cout << "Size of reference r: " << sizeof(r) << " bytes" << std::endl; // 输出 x 的大小 return 0; }
4、数组与多级指针
指针 可以创建指向指针的指针(多级指针),也可以创建指针数组,引用 不能创建指向引用的引用,也不能创建引用数组。
#include <iostream> int main() { int x = 5, y = 10; // 指向指针的指针 int* p = &x; // p 是指向 x 的指针 int** pp = &p; // pp 是指向指针 p 的指针 std::cout << "Address of p: " << &p << std::endl; // 输出 p 的地址 std::cout << "Address stored in pp (which points to p): " << *pp << std::endl; // 输出 pp 存储的 p 的地址 std::cout << "Value of x via pp: " << **pp << std::endl; // 输出 **pp 指向的值,即 x 的值 // 指针数组 int* arr[] = {&x, &y}; // arr 是一个指针数组,元素为 x 和 y 的地址 std::cout << "arr[0] points to x: " << *arr[0] << std::endl; // 输出 arr[0] 指向的值(x 的值) std::cout << "arr[1] points to y: " << *arr[1] << std::endl; // 输出 arr[1] 指向的值(y 的值) // 引用示例 int& r = x; // r 是 x 的引用 std::cout << "r references x: " << r << std::endl; // 输出 r 引用的值,即 x 的值 // 错误的代码: // int&& rr = r; // 错误,不能创建引用的引用 // int& arr[] = {r, s}; // 错误,不能创建引用数组 return 0; }
5、使用场景
引用 通常用于函数参数和返回类型,提供更简洁的语法,避免不必要的复制。指针 用于动态内存管理、实现复杂数据结构(如链表、树等)以及需要明确控制内存地址的场景。
#include <iostream> void increment(int& n) { n++; // 增加 n 的值 } int main() { // 使用引用作为函数参数 int num = 5; std::cout << "Before increment: " << num << std::endl; increment(num); // 调用函数,传递引用 std::cout << "After increment: " << num << std::endl; // 动态内存分配和释放 int* p = new int(10); // 动态分配内存并初始化为 10 std::cout << "Dynamically allocated value: " << *p << std::endl; delete p; // 释放内存 return 0; }